知其然,知其所以然
Kubernetes 2026-10-11

CNI:Pod IP 怎么分配,veth 怎么连

在 kind 节点上读 CNI 配置与现场:kindnet 用 ptp + host-local,每个节点一段 podCIDR(10.244.1.0/24 等);host-local 在 /run/cni-ipam-state 里一个 IP 一个文件并记下 last_reserved_ip,新 IP 总是往后分配;Pod 里的 eth0 和节点上的 vethXXXX 互为对端,节点上是一条 /32 主机路由;删除 Pod 后路由、veth 和 IP 记录约 2 秒后才被 CNI DEL 清掉。

Kubernetes CNI Pod IP host-local veth ptp kindnet 真实验证 动画演示
Kubernetes 2026-10-11

跨节点 Pod 通信:路由与封装

在 kind 集群里实测跨节点 Pod 通信:没有隧道,每个节点路由表里有一条去往别的节点 podCIDR 的路由(下一跳是节点 IP);服务端看到的是客户端真实的 Pod IP,KIND-MASQ-AGENT 对目的在 10.244.0.0/16 的流量 RETURN,只有出集群才 MASQUERADE;跨节点 ping 比同节点平均多约 0.03 ms;手动删掉去往另一节点的路由后访问超时,kindnet 约 5~8 秒内补回。

Kubernetes 跨节点通信 CNI 路由 kindnet NAT 真实验证 动画演示
Kubernetes 2026-10-11

containerd 与 crictl:节点上看到的容器

在 kind 节点上用 crictl、ctr、ps 把一个两容器 Pod 对应到运行时:1 个沙箱 + 2 个容器,共用一个 containerd-shim-runc-v2;ctr -n k8s.io 的 10 个 container 正好等于 5 个容器 + 5 个沙箱;crictl inspect 里看到 runc.v2、overlayfs、64Mi 和 100m 被翻译成 cgroup 参数;日志是 CRI 格式的文件 /var/log/pods/…/0.log;crictl stop 后 kubelet 0.7 秒内重启容器。

Kubernetes containerd crictl CRI 沙箱 日志 真实验证 动画演示
Kubernetes 2026-10-11

CRI:kubelet 与容器运行时的接口

在 kind 节点上直观看 CRI:kubelet 与 containerd 之间的 unix socket、Version 调用、RuntimeReady / NetworkReady 条件;用 crictl 按 RunPodSandbox → CreateContainer → StartContainer 手动起一个 Pod(0.13 / 0.06 / 0.09 秒),kubelet 在运行时会在 0.9 秒内把这个不认识的沙箱清掉,停掉 kubelet 才能留住;挪走 CNI 配置后 NetworkReady=false,8.6 秒后节点 NotReady,用 mv 放回不会触发重新加载。

Kubernetes CRI containerd kubelet crictl CNI NetworkReady 真实验证 动画演示
Kubernetes 2026-10-11

静态 Pod:控制平面组件为什么是文件

在 kind 集群里实测静态 Pod:kubelet 的 staticPodPath 是 /etc/kubernetes/manifests,控制面 4 个组件就是该目录里的文件,在 API 里是 config.source=file 且 ownerReference 是 Node 的镜像 Pod;往 worker 放一个文件 0.6 秒就出现镜像 Pod;kubectl delete 镜像 Pod 约 90 秒后会被重建而容器一直在跑;改文件触发重建、删文件才真正删除;引用 ConfigMap 会被 kubelet 拒绝。

Kubernetes 静态 Pod kubelet 镜像 Pod staticPodPath 控制平面 真实验证 动画演示
Kubernetes 2026-10-11

节点心跳:Lease 与 NodeStatus

在 kind 集群里实测节点心跳:kube-node-lease 里每个节点一个 Lease,leaseDurationSeconds=40、renewTime 约每 10 秒更新(间隔 10.0~10.3 秒);同样 100 秒 Lease 更新 10 次而 Node 对象只更新 1 次,没变化时 Node status 约 5 分钟才刷新;停掉 kubelet 后约 48 秒 Ready 变 NodeStatusUnknown 并出现 unreachable 污点;删除 Lease 5.7 秒后被 kubelet 重建。

Kubernetes 节点心跳 Lease NodeStatus kubelet node controller 真实验证 动画演示
Kubernetes 2026-10-11

节点 NotReady 之后:污点与驱逐的时间线

在 kind 集群里停掉一个 worker 的 kubelet,按秒记录时间线:+52 秒 Ready=Unknown 并同时打上 unreachable 的 NoSchedule 和 NoExecute 污点;容忍 30 秒的 Pod 在 +82 秒被标记删除,Deployment 在 +83 秒就有了新的替换 Pod,旧 Pod 停在 Terminating;默认容忍 300 秒和无限容忍的 Pod 都还在;kubelet 回来后 Terminating 的被清理。

Kubernetes 节点失联 NotReady 污点 驱逐 tolerationSeconds 真实验证 动画演示
Kubernetes 2026-10-11

cordon 与 drain:被驱逐的 Pod 去了哪

在 kind 集群里实测 cordon 与 drain:cordon 设 spec.unschedulable 并加 NoSchedule 污点,只拦新 Pod;drain 默认拒绝裸 Pod、DaemonSet 管理的 Pod 和带 emptyDir 的 Pod,逐步加 --ignore-daemonsets、--delete-emptydir-data、--force 才成功(3.1 秒);PDB minAvailable=3 让 drain 每 5 秒重试直到 25 秒超时且 cordon 保持不变;uncordon 后 Pod 不会自己迁回。

Kubernetes cordon drain PodDisruptionBudget 驱逐 运维 真实验证 动画演示
Kubernetes 2026-10-11

kubectl debug:临时容器与节点调试

在 kind 集群里实测 kubectl debug 的三种用法:往运行中的 Pod 加临时容器(--target 才能看到主容器的进程,临时容器不能删、不能设 resources、主容器不会重启);--copy-to 复制出独立的 Pod,在副本里换镜像换命令而原 Pod 不动,加 --share-processes 共享进程;debug node 创建 hostNetwork / hostPID / hostIPC 且挂载宿主机根目录的 privileged Pod,chroot /host 后就是节点自己的系统;--profile 的五种权限配置。

Kubernetes kubectl debug 临时容器 ephemeralContainers 节点调试 真实验证 动画演示
Kubernetes 2026-10-11

pause 容器:Pod 共享的命名空间从哪来

在 kind 节点上读 /proc/<PID>/ns:pause 与 Pod 里的两个容器共享同一个 net、ipc、uts 命名空间,pid、mnt、cgroup 各自独立;pause 进程只占 504 kB,镜像 268kB;同一网络命名空间让容器间用 localhost 互通且端口会冲突;只重启容器 IP 不变,杀掉 pause 沙箱重建 IP 就变(10.244.1.239 → .240)而 Pod uid 不变。

Kubernetes pause 容器 沙箱 命名空间 Pod containerd 真实验证 动画演示
Kubernetes 2026-10-11

shareProcessNamespace:容器之间互相看到进程

在 kind 集群里对照默认 Pod 和 shareProcessNamespace: true 的 Pod:共享后 PID 1 变成 /pause,app 的 sleep 是 PID 7;side 容器可以通过 /proc/7/root 读 app 的文件系统,可以 kill 它;孤儿短命进程在默认下留下 5 个僵尸,共享后因为 pause 会 wait 而是 0 个;容器重启后 PID 会变(7 → 62)且环境变量可被同 UID 的邻居读到。

Kubernetes shareProcessNamespace PID 命名空间 pause 僵尸进程 真实验证 动画演示
Kubernetes 2026-10-11

hostNetwork、hostPID:Pod 与宿主机的边界

在 kind 节点上对照读命名空间编号:hostNetwork 只打通 net 和 uts,hostPID 只打通 pid,hostIPC 只打通 ipc;hostNetwork Pod 的 IP 就是节点 IP,会和 kubelet 的 10250 冲突,DNS 默认退回节点的而解析集群内名字失败,要 ClusterFirstWithHostNet;hostPID 看到节点 34 行进程且 PID 1 是 systemd;hostPort 只靠 portmap 的 DNAT 映射一个端口,Pod 仍有自己的 IP,第二个同端口的 Pod 被 NodePorts 拒绝。

Kubernetes hostNetwork hostPID hostIPC hostPort 命名空间 真实验证 动画演示
京ICP备2026067502号-1京公网安备11010502063487号