Kubernetes 生产故障排查与恢复演练
验证:未记录
- 适用版本
- 未记录
- 验证范围
- 尚未登记验证记录。
本文缩写(英文全称与中文含义)
| 缩写 | 英文全称/名称 | 中文含义 |
|---|---|---|
| API | Application Programming Interface | 应用程序编程接口 |
| AZ | Availability Zone | 可用区 |
| CA | Certificate Authority | 证书颁发机构 |
| CI | Continuous Integration | 持续集成 |
| CRI | Container Runtime Interface | 容器运行时接口 |
| CSI | Container Storage Interface | 容器存储接口 |
| DNS | Domain Name System | 域名系统 |
| IP | Internet Protocol | 网际协议;IP 地址是网络寻址标识 |
| KMS | Key Management Service | 密钥管理服务 |
| PDB | Pod Disruption Budget | Pod 中断预算,约束自愿驱逐 |
| PVC | Persistent Volume Claim | 持久卷申领 |
| SSH | Secure Shell | 安全远程登录协议 |
| SSM | AWS Systems Manager | AWS 系统管理服务;SSM 是沿用的简称 |
前置:实践约定、真实预生产应用。先确认 context、故障时间和影响面;先采证,再重启。不要全量导出 Secret,也不要默认 cluster-info dump 输出到公开 CI。
1. 五分钟定位#
kubectl get --raw='/readyz?verbose'
kubectl get nodes -o wide
kubectl -n orders get deploy,pods,svc,endpointslices,pvc -o wide
kubectl -n orders get events --sort-by=.metadata.creationTimestamp
export POD='REPLACE_AFFECTED_POD'
kubectl -n orders describe pod "$POD"
kubectl -n orders logs "$POD" --all-containers --tail=200 --timestamps
kubectl -n orders logs "$POD" -c api --previous --tail=200 --timestamps最后一条仅适用于有上一次退出实例且容器叫 api。日志脱敏后入 evidence。
| 现象 | 下一份证据 | 恢复方向 |
|---|---|---|
| Pending | scheduler events、requests、污点、PVC/AZ、IP | 纠正约束/补兼容容量,不只增加副本 |
| ImagePullBackOff | event 中仓库/凭据/架构/限流信息 | 恢复拉取身份、CA、DNS或已验证 digest |
| CrashLoopBackOff | previous logs、exitCode、探针事件 | 修应用/配置;不要靠无限增大 initialDelay |
| OOMKilled | limits、working set、节点 MemoryPressure | 区分容器限额与节点驱逐,压测后调整 |
| Service 超时/503 | selector、ready endpoints、目标端口 | 按 网络篇逐跳排查 |
| PVC Pending/Mount 失败 | PVC events、CSI、AZ、KMS、VolumeAttachment | 恢复匹配的存储/身份,禁止盲目强制 detach |
| Node NotReady | Node conditions、kubelet/containerd、磁盘/网络 | 先隔离影响,再修节点或安全替换 |
| Terminating 卡住 | finalizer、控制器日志、云资源状态 | 恢复控制器;确认外部清理完成后才定向处理 |
2. 可恢复的故障注入#
从现有 Deployment 生成不被业务 Service 选中的独立副本,保留真实配置但不接业务流量。其启动不得自动执行迁移/消费生产队列;数据库为预生产副本。
kubectl -n orders get deployment orders-api -o json | jq '
del(.status,.metadata.uid,.metadata.resourceVersion,.metadata.creationTimestamp,.metadata.managedFields,.metadata.annotations) |
.metadata.name="orders-debug" |
.spec.replicas=1 |
.spec.selector.matchLabels={"app.kubernetes.io/name":"orders-debug"} |
.spec.template.metadata.labels={"app.kubernetes.io/name":"orders-debug"}
' > debug-deployment.json
kubectl apply -f debug-deployment.json
kubectl -n orders rollout status deployment/orders-debug --timeout=5m
kubectl -n orders set image deployment/orders-debug api=registry.invalid/orders:missing
kubectl -n orders get events --sort-by=.metadata.creationTimestamp预期新 Pod 拉取失败,原正式应用不受影响。记录 event 的真实原因,再恢复:
kubectl apply -f debug-deployment.json
kubectl -n orders rollout status deployment/orders-debug --timeout=5m
kubectl -n orders patch deployment orders-debug --type=merge -p '{"spec":{"template":{"spec":{"nodeSelector":{"training.example.com/no-node":"true"}}}}}'
kubectl -n orders describe pod -l app.kubernetes.io/name=orders-debug
kubectl -n orders patch deployment orders-debug --type=json -p='[{"op":"remove","path":"/spec/template/spec/nodeSelector/training.example.com~1no-node"}]'
kubectl -n orders rollout status deployment/orders-debug --timeout=5m预期 Pending 证据指向 nodeSelector;恢复后可调度。不要删除原业务 nodeSelector。本实验比“删 Pod 看它重建”多验证了镜像链路与调度原因。
3. 节点故障只读检查#
自建节点经受控 SSH/SSM 登录,托管平台按允许方式获取日志:
sudo journalctl -u kubelet --since '-20 min' --no-pager
sudo journalctl -u containerd --since '-20 min' --no-pager
sudo crictl --runtime-endpoint unix:///run/containerd/containerd.sock ps -a
df -h
df -i
free -m查磁盘/inode、系统时间、CRI socket、证书和 API 连通性。驱逐失败先看 PDB/容量;有卷写入的失联节点必须 fencing 后才能考虑强制恢复。
4. 验收与清理#
kubectl -n orders delete deployment orders-debug运行真实业务建单/查询/消息对账,确认告警恢复;故障记录包括根因、临时恢复、永久修复、检测缺口和负责人。超时只表示未完成,不能视为修复成功。