学 Kubernetes 最容易迷路的地方,不是命令太多,而是脑子里没有一张地图:不知道哪个组件管什么,不知道一个 YAML 提交上去之后被谁接手。这篇先不抠细节,只给你一张全景图,把控制面、数据面、核心对象三件事摆清楚。后面看任何组件,你都能把它挂到这张图上。
目录
- 一、先记住一句话:K8s 是个"对账系统"
- 二、控制面:决定集群"应该是什么样"
- 三、数据面:让容器"真的跑起来"
- 四、核心对象:你日常打交道的就这几个
- 五、一次部署,四个组件接力
- 六、为什么容器不是"小虚拟机"
- 七、学 K8s 的三层顺序(附本篇路线图)
- 八、小结
一、先记住一句话:K8s 是个"对账系统"
很多人把 K8s 理解成"一个能启动容器的工具",这是命令式思维。它真正的模型是声明式:
你只写"我要 3 个副本、镜像用 nginx:1.25",剩下的交给系统自己想办法达到,并且永远保持。
所以整个集群其实在干一件事:不断比对"期望状态"和"实际状态",不一致就动手改成一致。这个动作有个正式名字,叫Reconcile(调谐/收敛)。
理解了这个前提,下面所有组件的位置就都清楚了:
- 存"期望"的:etcd
- 收"期望"的:kube-apiserver
- 算"怎么达到"的:scheduler + controller-manager
- 干"实际动作"的:kubelet + containerd + kube-proxy
二、控制面:决定集群"应该是什么样"
控制面是集群的大脑,通常跑在 master / control-plane 节点上,四个核心组件:
| 组件 | 一句话职责 | 挂掉会怎样 |
|---|---|---|
| kube-apiserver | 集群唯一入口,唯一能读写 etcd 的组件 | 所有kubectl失效,但已运行的 Pod 不受影响 |
| etcd | 集群唯一事实来源,存所有对象 | 集群"失忆",无法创建/更新任何对象 |
| kube-scheduler | 给新 Pod 挑节点 | 新 Pod 一直Pending,老 Pod 正常 |
| controller-manager | 跑各种控制器,把实际状态拉回期望 | 副本不会自动补齐,滚动更新卡住 |
有个细节值得记住:这四个组件里,只有 apiserver 会跟 etcd 说话,其他组件一律通过 apiserver 读写数据。这是 K8s 的设计红线,也是排障时的重要线索——etcd 出问题,症状一定是"整个集群都不对",而不是某个节点不对。
控制面可以多副本部署,前面挂 VIP 或负载均衡;其中 scheduler 和 controller-manager 通过 etcd 的租约(lease)选主,同一时刻只有一个在干活,其他待命。
三、数据面:让容器"真的跑起来"
数据面在每个工作节点上,负责把"期望"变成"真的在跑的东西":
| 组件 | 一句话职责 | 典型故障表现 |
|---|---|---|
| kubelet | 节点的"工头",管本节点 Pod 的生死 | 节点变NotReady,Pod 卡在ContainerCreating |
| containerd | 真正拉镜像、建容器的运行时 | ImagePullBackOff、容器起不来 |
| kube-proxy | 把 Service 规则写进内核,做转发 | Service 访问不通、负载不均 |
三个组件分工很清晰:
- kubelet 决定"要不要起",并把结果报给 apiserver
- containerd 被 kubelet 通过CRI接口调用,负责"怎么起"(先起 pause 沙箱,再起业务容器)
- kube-proxy 负责"起好了怎么被别人访问"
注意方向:kubelet 是主动连 apiserver 的,apiserver 从不反向连 kubelet。所以查节点问题,第一现场永远是节点上的 kubelet 日志,而不是 apiserver 日志。
四、核心对象:你日常打交道的就这几个
组件是"谁在干活",对象是"你要什么"。日常 90% 的工作就在这几个对象上:
| 对象 | 解决什么问题 | 关键特点 |
|---|---|---|
| Pod | 最小调度单元 | 一个 IP,可含多容器,共享网络与存储 |
| Deployment | 无状态应用部署 | 副本数、滚动更新、回滚,管理 ReplicaSet |
| StatefulSet | 有状态应用 | 稳定网络标识、有序启停、独享存储 |
| DaemonSet | 每个节点都要跑一个 | 日志采集、监控 agent、网络插件 |
| Service | 给一组 Pod 一个稳定入口 | ClusterIP / NodePort / LoadBalancer |
| ConfigMap / Secret | 配置与敏感信息外置 | 环境变量或文件挂载注入 |
| PV / PVC | 存储与使用解耦 | PVC 声明"我要多大",PV 是实际存储 |
新手最容易踩的一个坑是忘记 Pod 会变:Pod IP 会变、Pod 会被重建。所以任何配置里都不要写死 Pod IP,一律走 Service。
五、一次部署,四个组件接力
把上面这些串起来,看一次kubectl apply发生了什么(细节后面单独讲,这里只记接力顺序):
kubectl ──提交 YAML──▶ apiserver(认证/授权/准入)──▶ etcd 存下"期望" │ controller-manager 发现差距 ◀────────┘ │ 创建 Pod 对象 ▼ scheduler 挑节点,写 nodeName │ ▼ kubelet(节点上)──CRI──▶ containerd 拉镜像、建 pause + 业务容器 │ ▼ kube-proxy 更新规则,Service 可访问这条链路上每一步失败,Pod 卡的状态都不一样:
| 卡住的位置 | Pod 状态 | 先看什么 |
|---|---|---|
| apiserver 拒收 | kubectl直接报错(401/403/配额) | 错误详情 |
| 调度无节点 | Pending,无 nodeName | kubectl describe pod的 Events |
| 节点拉镜像失败 | ImagePullBackOff | 镜像地址、仓库凭据 |
| 容器反复退出 | CrashLoopBackOff | kubectl logs --previous |
| 探针不过 | Running但READY 0/1 | kubectl describe pod的探针失败原因 |
六、为什么容器不是"小虚拟机"
这是整个系列的起点,值得在导读里先点一句:
容器不是一台小机器,它只是宿主机上一个被"隔离"(Namespace)和"限制"(cgroup)的普通进程。
所以:
- 容器启动快,因为没有操作系统要启动
- 容器镜像小,因为不用打包内核
- 容器里换不了内核、也加载不了内核模块,因为它没有自己的内核
理解了这一层,Pod、pause 容器、OOMKilled 137 这些概念才不会变成需要死记硬背的名词。
七、学 K8s 的三层顺序(附本篇路线图)
我给这个系列排的顺序是「从下往上,再从内到外」:
| 阶段 | 内容 | 对应篇章 |
|---|---|---|
| 第一层:容器底座 | Namespace / cgroup / 镜像 / 运行时 | 01 |
| 第二层:Pod | 为什么包一层、pause 容器、共享边界 | 03 |
| 第三层:控制面 | apiserver 三道关、etcd、调度与控制器 | 04 / 05 / 06 |
| 第四层:数据面 | kubelet 生命周期、kube-proxy 转发 | 07 |
| 收尾:全链路 | 一次 apply 的六阶段、按阶段排障 | 08 |
这个顺序的好处是:每一步都建立在上一层已经理解的基础上,不会出现"背了一堆名词但不知道它为什么存在"的情况。
八、小结
把这篇压成五句话:
- K8s 是个"对账系统",核心动作是 Reconcile,不是"执行启动命令"
- 控制面四个组件:apiserver 收单、etcd 记账、scheduler 分配、controller 纠偏
- 数据面三个组件:kubelet 管生死、containerd 管落地、kube-proxy 管转发
- 日常对象就那几个:Pod、Deployment、StatefulSet、DaemonSet、Service、ConfigMap/Secret、PV/PVC
- 容器只是被隔离和限制的进程,所有上层设计都是围绕这一点长出来的
地图有了,下一篇我们从最底层开始:容器到底是个什么东西,Namespace 和 cgroup 各管什么。