可观测性与排错Part 1日志与监控概念引入你的 K8s 集群就像一个大型工厂——几十个 Pod 在运转但你看不见里面发生了什么。你需要两样东西日志Logs每台机器的工作日记——记下了做了什么、出了什么错监控Metrics工厂的仪表盘——CPU 多少、内存多少、请求量多少可观测性三大支柱日志Logs、指标Metrics、链路追踪Traces。本文聚焦前两个。三大支柱收集采集可视化收集 日志 Logs发生了什么事件 指标 Metrics系统的数值状态 追踪 Traces请求经过的路径EFK / LokiPrometheusGrafanaJaeger / Tempo原理讲解kubectl logs最基础的日志工具# 查看 Pod 日志kubectl logs my-pod# 实时跟踪类似 tail -fkubectl logs-fmy-pod# 查看之前崩溃的日志上一次容器的日志kubectl logs my-pod--previous# 查看指定容器的日志多容器 Podkubectl logs my-pod-csidecar# 按时间筛选kubectl logs my-pod--since1h kubectl logs my-pod --since-time2024-01-01T00:00:00Z⚠️kubectl logs 的局限只能看当前容器的日志Pod 被删除后日志也没了。生产环境需要集中式日志系统。集中式日志架构每个节点写入发送查询Pod 日志日志收集器(Fluentd/Filebeat)日志存储(Elasticsearch/Loki)查询界面(Kibana/Grafana)方案组件特点EFKElasticsearch Fluentd Kibana功能强大资源占用大Loki PromtailLoki Promtail Grafana轻量与 Grafana 集成好Metrics Server集群指标采集K8s 自带的 Metrics Server 采集每个 Pod 和 Node 的 CPU/内存使用量# 查看 Node 资源使用kubectltopnodes# 查看 Pod 资源使用kubectltoppods kubectltoppods --sort-bycpu# 按 CPU 排序kubectltoppods-nkube-system# 指定 Namespace Metrics Server 是 HPA自动扩缩容的数据来源。没有它HPA 无法工作。Prometheus指标采集与告警Prometheus 是 K8s 生态的事实标准监控系统可视化Prometheus数据源暴露暴露暴露查询通知应用 /metrics 端点Node Exporter(硬件指标)kube-state-metrics(K8s 资源状态)Scrape(定时拉取指标)时序数据库(存储指标)Alertmanager(告警规则)Grafana(仪表盘)Slack / 邮件 / Webhook核心概念ScrapePrometheus 主动拉取pull目标的/metrics端点时间序列每个指标是 (指标名, 标签, 时间戳, 值) 的四元组PromQLPrometheus 查询语言如rate(http_requests_total[5m])告警规则如CPU 80% 持续 5 分钟 → 发送告警四个黄金信号Google SRE 提出的监控四个黄金信号信号含义示例指标延迟 (Latency)请求处理时间http_request_duration_seconds流量 (Traffic)系统负载量http_requests_total错误率 (Errors)请求失败的比例http_requests_total{code500}饱和度 (Saturation)资源使用率container_memory_usage_bytes动手实验配套实验位于docs/labs/beginner/logging-monitoring/步骤 1安装 Metrics Servercddocs/labs/beginner/logging-monitoringbashsetup.sh步骤 2查看集群指标⚠️ 需要 Metrics Server 正常运行setup.sh 会自动尝试安装。如果网络受限导致 Metrics Server 镜像拉不下来kubectl top会报Metrics API not available——这不影响步骤 3 的日志实验。# 查看节点资源使用kubectltopnodes# 查看 Pod 资源使用kubectltoppods --all-namespaces --sort-bymemory|head-10# 查看特定 Deployment 的资源使用kubectltoppods-lapplog-generator步骤 3查看日志# 查看最近 10 行日志kubectl logs-lapplog-generator--tail10# 实时跟踪CtrlC 停止kubectl logs-lapplog-generator-f# 查看最近 1 分钟的日志kubectl logs-lapplog-generator--since1m# 多容器 Pod 查看指定容器kubectl logs multi-container-pod-capp kubectl logs multi-container-pod-csidecar步骤 4清理bashteardown.shPart 2排障方法论概念引入你的 Pod 启动不了。新手反应怎么办老手反应“打开排查清单。”排障不是靠运气而是靠系统化流程。就像医生看病先望闻问切再化验拍片最后诊断治疗。K8s 排障五步法1️⃣ Describe看事件2️⃣ Logs看日志3️⃣ Events看集群事件4️⃣ Exec进容器看5️⃣ Debug调试容器原理讲解第一步kubectl describe — 看事件这是排障的第一步也是最重要的一步。80% 的问题靠 describe 就能定位。kubectl describe pod my-pod重点看底部的Events部分事件含义排查方向Pulling image→Pulled镜像拉取成功✅ 正常Failed to pull image镜像拉取失败检查镜像名、tag、仓库认证Scheduled调度成功✅ 正常0/N nodes are available调度失败看原因资源不足污点亲和性Created container容器创建成功✅ 正常Back-off restarting容器反复重启看日志找崩溃原因Liveness probe failed健康检查失败检查探针配置和应用状态第二步kubectl logs — 看应用日志# 当前容器的日志kubectl logs my-pod# 上一次崩溃的日志Pod 重启后kubectl logs my-pod--previous# 多容器 Pod 指定容器kubectl logs my-pod-csidecar# 只看最近的日志kubectl logs my-pod--tail50第三步kubectl get events — 看集群事件# 最近的事件kubectl get events --sort-by.lastTimestamp# 只看某个 Namespace 的事件kubectl get events-ndev --sort-by.lastTimestamp# 只看 Warning 级别kubectl get events --field-selectortypeWarning第四步kubectl exec — 进容器排查# 进入容器 shellkubectlexec-itmy-pod --sh# 在容器内检查cat/etc/resolv.conf# DNS 配置curllocalhost:8080# 内部服务是否正常env# 环境变量是否正确ls-la/data# 挂载卷是否正常 如果容器的镜像没有 shell如 distroless用kubectl debug注入一个调试容器。第五步kubectl debug — 调试容器# 注入调试容器基于 busyboxkubectl debug my-pod-it--imagebusybox:1.36# 节点级调试kubectl debug node/my-node-it--imageubuntu常见故障速查表状态原因排查命令Pending调度失败资源不足/污点/亲和性kubectl describe pod看 EventsImagePullBackOff镜像不存在或认证失败检查镜像名和 imagePullSecretsCrashLoopBackOff应用启动后崩溃kubectl logs --previousOOMKilled内存超 limitkubectl describe pod看 Last StateEvicted节点资源不足Pod 被驱逐kubectl describe node看 ConditionsContainerCreating等 PV、拉镜像、配网络kubectl describe pod看 EventsRunning但不健康Readiness 探针失败kubectl describe pod看 Readiness动手实验配套实验位于docs/labs/beginner/troubleshooting/本实验预设 3 个故障场景你需要用上面的方法论逐一排查。场景 1Pod 一直 Pendingcddocs/labs/beginner/troubleshootingbashsetup.sh# 你的任务找出 pending-pod 为什么调度不上去kubectl get pods kubectl describe pod pending-pod 提示看 Events 里的0/N nodes are available信息。原因和resource有关。场景 2Pod 反复重启# 你的任务找出 crash-pod 为什么一直 CrashLoopBackOffkubectl get pods# 等 Pod 第一次重启后再用 --previous 看崩溃前的日志kubectl logs crash-pod--previous 提示看日志最后一行。应用缺少一个关键的环境变量。场景 3镜像拉不下来# 你的任务找出 image-pull-pod 为什么 ImagePullBackOffkubectl describe pod image-pull-pod 提示仔细看 Events 里的错误信息。镜像名写错了。清理bashteardown.sh自检问题K8s 排障五步法的顺序是什么为什么 describe 是第一步查看答案 五步法describe → logs → events → exec → debug。describe 是第一步因为它能直接看到 K8s 调度器、kubelet 对 Pod 做了什么操作以及失败原因覆盖了大多数基础设施层面的问题调度、镜像、探针、挂载不需要进入容器内部。CrashLoopBackOff和OOMKilled的根因有什么区别查看答案 **CrashLoopBackOff** 是应用启动后主动退出exit code ≠ 0根因通常在应用层面配置错误、依赖不可用、代码 bug排查用 kubectl logs --previous 看应用日志。**OOMKilled** 是容器内存使用超过 limits 被内核杀掉根因是资源配置不合理或内存泄漏排查用 kubectl describe pod 看 Last State 的 Exit Code 137然后检查 limits 设置和应用内存使用。kubectl logs --previous是做什么的什么场景下用它查看答案 --previous 查看**上一次容器实例**的日志。当 Pod 因 OOMKilled 或 CrashLoopBackOff 重启时当前容器的日志是新的重启后的而 --previous 能看到崩溃前的日志帮助定位崩溃原因。你的 Pod 状态是Running但 Service 访问不通。你会按什么顺序排查查看答案 按顺序排查(1) kubectl describe pod — Pod 是否 ReadyReadiness 探针(2) kubectl get endpoints — Service 是否关联了 Pod(3) kubectl exec 进 Pod 内部 curl 服务端口 — 应用是否在监听(4) 检查 Service selector 是否匹配 Pod labels(5) 检查 NetworkPolicy 是否阻止了流量。下一步你的 K8s 基础功已经齐全了最后一篇学习 K8s 网络的最新演进→ 11. Gateway API本文来自 K8s Guide—— 开源免费的 Kubernetes 中文学习指南️ 初学者轨道 面试轨道从零基础到拿 Offer 一站式覆盖 每篇文章配套 Kind 实验脚本本地一键运行 本文源码docs/beginner/18-logging-monitoring.md / docs/beginner/19-troubleshooting.md⭐如果对你有帮助欢迎 Stargithub.com/callmebg/k8s-guide