HiHuo
首页
博客
手册
工具
关于
首页
博客
手册
工具
关于
  • 概览

    • K8s 实战学习实验室
    • 服务访问清单
    • K8s-Lab 学习总纲、仓库评估与专家路线图
  • 课程正文

    • 环境验证与第一课:认识你的真实集群
    • 第二课:kubectl apply 之后,到底发生了什么
    • 第三课:调度器如何选节点,为什么 Pod 会 Pending
    • 第四课:Kubernetes 网络、协议分层、VXLAN/IPIP/WireGuard 原理与排障
    • 第五课:NetworkPolicy、零信任网络与流量边界
    • 第六课:身份、认证、授权、准入与 ServiceAccount / RBAC 原理
    • 第七课:ConfigMap 与 Secret 注入模型、更新机制与安全边界
    • 第八课:存储持久化、PV / PVC / StorageClass 与 NFS 原理
    • 第九课:StatefulSet、Headless Service、稳定身份与存储原理
    • 第十课:探针、滚动更新、优雅终止与 PDB 原理
    • 第十一课:requests / limits、QoS、OOM 与驱逐原理
    • 第十二课:HPA、自动扩缩容、指标链路与副本伸缩原理
    • 第十三课:Service、EndpointSlice、kube-proxy、CoreDNS 与服务发现原理
    • 第十四课:Ingress-nginx、反向代理、Host / Path、NodePort 与北南向流量原理
    • 第十五课:HTTPS、TLS、SNI、证书信任与 Ingress 终止原理
    • 第十六课:cert-manager、Ingress 自动签发、证书生命周期与 ACME 工作流原理
    • 第十七课:ACME、Let's Encrypt、HTTP-01 / DNS-01、Orders / Challenges 与生产限制原理
    • 第十八课:大模型全生态,从数据到训练到部署到治理原理
    • 第十九课:大模型数据集、清洗、标注、切分、版本管理与质量治理原理
    • 第二十课:大模型训练、SFT、LoRA、Checkpoint、Adapter 与模型产物原理
    • 第二十一课:大模型推理、量化、KV Cache、vLLM、吞吐/延迟与部署发布链路原理
  • 实验操作记录

    • 本次仓库审查操作记录与命令原理
    • 本轮操作记录:环境验证、集群基线盘点与故障样本采集
    • 本轮操作记录:kubectl apply 主链路实验
    • 本轮操作记录:调度实验与 Pending 排查
    • 本轮操作记录:Kubernetes 网络原理、协议对比与调试实验
    • 本轮操作记录:NetworkPolicy 与零信任网络实验
    • 本轮操作记录:身份、认证、授权、准入实验
    • 本轮操作记录:ConfigMap 与 Secret 注入、更新与安全边界实验
    • 本轮操作记录:存储持久化、PV / PVC / StorageClass 与 NFS 实验
    • 本轮操作记录:StatefulSet、Headless Service 与稳定身份实验
    • 本轮操作记录:探针、滚动更新、优雅终止与 PDB 实验
    • 本轮操作记录:资源模型、QoS、OOM 与 CPU 节流实验
    • 本轮操作记录:HPA 自动扩缩容实验
    • 本轮操作记录:Service、EndpointSlice、CoreDNS 与服务发现排障实验
    • 本轮操作记录:Ingress-nginx、NodePort 与北南向流量实验
    • 本轮操作记录:HTTPS、TLS、自签证书与 Ingress 实验
    • 本轮操作记录:cert-manager 安装、CA 签发与 Ingress 自动证书实验
    • 本轮操作记录:ACME staging、HTTP-01 失败样本与排障实验
    • 本轮操作记录:大模型全生态与基础原理科普文撰写
    • 本轮操作记录:大模型数据集样本与治理文档编写
    • 本轮操作记录:大模型训练与模型产物概念文撰写
    • 本轮操作记录:大模型推理与服务发布概念文撰写

故障排查实验室 — 面试最实战的能力

排查方法论

面对任何 K8s 故障,按这个顺序排查:

1. kubectl get pods -o wide        → 看状态、哪个节点
2. kubectl describe pod <name>     → 看 Events、Conditions
3. kubectl logs <pod>              → 看应用日志
4. kubectl logs <pod> --previous   → 看上一次崩溃的日志
5. kubectl get events --sort-by=.lastTimestamp  → 看集群事件
6. kubectl exec -it <pod> -- sh   → 进容器排查
7. kubectl top pods/nodes          → 看资源使用
8. journalctl -u kubelet           → 看节点级日志

场景 1: CrashLoopBackOff

制造故障

spec:
  containers:
  - name: app
    image: busybox:1.36
    command: ["sh", "-c", "echo starting; exit 1"]   # 启动即退出

现象

NAME         READY   STATUS             RESTARTS      AGE
crash-demo   0/1     CrashLoopBackOff   1 (10s ago)   16s

排查

# describe 看到:Exit Code: 1,Restart Count 持续增加
kubectl describe pod crash-demo | grep -A5 "Last State"
    Last State:  Terminated
      Reason:    Error
      Exit Code: 1

# logs 看到应用输出
kubectl logs crash-demo
starting

# --previous 看上一次崩溃的日志(如果容器重启太快来不及看)
kubectl logs crash-demo --previous

原因分析

容器进程退出(exit code 非 0)→ kubelet 按 restartPolicy 重启 → 又退出 → 退避重启(间隔 10s, 20s, 40s, 80s, 160s, 最大 300s)

常见原因: 配置错误、依赖服务不可达、缺少环境变量、启动命令错误

面试答法: "看 describe 的 Exit Code 和 Reason,看 logs 的应用错误信息。Exit Code 137 = OOMKilled,Exit Code 1 = 应用错误,Exit Code 0 但还是 CrashLoop = 主进程退出了(不是长驻进程)。"


场景 2: ImagePullBackOff

制造故障

image: nginx:99.99.99-nonexistent   # 不存在的 tag

排查

kubectl describe pod bad-image | grep Events -A5
  Warning  Failed  10s  kubelet  Failed to pull image "nginx:99.99.99-nonexistent": not found

常见原因

Events 信息原因
not found镜像或 tag 不存在
unauthorized没有 imagePullSecret
i/o timeout网络不通或 registry 被墙
manifest unknowntag 存在但平台不匹配(如 arm64 镜像在 amd64 节点)

场景 3: Pending(资源不足)

制造故障

resources:
  requests:
    memory: 100Gi    # 没有节点有 100G 内存

排查

kubectl describe pod greedy-pod | grep Events -A3
  Warning  FailedScheduling  default-scheduler
    0/5 nodes are available:
    1 node(s) had untolerated taint {control-plane},
    4 Insufficient memory.

关键: Scheduler 的 FailedScheduling 事件会精确告诉你为什么调度不上去。

常见 Pending 原因

事件信息原因解决
Insufficient cpu/memory资源不够降低 requests 或加节点
no nodes match nodeSelector没有匹配标签的节点检查标签
untolerated taint节点有 taint加 toleration
PVC not bound存储没就绪检查 StorageClass/PV

场景 4: Service 不通(Endpoints 为空)

制造故障

# Service 的 selector 和 Pod 的 label 不匹配
spec:
  selector:
    app: WRONG-LABEL    # Pod 实际标签是 app: web-test

排查

# 关键:检查 Endpoints
$ kubectl get endpoints broken-svc
NAME         ENDPOINTS
broken-svc   <none>       ← 空!没有后端 Pod

# 对比 selector 和 labels
$ kubectl get svc broken-svc -o jsonpath="{.spec.selector}"
{"app":"WRONG-LABEL"}

$ kubectl get pods --show-labels | grep web-test
web-test-xxx   app=web-test    ← 不匹配!

面试答法: "Service 不通第一步看 Endpoints。Endpoints 为空说明 selector 没匹配到 Pod。对比 Service 的 selector 和 Pod 的 labels。"


场景 5: Node NotReady

制造故障

ssh root@<node> "systemctl stop kubelet"

现象(约 80 秒后)

hk652699382121    NotReady   <none>   3h   v1.30.14

排查

kubectl describe node hk652699382121 | grep Conditions -A10
  Ready   False   KubeletNotReady   container runtime network not ready

常见原因

原因检查方法
kubelet 挂了systemctl status kubelet
容器运行时挂了systemctl status containerd
磁盘满了df -h(kubelet 有磁盘压力阈值)
内存不足free -m
网络断了ping <master-ip>

场景 6: OOMKilled

制造故障

resources:
  limits:
    memory: 10Mi    # 给极小的内存
command: ["tail", "/dev/zero"]    # 占满内存

排查

kubectl describe pod oom-demo | grep "Last State"
    Last State: Terminated
      Reason:   OOMKilled        ← Linux OOM Killer 杀掉了
      Exit Code: 137             ← 128 + 9 (SIGKILL)

面试重点: "CPU 超过 limits 会被节流(throttle),进程变慢但不会被杀。Memory 超过 limits 会被 OOMKill,进程直接终止。所以 CPU limits 可以设高一点(允许 burst),Memory limits 要精确。"


场景 7: 滚动更新卡住

制造故障

kubectl set image deployment/nginx nginx=nginx:999-broken

排查

$ kubectl rollout status deployment/nginx --timeout=3s
Waiting for deployment rollout to finish: 1 out of 3 new replicas have been updated...
error: timed out

$ kubectl get pods -l app=nginx
nginx-7b97df8d44-xxx   nginx:1.25         Running   true    ← 旧 Pod 还在
nginx-dcd499979-xxx    nginx:999-broken   Pending   false   ← 新 Pod 起不来

解决

kubectl rollout undo deployment/nginx    # 秒级回滚

原理: maxUnavailable=25% 保证至少 75% 的 Pod 保持运行。新 Pod 起不来时,旧 Pod 不会被杀,业务不中断。这就是滚动更新的安全网。


排查必备命令速查

# Pod 级别
kubectl get pods -o wide                          # 状态、节点、IP
kubectl describe pod <name>                       # 事件、条件
kubectl logs <pod> [-c container] [--previous]   # 日志
kubectl exec -it <pod> -- sh                      # 进容器
kubectl top pods                                  # CPU/内存

# 节点级别
kubectl get nodes                                 # 状态
kubectl describe node <name>                      # 条件、资源
kubectl top nodes                                 # 资源使用
kubectl drain <node> --ignore-daemonsets          # 维护排空

# 集群级别
kubectl get events --sort-by=.lastTimestamp -A    # 全局事件
kubectl get componentstatuses                     # 控制面状态

# 网络排查
kubectl get endpoints <svc>                       # Service 后端
kubectl exec <pod> -- nslookup <svc>             # DNS
kubectl exec <pod> -- curl <url>                  # 连通性

# 节点上(SSH 进去)
journalctl -u kubelet -f                          # kubelet 日志
crictl ps -a                                      # 容器状态
crictl logs <container-id>                        # 容器日志

→ 02-interview-guide.md