# 核心心智模型:脱离 API 掌控的“法外狂徒”

普通的 Pod 是由 Kube-apiserver 存入 etcd,再派发给节点运行的。 静态 Pod 则完全不同:它们根本不归 apiserver 管!

  • 技术本质: Master 节点上的 kubelet 进程会死死盯着宿主机上的一个特定目录(/etc/kubernetes/manifests/)。
  • 运行机制: 只要这个目录里放了 YAML 文件,kubelet 就会直接调用底层的容器运行时(如 containerd)把它拉起来。如果 YAML 被修改,kubelet 会瞬间重启该容器;如果 YAML 被移走,容器立刻被销毁。

既然你要抢救瘫痪的 API,那 kubectl 肯定是废了。你唯一的武器,就是宿主机底层的容器命令行工具 crictl 或系统日志。

# 实验过程

# 实验前置准备

在 Master 节点上操作。破坏之前,永远、永远、永远记得先备份!

## 将 API Server 的配置备份到 root 目录下
sudo cp /ect/kubernetes/manifests/kube-apiserver.yaml /root/kube-apiserver.yaml.bak
# 阶段一:制造“坠机”现场

这里我们故意将 API Server 启动参数里的一个字母拼错

1、编辑静态 Pod 配置文件

sudo vi /etc/kubernetes/manifests/kube-apiserver.yaml

2、注入致命错误

找到 spec.containers.command 下面的 --authorization-mode=Node,RBAC 这一行。 把它故意改成 --authorization-mode=Node,RBAC123,然后保存退出 (:wq)。

3、见证集群瘫痪

退出文件后,kubelet 会立刻察觉到文件变动并重启 API Server。你只需要疯狂敲击获取节点的命令:

kubectl get nodes

预期现象: 等待大约 10-20 秒后,你会看到令人窒息的报错: The connection to the server 192.168.x.x:6443 was refused - did you specify the right host or port? 此时,整个 Kubernetes 集群的“大脑”已经彻底死亡。

# 阶段二:极限抢救(脱离 kubectl 的盲操)

假装你现在刚刚登录考场的服务器,发现集群挂了。按以下步骤排查:

1. 检查 kubelet 存活状态:

控制平面挂了,是不是 kubelet 进程死了?

systemctl status kubele

会看到 Active: active (running)。说明 Kubelet 没死,是它拉起的静态 Pod 出了问题。

2. 寻找死亡的容器 (crictl 出场):

既然 kubectl 不能用了,我们必须直接向底层的容器运行时(containerd)要日志。使用 K8s 官方底层的调试工具 crictl

crictl ps -a  grep kube-apiserver

会看到一个状态为 Exitedkube-apiserver 容器。记下最左边那一列的 Container ID(比如 a1b2c3d4e5f6)。

3. 查看底层日志:

拿着刚才找到的 Container ID,查看容器为什么起不来:

circtl log <你的Container-ID>

预期输出: 在一堆日志的最后,你会看到非常清晰的致命报错: Error: unknown flag: --authorization-mode=Node,RBAC123 真相大白!启动参数写错了。

# 阶段三:修复

知道了病因,修复就如探囊取物。

1. 恢复正确的配置文件:

我们刚才做了备份的情况下,最快、最稳妥的方法是直接覆盖覆盖回来:

sudo cp /root/kube-apiserver.yaml.bak /etc/kubernetes/manifests/kube-apiserver.yaml

2. 见证脑死亡苏醒:

覆盖文件后,kubelet 再次察觉到变动,开始重新拉起健康的 API Server。 每隔几秒敲一次:


kubectl get nodes

预期现象: 当你再次看到 master, node1, node2 显示 Ready

# 考场究极避坑指南

如果考场上 crictl logs 看不到任何东西(比如配置文件的语法彻底错了,导致容器压根没创建出来),你该去哪里找线索? 答案是去看宿主机的系统日志:

journalctl -u kubelet  tail -n 50

这里面会记录 kubelet 解析 /etc/kubernetes/manifests/ 目录时发生的所有错误。