本章目录(点击跳转):
- 9.1 可观测性三支柱(先有概念)
- 9.2 日志(Logs)
- 9.2.1 kubectl logs 全姿势
- 9.2.2 日志的两个重要限制(小白必知)
- 9.2.3 生产日志方案(了解架构即可)
- 9.3 事件(Events)
- 9.4 资源指标(Metrics)
- 9.4.1 开启 metrics-server(minikube)
- 9.4.2 看 CPU / 内存
- 9.4.3 生产监控栈:Prometheus + Grafana(架构认知)
- 9.5 端口转发与调试入口
- 9.5.1 port-forward
- 9.5.2 临时调试 Pod(原 Pod 起不来的救星)
- 9.5.3 常用"进容器"排障命令
- 9.6 排障标准流程(建议背下来)
- 9.7 本章小结
本章目标:掌握日志、事件、资源指标、port-forward 四大观测手段,建立一套"看到异常 → 5 分钟定位"的排障流程,并了解生产级监控方案(Prometheus + Grafana)的全貌。
9.1 可观测性三支柱(先有概念)
| 支柱 | 回答什么问题 | K8s 对应手段 |
|---|---|---|
| Logs(日志) | 应用内部发生了什么? | kubectl logs、日志系统(ELK/Loki) |
| Metrics(指标) | 资源/性能现在什么水平? | metrics-server、Prometheus |
| Events(事件)/ Traces | 集群对我做了什么?请求链路怎么了? | kubectl get events、链路追踪(Jaeger 等) |
9.2 日志(Logs)
9.2.1 kubectl logs 全姿势
# 基本
kubectl logs mypod
# 实时跟踪(等价 tail -f)
kubectl logs -f mypod
# 只看最近 100 行 / 从现在开始
kubectl logs mypod --tail=100
kubectl logs mypod --since=10m
kubectl logs -f mypod --since-time="2026-09-30T10:00:00"
# 崩溃容器:看上一次
kubectl logs mypod -p
# 多容器 Pod
kubectl logs mypod -c main
kubectl logs mypod -c sidecar
# 按标签看所有副本
kubectl logs -l app=web --tail=50
# 看所有容器日志(含已结束的)
kubectl logs mypod --all-containers=true
9.2.2 日志的两个重要限制(小白必知)
- Pod 删除后日志即消失(节点本地存储),所以生产必须接日志系统。
- **
kubectl logs只看 stdout/stderr**:应用如果把日志写到文件里,kubectl logs是看不到的——要么让应用打 stdout,要么用边车/agent 收集文件日志。
9.2.3 生产日志方案(了解架构即可)
Pod(日志) → 节点 agent(Filebeat/Fluentd/Vector) → 存储(Elasticsearch/Loki) → 查询(Kibana/Grafana)
minikube 上快速体验 Loki + Grafana(可选练习):
# 用 helm 一键部署 loki + promtail + grafana(需先装 helm)
helm repo add grafana https://grafana.github.io/helm-charts
helm install loki grafana/loki-stack -n observability --create-namespace
# 之后在 Grafana 里配置 Loki 数据源即可查询日志
9.3 事件(Events)
事件是 K8s 组件记录在资源上的"近期发生了什么"(默认只保留 1 小时):
# 当前 ns 的事件(按时间倒序)
kubectl get events --sort-by=.lastTimestamp
# 所有 ns
kubectl get events -A --sort-by=.lastTimestamp
# 某个资源的事件(describe 的 Events 段就是它)
kubectl describe pod mypod | tail -20
# 看警告事件(排障第一筛子)
kubectl get events -A --field-selector type=Warning
典型事件示例:
Warning Failed pod/mypod Error: ImagePullBackOff
Warning BackOff pod/mypod Back-off restarting failed container
Normal Pulled pod/mypod Container image "nginx:1.27" already present
Normal Started pod/mypod Started container web
9.4 资源指标(Metrics)
9.4.1 开启 metrics-server(minikube)
minikube addons enable metrics-server
sleep 10
kubectl get apiservices | grep metrics
# v1beta1.metrics.k8s.io 应为 True
9.4.2 看 CPU / 内存
# 节点级
kubectl top nodes
# Pod 级(所有 ns)
kubectl top pods -A --sort-by=memory
# 某个 ns / 某个 Pod
kubectl top pods -n dev
kubectl top pod mypod
# 容器级
kubectl top pod mypod --containers
输出示例:
NAME CPU(cores) MEMORY(bytes)
web-abc12 3m 24Mi
web-xyz34 2m 25Mi
kubectl top只看"现在",不能画历史曲线。历史曲线 + 告警是 Prometheus 的活。
9.4.3 生产监控栈:Prometheus + Grafana(架构认知)
Pod/Node 指标
↓ (node-exporter, kube-state-metrics, cAdvisor)
Prometheus(抓取并存储时序数据)
↓ 查询
Grafana(可视化大屏) + Alertmanager(告警 → 钉钉/邮件/PagerDuty)
minikube 上快速体验(可选练习):
# 官方一键 demo
kubectl apply -f https://raw.githubusercontent.com/prometheus/k8s/master/quick-start/docker/prometheus-operator.yaml
kubectl apply -f https://raw.githubusercontent.com/prometheus/k8s/master/quick-start/docker/k8s-monitoring.yaml
# 然后 port-forward grafana:
kubectl -n monitoring port-forward svc/grafana 3000:80
# 打开 http://localhost:3000 (admin/prometheus)
9.5 端口转发与调试入口
9.5.1 port-forward
# Pod
kubectl port-forward pod/mypod 8080:8080
# Service(流量自动打到各副本)
kubectl port-forward svc/web 8080:80
# API Server 本身(高级玩法:直接用 HTTP 操作集群)
kubectl proxy --port=8081
curl http://127.0.0.1:8081/api/v1/namespaces/default/pods
9.5.2 临时调试 Pod(原 Pod 起不来的救星)
# 方式一:给现有 Pod 注入一个调试容器(共享网络命名空间)
kubectl debug -it mypod --image=busybox:1.36
# 进去后可以直接 telnet/curl 到主容器端口(同一网络空间)
# 方式二:起一个同网络的独立调试 Pod(1.23+,--copy-to 等参数可选)
kubectl debug mypod --image=busybox:1.36 -- sh
# 方式三:复制出一个"可 exec"的副本
kubectl debug -it mypod --copy-to mypod-debug --image=busybox:1.36 -- sh
9.5.3 常用"进容器"排障命令
kubectl exec -it mypod -- sh
# 进去后:
ps aux # 进程在吗
ls -l /app # 配置/文件在吗
cat /etc/app/config # 配置对不对
netstat -tlnp # 端口监听了吗
curl -v http://localhost:8080/healthz # 自己调自己
nslookup db.default.svc # DNS 通不通
wget -qO- db.default.svc:3306 # 依赖服务通不通
9.6 排障标准流程(建议背下来)
场景:一个 Deployment 的 Pod 不正常
1. kubectl get pods -o wide -l app=web
→ 状态是什么?(Pending / CrashLoop / ImagePull / OOMKilled)
2. kubectl describe pod <name>
→ Events 里有什么警告?(调度失败?拉镜像失败?探针失败?)
3. 按状态分流:
- Pending → 资源不够?nodeSelector/亲和性?PVC 没绑定?
- ImagePullBackOff → 镜像名/仓库/凭证(imagePullSecrets)
- CrashLoopBackOff → kubectl logs -p 看崩溃日志
- OOMKilled → 内存 limit 太小 / 内存泄漏
- 探针失败 → 调大 initialDelay / 加 startupProbe / 修应用
- Running 但访问不通 → exec 进去 curl 自己;查 Service endpoints
4. 横向对比:
- 其他副本正常吗?(k get pods -l app=web)
- 之前是好的吗?(k get events 时间线)
- 最近改过什么?(git log / rollout history)
两个高级命令(1.27+ 非常有用):
# 看资源完整状态 + 常用诊断信息(比 describe 更全)
kubectl get pod mypod --show-events=true
# kubectl 内置排障小工具(内置工具箱)
kubectl debug node/minikube # 进节点调试(排节点级问题)
9.7 本章小结
- 三支柱:日志(发生了什么)、指标(什么水平)、事件(集群做了什么)。
- 排障顺序永远是:
get→describe→logs→exec/debug。 kubectl logs只看 stdout 且 Pod 删了就没;生产必须接日志系统。kubectl top看当前资源,历史曲线和告警交给 Prometheus + Grafana + Alertmanager。
下一章:综合实战 + 生产最佳实践,把全书串起来。
原文链接:第9章 可观测性与排障,转载请注明来源!
