高级故障排除:Kubernetes 日志、事件与指标深度解析
关联 Kubernetes 日志、事件和指标,调试 Pod 故障、调度问题和性能瓶颈。
高级故障排除:Kubernetes 日志、事件与指标深度解析
当您将三个问题分开思考时,Kubernetes 故障排除会变得更容易:容器说了什么?控制平面做了什么?指标显示了什么?日志、事件和指标回答了同一事件的不同方面。
以下示例展示了当 Pod 崩溃、镜像拉取失败、工作负载无法调度或服务看似健康但响应缓慢时,如何同时使用这三者。
Kubernetes 日志:调试的基础
日志是应用程序或系统进程所做操作的详细记录。在 Kubernetes 中,日志由 Pod 内运行的容器生成。当应用程序行为异常时,日志通常是首先查看的地方。
访问容器日志
kubectl logs 命令是您从 Pod 检索日志的主要工具。它功能多样,并提供多个有用的选项。
从 Pod 中的单个容器获取日志:
kubectl logs <pod-name>如果 Pod 只有一个容器,此命令可直接使用。
从多容器 Pod 中的特定容器获取日志:
kubectl logs <pod-name> -c <container-name>查看崩溃容器先前实例的日志: 如果容器因错误而重启,您可以使用
--previous标志查看重启前的日志:kubectl logs <pod-name> --previous实时跟踪日志: 类似于
tail -f,-f(或--follow)标志允许您流式传输新生成的日志条目,这对于调试实时问题非常宝贵。kubectl logs -f <pod-name> -c <container-name>按时间过滤日志: 您可以指定从末尾检索的行数(
--tail)或特定时间段的日志(--since)。kubectl logs <pod-name> --tail=100 # 最后 100 行 kubectl logs <pod-name> --since=1h # 过去一小时的日志
集中式日志解决方案
虽然 kubectl logs 非常适合即时调试,但对于大规模、长期的日志管理并不实用。对于生产环境,集中式日志解决方案至关重要。这些解决方案通常包括:
- 日志代理: 在每个节点上运行代理(例如 Fluentd、Fluent Bit、Filebeat)以收集所有 Pod 的日志。
- 日志存储与索引: 将日志存储在中央存储库(例如 Elasticsearch、Loki、Splunk)中。
- 日志可视化与分析: 提供搜索、过滤和可视化日志的界面(例如 Kibana、Grafana、Splunk UI)。
日志记录的最佳实践
- 结构化日志: 以结构化格式(例如 JSON)输出日志,使其易于被集中式日志系统解析和查询。
- 适当的日志级别: 使用不同的日志级别(DEBUG、INFO、WARN、ERROR、FATAL)对消息进行分类并控制详细程度。
- 避免敏感信息: 不要直接记录敏感数据(密码、个人身份信息)。
Kubernetes 事件:集群的叙述者
Kubernetes 事件是集群内状态变化和操作的记录。它们提供了关于 Kubernetes 本身在响应您的期望状态时正在做什么(或未能做什么)的关键见解。事件对于理解为什么 Pod 无法调度、镜像无法拉取或卷无法挂载非常宝贵。
访问 Kubernetes 事件
集群范围的事件:
kubectl get events此命令显示当前命名空间中的所有近期事件。您可以添加
--all-namespaces以查看整个集群中的事件。典型的事件输出如下所示:
LAST SEEN TYPE REASON OBJECT MESSAGE 3m21s Normal Scheduled pod/my-app-789c6f66-abcde Successfully assigned default/my-app-789c6f66-abcde to node01 3m20s Normal Pulling pod/my-app-789c6f66-abcde Pulling image "example/my-app:1.2.3" 2m58s Warning BackOff pod/my-app-789c6f66-abcde Back-off restarting failed container app单个对象的事件:
kubectl describe pod <pod-name>底部的
Events部分通常是查看单个 Pod 的调度、拉取、挂载和重启问题的最快方式。按创建时间排序事件:
kubectl get events --sort-by=.metadata.creationTimestamp
事件通常告诉您什么
事件是短暂存在的记录,因此最适合用于近期故障。查找这些常见原因:
FailedScheduling:调度器无法放置 Pod。检查节点选择器、污点、容忍度、资源请求和可用容量。ImagePullBackOff或ErrImagePull:Kubernetes 无法拉取镜像。检查镜像名称、标签、注册表访问和镜像拉取密钥。FailedMount:卷无法挂载。检查 PVC 绑定、存储类、节点权限和 CSI 驱动程序健康状态。BackOff:容器持续失败。将事件与kubectl logs --previous结合使用。
Kubernetes 指标:资源视图
指标告诉您集群是否有足够的 CPU、内存和容量来运行工作负载。它们还有助于将应用程序错误与资源压力区分开来。
使用 metrics-server 快速检查
如果已安装 metrics-server,请使用 kubectl top:
kubectl top nodes
kubectl top pods
kubectl top pod <pod-name> --containers
接近容器限制的高 Pod 内存通常与 OOMKilled 重启相对应。高节点 CPU 可以解释延迟,即使 Pod 日志看起来干净。
使用 Prometheus 进行更深入的指标分析
在生产环境中,Prometheus 和 Grafana 通常提供 kubectl top 所缺乏的历史视图。有用的信号包括:
- 容器随时间推移的重启次数。
- 具有低 CPU 限制的容器的 CPU 限制。
- 与限制相比的内存工作集。
- 按命名空间划分的待处理 Pod。
- API 服务器请求延迟和错误率。
- 节点磁盘压力、内存压力和网络饱和。
关联日志、事件和指标
使用时间窗口,从症状到原因:
- 检查 Pod 状态:
kubectl get pod <pod-name> -o wide kubectl describe pod <pod-name> - 读取当前和先前的日志:
kubectl logs <pod-name> -c <container-name> kubectl logs <pod-name> -c <container-name> --previous - 检查最近的命名空间事件:
kubectl get events --sort-by=.metadata.creationTimestamp - 比较资源使用情况:
kubectl top pod <pod-name> --containers kubectl top node
例如,一个处于 CrashLoopBackOff 状态的 Pod,先前的日志以内存不足错误结束,并且指标显示内存接近限制,这指向内存限制或应用程序内存问题。一个处于 Pending 状态且带有 FailedScheduling 事件以及低节点容量的 Pod,指向调度压力,而不是容器错误。
要点
不要仅从一个信号调试 Kubernetes。日志解释应用程序行为,事件解释控制平面决策,指标解释资源压力。当您按时间和对象名称将它们对齐时,根本原因更容易与症状区分开来。