先记住这个答案
静态 Pod 是 kubelet 直接管理的 Pod,其 manifest 存放在节点本地目录或 URL 中,kubelet 周期扫描并创建、更新、删除对应 Pod。静态 Pod 本身不通过 API Server 创建或管理,但 kubelet 会为每个静态 Pod 在 API Server 上创建一个只读的镜像 Pod,由 kubelet 同步状态;用户无法通过 API 删除或修改静态 Pod。控制平面组件如 kube-apiserver、etcd 常以静态 Pod 方式启动,因为集群初始化时 API Server 尚未可用,kubelet 可以在无 API Server 的情况下先拉起这些关键组件,实现控制平面自举。
- 静态 Pod 由 kubelet 直接管理,不通过 API 创建。
- 镜像 Pod 是 API 中的只读影子,删除会被重建。
- 控制平面用静态 Pod 实现自举和本地恢复。
静态 Pod 的创建与同步机制
kubelet 通过配置中的 staticPodPath(如 /etc/kubernetes/manifests)或 staticPodURL 获取 Pod manifest。它会定期扫描目录(或拉取 URL),将文件内容视为标准 Pod 定义,直接通过 CRI 创建容器。kubelet 不把 manifest 提交给 API Server,而是自己维护 Pod 状态,并在节点上持续确保容器符合 spec。
为了让集群 API 可以观察到静态 Pod,kubelet 会向 API Server 创建一个镜像 Pod(Mirror Pod),名字后缀为节点名,如 static-web-node1。镜像 Pod 是只读的,用户无法通过 kubectl delete 删除它——kubelet 会重新创建。static Pod 的标签会传播到镜像 Pod,因此可以被 Service 或 NetworkPolicy 选中。注意 kubelet 需要有权创建镜像 Pod,否则 API 中不出现。
# 在节点上查看容器运行时中的 Pod
crictl ps
# 在控制面查看镜像 Pod
kubectl get pods
# 尝试删除镜像 Pod,会被 kubelet 重建
kubectl delete pod static-web-node1
sleep 20
kubectl get pods static-web-node1适用于使用 CRI-O 或 containerd 的节点,crictl 命令直接查看由 kubelet 启动的容器。
仿真一个单节点控制平面自举场景
假设你有一个裸机节点,要部署一个最小 Kubernetes 控制平面。按照 kubeadm 流程,先安装 kubelet、kubeadm、kubectl,然后运行 kubeadm init。kubeadm 会将 kube-apiserver、kube-controller-manager、kube-scheduler 的 manifest 写入 /etc/kubernetes/manifests/,并启动 kubelet。此时 API Server 容器还没运行,kubelet 作为独立的守护进程,直接读取这些 manifest 启动容器,从而拉起 API Server。等 API Server 就绪后,kubelet 再上报静态 Pod 状态,kubeadm 也据此完成控制平面初始化。在这个过程中,静态 Pod 的启动不依赖任何 API 对象,打破了循环依赖。
如果把这些组件写成 Deployment 或 DaemonSet,那么调度器需要 API Server 工作,API Server 又依赖 etcd 和证书,在集群还没初始化时根本无法创建这些 Pod。kubelet 从本地文件读取 manifest 的方式绕过了整个 API 层,确保控制平面可以冷启动。生产环境中多个控制面节点各跑一套静态 Pod,kubelet 持续监控 manifest 变化,文件丢失或修改会直接停止或重建对应容器,实现组件级自愈。
静态 Pod 的适用边界与失效条件
静态 Pod 只保证 kubelet 本地的自愈,不参与 ReplicaSet 的扩缩容,也没有滚动更新策略。如果 manifest 文件被误删除,Pod 会被停止且不会自动恢复;文件被错误修改可能启动错误版本。kubelet 不会过滤文件扩展名,比如一个 .yaml.bak 文件也会被当成有效 manifest,如果两个文件定义同名 Pod,行为未定义,可能由旧备份静默占先。因此所有备份必须移出 staticPodPath 目录。
另一个边界是镜像 Pod 的权限问题:如果 kubelet 缺少创建镜像 Pod 的 RBAC 权限,静态 Pod 仍能运行,但无法在 API 中显示,也就无法被 Service 发现和负载均衡。这类故障通常表现为节点上容器正常但 kubectl get pods 无对应条目。排查时用 crictl ps 检查容器是否创建,并用 journalctl 查看 kubelet 日志中的 RBAC 拒绝信息。
容易答错的地方
- 静态 Pod 可被 Deployment 管理
- 纠正:静态 Pod 由 kubelet 直接管理,Deployment 控制器无法感知其存在,也不能修改或删除它。删除镜像 Pod 后 kubelet 会基于本地 manifest 重建,直到文件被移除。
- 静态 Pod 只能本地文件配置
- 纠正:除了 staticPodPath 文件方式,kubelet 还支持 staticPodURL,通过定期下载 HTTP(S) 文件来同步 Pod 清单。两种方式均可动态增删,只是 URL 方式需要额外网络依赖。
面试官还会怎么问?
静态 Pod 与 DaemonSet 有何区别?
DaemonSet 由 API Server 中的控制器根据节点选择器在匹配节点上创建 Pod,需要集群可用;静态 Pod 由 kubelet 本地管理,不依赖调度器。DaemonSet 支持滚动更新,但副本数由节点选择决定,不可手动扩缩;静态 Pod 只能通过修改文件并触发 kubelet 重新创建。
如何安全地更新一个静态 Pod 的镜像或参数?
直接编辑 manifest 文件,kubelet 会在扫描周期内发现变更并重启 Pod。推荐的做法是原子替换整个文件,避免产生部分写入或携带 .bak 后缀的残留文件。
控制平面组件若以静态 Pod 运行,kubelet 故障会怎样?
kubelet 是运行在 systemd 下的进程,如果它停止,静态 Pod 的容器不会被自动停止,但 kubelet 无法执行健康检查和重启。通常 systemd 会拉起 kubelet,随后静态 Pod 按原 manifest 恢复。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。