谁在干活:kubectl 命令背后的组件分工 系列前十几篇,集群一直当"黑盒"用—— kubectl apply 一个清单,应用就起来了,至于是谁把这件事做完的,没拆开看过。对兼职运维来说,这个黑盒必须拆开:排障的第一问不是"怎么修",而是"哪一环出了问题、该看谁"——Pod 一直 Pending 是调度的问题还是资源的问题?探针失败是应用的问题还是 kubelet 的问题?服务访问不通是 Service 配置还是网络插件?组件职责 = 排障归属地图。
这篇用一条生产里每天都在用的命令( kubectl apply )当主线案例,把控制面四个组件和节点四个组件的职责、工作流程讲清楚,并用 kind 集群上的实测事件证明"谁在干活"。理论向,不做源码级剖析——兼职运维只需要知道"每个组件干什么、出了事找谁"。
1. 组件全景:控制面管"想",节点管"做" K8s 的所有组件分成两组,职责边界非常清晰:
控制面(control plane):负责决策——存状态、做调度、收敛声明,全在控制面; 节点(node):负责执行——拉镜像、起容器、转发流量、管网络,全在节点。 %% K8s 组件全景: 控制面 4 件套 + 节点 4 件套 flowchart TD subgraph CP["控制面(决策)"] API["kube-apiserver\n唯一入口 + 收费站"] ETCD[("etcd\n唯一真相存储")] SCH["kube-scheduler\n给新 Pod 找节点"] CM["kube-controller-manager\n控制器集合(把声明收敛成动作)"] end subgraph N1["节点 learn-worker"] KL1["kubelet\nPod 生命周期 + 探针"] KP1["kube-proxy\nService 转发规则"] CT1["containerd\n容器运行时"] CNI1["kindnet\nPod 网络 + IP"] end subgraph N2["节点 learn-worker2"] KL2["kubelet"] KP2["kube-proxy"] CT2["containerd"] CNI2["kindnet"] end API --> ETCD API <-->|"watch/上报"| KL1 API <-->|"watch/上报"| KL2 API <-->|"watch"| KP1 API <-->|"watch"| KP2 API <-->|"watch"| SCH API <-->|"watch"| CM style API fill:#0f172a,stroke:#3b82f6,stroke-width:2.5px,color:#ffffff,font-weight:bold style SCH fill:#0f172a,stroke:#3b82f6,stroke-width:2.5px,color:#ffffff,font-weight:bold style CM fill:#0f172a,stroke:#3b82f6,stroke-width:2.5px,color:#ffffff,font-weight:bold style ETCD fill:#052e16,stroke:#16a34a,stroke-width:2px,color:#ffffff,font-weight:bold style KL1 fill:#1e1e24,stroke:#6b7280,stroke-width:2px,color:#ffffff style KL2 fill:#1e1e24,stroke:#6b7280,stroke-width:2px,color:#ffffff style KP1 fill:#1e1e24,stroke:#6b7280,stroke-width:2px,color:#ffffff style KP2 fill:#1e1e24,stroke:#6b7280,stroke-width:2px,color:#ffffff style CT1 fill:#1e1e24,stroke:#6b7280,stroke-width:2px,color:#ffffff style CT2 fill:#1e1e24,stroke:#6b7280,stroke-width:2px,color:#ffffff style CNI1 fill:#1e1e24,stroke:#6b7280,stroke-width:2px,color:#ffffff style CNI2 fill:#1e1e24,stroke:#6b7280,stroke-width:2px,color:#ffffff 在 kind 里这些组件都是真实运行的 Pod(生产 K8s 同款,只是 kind 把它们跑在 Docker 里)。看它们:
...