写在前面
承接前八篇。前面讲了 Pod/Deployment/Service/配置/调度/安全/运维——都是"资源怎么用"。本篇补上地基:K8s 到底由哪些组件组成、各自干什么。
篇1 的架构概览只列了组件名,这篇把每个组件掰开讲透:控制平面、工作节点、插件体系。理解组件,才能看懂下一篇(篇10)的调用链路——一次 kubectl apply、一次外部请求,在组件之间到底怎么流转;也才能排查"Pod 没调度上"“Service 不通"这类深层问题。
一、K8s 架构总览
K8s 是主从架构:一个控制平面(Control Plane,俗称 master)管着一堆工作节点(Worker Node)。控制平面是"大脑”,工作节点是"手脚"。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| ┌─────────────────────────────────┐
│ Control Plane(控制平面) │
│ ┌──────────┐ ┌───────────────┐ │
│ │apiserver │ │ etcd │ │
│ └──────────┘ └───────────────┘ │
│ ┌────────────┐ ┌─────────────┐ │
│ │ scheduler │ │ controllers │ │
│ └────────────┘ └─────────────┘ │
└─────────────────────────────────┘
▲
kubectl / 应用 / 组件 都走 apiserver
▼
┌──────────────┬──────────────┬──────────────┐
▼ ▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐
│ Worker1 │ │ Worker2 │ │ Worker3 │ │ ... │
│ kubelet │ │ kubelet │ │ kubelet │ │ │
│kube-proxy│ │kube-proxy│ │kube-proxy│ │ │
│ runtime │ │ runtime │ │ runtime │ │ │
│ Pods │ │ Pods │ │ Pods │ │ │
└─────────┘ └─────────┘ └─────────┘ └─────────┘
|
三类角色:
- 控制平面组件:决策(调度、reconcile)、存状态(etcd)、对外暴露 API(apiserver)
- 工作节点组件:执行(跑 Pod、转发流量)
- 插件(addons):按集群能力选装的扩展组件,通常以工作负载形式运行;部署位置和是否必需取决于发行版与实现
二、控制平面(Control Plane)
2.1 kube-apiserver —— 唯一入口
整个集群唯一的对外接口。所有操作(kubectl、组件间通信、dashboard、CI/CD)都通过它。
1
2
3
4
5
6
7
| 职责:
✓ RESTful API(HTTPS),所有资源的 CRUD
✓ 认证(你是谁)→ 授权(你能干啥,RBAC)→ 准入(改不改请求体)
✓ 唯一能直接读写 etcd 的组件
✓ 无状态(状态全在 etcd),可水平扩展(多实例 + LB)
口诀:apiserver 是"前台",etcd 是"账本",前台不存钱只转手
|
为什么所有组件都走 apiserver 而不直接读写 etcd?因为 apiserver 做认证 / 授权 / 准入 / 校验 / 乐观锁 / 审计 / watch 机制——这些不该让每个组件自己实现。集中到 apiserver,安全且一致。
2.2 etcd —— 集群的大脑
强一致性的键值存储,K8s 把所有集群状态(有哪些 Pod / Service / 节点 / 配置…)都存在 etcd 里。
1
2
3
4
5
6
7
| 特点:
✓ KV 存储(不是关系库),key 按资源路径组织
✓ Raft 共识协议:强一致(写要多数节点确认)
✓ 保存 Kubernetes API 对象的持久状态 → 必须备份!
✓ etcd 不可用时控制面无法正常读写状态;已有工作负载可能暂时继续运行,但调度、变更和故障恢复会受影响
备份:etcdctl snapshot save;恢复 = 从快照重建
|
etcd 是 Kubernetes API 状态的权威存储,快照是控制面灾难恢复的核心。但 etcd 快照不包含 PV 中的业务数据、外部密钥系统数据、镜像和集群外基础设施配置,不能把“备份 etcd”等同于完整业务备份。
2.3 kube-scheduler —— 决定 Pod 跑在哪
新 Pod 创建后(还没绑定节点),scheduler 负责"给它选一个节点"。
1
2
3
4
5
6
7
| 调度两步:
1. 过滤(Filter):哪些节点能用?(资源够、亲和、污点容忍、nodeSelector)
2. 打分(Score):能用里挑最优(资源均衡、亲和优先、反亲和)
选定后 → 通过 Binding 完成 Pod 与节点的绑定,交给 kubelet 去起
注意:scheduler 只"决定",不"启动"——启动是 kubelet 的活
|
Pod 卡在 Pending 多半是 scheduler 没找到合适节点(资源不足 / 亲和冲突 / 污点)。kubectl describe pod 看 Events 里的 FailedScheduling 是关键线索。
2.4 kube-controller-manager —— 调谐循环
跑一堆控制器,每个控制器管一类资源,核心是 reconcile(调谐)循环:持续观察"实际状态",趋近"期望状态"。
1
2
3
4
5
6
7
8
9
10
11
12
13
| 内置控制器(部分):
Deployment Controller → 维持 N 个副本、滚动更新
ReplicaSet Controller → 维持 Pod 副本数(Deployment 底层用它)
Node Controller → 节点失联检测、标记 NotReady
EndpointSlice Controller → 维护 Service 的 EndpointSlice(哪些后端)
ServiceAccount Controller → 保证每个 ns 有默认 SA
Job / CronJob Controller → 批处理任务的完成 / 重试
统一模式:
期望状态(存在 etcd,如 replicas: 3)
↕ reconcile
实际状态(从 apiserver 观察到的运行 Pod 数)
不一致 → 创建 / 删除 Pod,直到匹配
|
这是 K8s “声明式"的本质:你声明 replicas: 3,controller 替你维持。Pod 挂了它补,多了它删——你不用写"创建 3 个 Pod"的命令,只声明期望。
2.5 cloud-controller-manager —— 云特定逻辑
把"和云厂商打交道"的逻辑从核心分离(节点管理 / 负载均衡 / 路由)。这样 K8s 核心不知道"是 Azure 还是 AWS”,云厂商各自实现自己的 CCM。
1
2
3
4
| 内部控制器:
Node Controller → 给云上 VM 打标签、检查存活
Route Controller → 配置云路由(Pod 网段到节点)
Service Controller → 创建云 LoadBalancer(type=LoadBalancer 时)
|
自建集群通常不跑 CCM;云托管(AKS/EKS/GKE)一定跑——type=LoadBalancer 的 Service 就是 CCM 调云 API 建的。
三、工作节点(Worker Node)
3.1 kubelet —— 节点代理
每个节点上跑一个,管这个节点上的 Pod。
1
2
3
4
5
6
7
8
| 职责:
✓ 从 apiserver 观察绑定到本节点的 PodSpec("这个节点该跑哪些 Pod")
✓ 调 container runtime(CRI)起 / 停容器
✓ 执行健康检查(liveness / readiness probe)
✓ 上报节点条件、容量以及 Pod/容器状态给 apiserver;实时 CPU/内存用量由资源指标链路另行提供
✓ 挂载 volume
口诀:kubelet 是节点上的"包工头",按 apiserver 的图施工、汇报进度
|
3.2 kube-proxy —— 服务转发
每个节点上跑一个,负责 Service 的网络规则。
1
2
3
4
5
6
7
| 职责:
✓ 监听 Service / EndpointSlice 变化
✓ 按配置在节点上维护 iptables、nftables 或其他支持模式的规则:
访问 Service 的 ClusterIP → DNAT 到某个 Pod IP
注意:kube-proxy 不真正转发流量(那是内核 netfilter 干的)
它只是"写规则的人",规则匹配后内核改目的地址
|
不能再用“小集群 iptables、大集群 ipvs”作为选型规则。IPVS 模式已在 Kubernetes 1.35 弃用;符合内核要求的新 Linux 集群应评估 nftables 模式,旧内核则优先参考官方建议使用 iptables。某些网络实现会完全替代 kube-proxy。
Service 的 ClusterIP 通常是没有对应真实网卡的虚拟 IP。kube-proxy 可通过 iptables 或 nftables 等模式实现转发,也可能由集群选用的 eBPF 等数据面完全替代。篇10 会展开常见路径及其实现边界。
3.3 container runtime —— 跑容器
真正启动容器的组件,通过 CRI(Container Runtime Interface)和 kubelet 交互。
1
2
3
4
5
6
| 主流 runtime:
containerd ← 常见 CRI runtime(源自 Docker 生态中的容器运行能力)
CRI-O ← Red Hat 系(OpenShift 默认)
Docker ← 已弃(K8s 1.24 起移除 dockershim),新集群别用
K8s 不关心你用哪个 runtime,只要实现 CRI 接口
|
“K8s 不再支持 Docker”的准确含义是:Kubernetes 通过 CRI 调 runtime,Docker Engine 曾依赖 dockershim,1.24 移除了这个内置适配层。Docker 构建的标准容器镜像仍可由兼容的 runtime 运行;变化的是运行时接入方式,不是镜像突然失效。
四、组件协作一览
1
2
3
4
5
6
7
8
9
10
11
| kubectl apply → apiserver → etcd(存期望)
↓ watch
controller-manager(看到要 3 副本,创建 Pod 对象)
↓ watch
scheduler(给 Pod 选节点,写 nodeName)
↓ watch
目标节点的 kubelet(收到,调 runtime 起容器)
↓
kube-proxy(Service 变了,更新 iptables)
↓
Pod 跑起来,Service 可访问
|
控制器、scheduler、kubelet 等主要通过 API Server 观察和更新资源,watch 与 reconcile 降低了组件之间的直接耦合。但它们并非全部“被动”,也不是绝不直接调用其他系统:kubelet 会调用 CRI 和 CSI 相关接口,容器运行时通常再调用 CNI 插件配置网络;cloud-controller-manager 会调用云 API,API Server 也可能调用准入 Webhook。完整链路留篇10 详演。
五、插件体系(Addons)
addons 是"集群跑起来必需、但不在核心二进制里"的组件,以 Pod / DaemonSet 形式跑在 kube-system 命名空间。
1
2
3
4
5
| 什么是 addon:
✓ 不是 K8s 核心(不在 kubelet / apiserver 等二进制里)
✓ 有些提供基础能力(如 Pod 网络、DNS),有些是可选能力(如资源指标、Dashboard)
✓ 常以 Deployment / DaemonSet 部署,Namespace 由发行版或安装清单决定
✓ 可替换(CNI 选 Calico 还是 Cilium,DNS 用 CoreDNS 还是别的)
|
5.1 CoreDNS —— 集群 DNS
1
2
3
4
5
6
7
| 职责:Service 名字解析
访问 http://web-app → 同 ns 内解析到 Service ClusterIP
访问 http://web-app.default → 跨 ns 显式指定
访问 web-app.default.svc.cluster.local → 完整 FQDN
形式:Deployment(2 副本)+ Service,跑在 kube-system
没它:Service 名字不通,只能用 IP(痛苦)
|
5.2 CNI —— Pod 网络
1
2
3
4
5
6
| 职责:给 Pod 分配 IP + 跨节点 Pod 互通
主流:Calico(BGP / 网络策略强)、Cilium(eBPF,新锐)、Flannel(简单老牌)
云托管:Azure CNI / Amazon VPC CNI / GKE alias(Pod 拿 VPC IP)
没它:Pod 拿不到 IP、跨节点 Pod ping 不通
Kubernetes 定义网络模型和相关 API;Pod 网络的数据面通常由 CNI 兼容实现完成
|
CNI 的对比详见本站「云托管 K8s 实战」系列,以及本系列网络篇(04)。
5.3 Metrics Server —— 指标源
1
2
3
4
5
| 职责:聚合各节点资源用量(CPU / 内存),通过 Metrics API 暴露
下游:HPA(按 CPU 扩缩)、kubectl top(看节点 / Pod 占用)
没有 Resource Metrics API:kubectl top 不可用,基于 CPU/内存资源指标的 HPA 无法计算
形式:可部署一个或多个副本,从 kubelet 获取资源用量并通过聚合 API 暴露
|
5.4 Ingress Controller —— 七层入口
1
2
3
4
5
| 职责:把外部 HTTP / HTTPS 流量按 Host / Path 路由到 Service
实现:Gateway API Controller、仍受维护的第三方 Ingress Controller、云厂商入口控制器
本质:一个反向代理 Pod + 读 Ingress 资源动态配置
没它:Ingress 资源没人执行(声明了也没用)
|
5.5 CSI —— 存储插件
1
2
3
4
5
| 职责:对接具体存储后端(云盘、NFS、Ceph、分布式存储)
三阶段:Provision(建卷)→ Attach(挂到节点)→ Mount(挂进 Pod)
形式:一堆组件(Controller / Node Plugin)以 Pod 跑
动态卷供应、挂载能力取决于所装 CSI 驱动和存储后端;仅创建 PVC 不会凭空得到可用存储
|
5.6 其他常见 addon
1
2
3
4
| Dashboard Web UI(生产慎开,安全风险)
认证 Webhook 扩展认证授权(对接 LDAP/OIDC)
Cluster Autoscaler 节点自动扩缩(节点不够加机器)
cert-manager 自动 TLS 证书(Let's Encrypt 等)
|
六、实地看:kubectl get pods -n kube-system
1
2
3
4
5
6
7
8
9
10
| kubectl get pods -n kube-system
# NAME READY STATUS AGE
# coredns-xxx-xxx 1/1 Running 10d ← CoreDNS addon
# etcd-master 1/1 Running 10d ← 控制平面(静态 Pod)
# kube-apiserver-master 1/1 Running 10d ← 控制平面(静态 Pod)
# kube-controller-manager-master 1/1 Running 10d ← 控制平面(静态 Pod)
# kube-proxy-xxxxx 1/1 Running 10d ← DaemonSet(每节点一个)
# kube-scheduler-master 1/1 Running 10d ← 控制平面(静态 Pod)
# metrics-server-xxx-xxx 1/1 Running 10d ← Metrics addon
# calico-node-xxxxx 1/1 Running 10d ← CNI(DaemonSet)
|
几个现象:
- kubeadm 的控制平面组件通常是静态 Pod(由 kubelet 直接管,清单在
/etc/kubernetes/manifests);其他发行版可能使用 systemd、容器或托管控制面。 - kube-proxy / CNI 常以 DaemonSet 部署到符合条件的节点,但也可能被发行版或其他数据面实现替代。
- addons 是普通 Deployment / DaemonSet。
七、小结
1
2
3
4
5
6
7
8
9
10
11
12
13
| K8s 组件全景:
控制平面(决策 + 存状态)
apiserver 唯一入口,认证授权
etcd Kubernetes API 状态库(必须备份)
scheduler Pod 选节点
controller-manager reconcile 循环维持期望
cloud-controller-manager 云特定逻辑
工作节点(执行)
kubelet 管 Pod 生命周期
kube-proxy 可写 Service 转发规则(iptables / nftables 等,也可能被替代)
runtime 跑容器(containerd / CRI-O)
插件(以 Pod 跑在 kube-system)
CoreDNS / CNI / Metrics Server / Ingress Controller / CSI / ...
|
1
2
3
4
5
| 核心认知:
✓ 核心控制循环主要通过 apiserver 读写和 watch API 对象,外部系统调用另算
✓ 声明式 = 你写期望状态,controller / scheduler 替你维持
✓ apiserver 可多实例部署;etcd 是 API 状态恢复的关键,但不是业务数据的完整备份
✓ Kubernetes 定义网络与服务发现模型,具体数据面和 DNS 由所选实现提供
|
下一篇:调用链路深挖——一次 kubectl apply 在组件间怎么流转(管理面),一次外部 HTTP 请求怎么从公网打到 Pod(数据面),把本篇的组件全串起来。
参考资料