想象你经营一家大型酒店。酒店不能只有前台、厨房和客房,还要有一套清晰的“后台班子”:有人负责接单办入住,有人负责保存所有房态记录,有人负责排班派活,有人负责检查房间是否达到标准。与此同时,每一层楼还得有领班,专门执行具体清扫和设备维护。如果所有角色都挤在同一个办公室,酒店早就乱成一锅粥。Kubernetes 的架构思路正是如此——它把一台台服务器分成“控制面”与“工作节点”两类角色。控制面像酒店的管理层,负责决策、调度和校验;工作节点像各个楼层的领班,负责真正运行容器、处理流量。整篇文章将用这座“酒店”作为贯穿始终的比喻,带你看懂 K8s 控制面与工作节点如何各司其职、默契配合。

岗位关联

理解 K8s 控制面与工作节点的分工,是定位线上故障、优化集群性能、设计高可用平台的必修基本功。

目录
  1. 可视化演示
  2. 集群总览
  3. 统一入口
  4. 状态仓库
  5. 调度控制
  6. 节点执行
  7. 运维实践
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

演示控制面组件交互、调度器过滤打分绑定流程,以及声明式API的控制循环协调机制,可切换三种模式观察Pod如何被调度运行。

本节配有交互动效(进入视口后自动加载,约 3KB)。

控制面组件交互 API Server是集群唯一入口,所有操作经它 etcd用Raft共识存储集群状态,Scheduler调度为Pod选节点 State = etcd(Raft) Controller Manager维持期望状态,kubelet执行。

集群总览

假设你经营一家五星酒店。如果所有人都挤在同一个办公室里,既要接电话,又要跑去每个房间打扫,很快前台就会陷入混乱。一家成熟的酒店一定会把“管理区”和“楼层区”分开:管理区负责接单、排班、盯服务标准,楼层区则负责真正铺床、送餐、清扫。Kubernetes 的架构思路和这家酒店完全一致。

K8s 把一台台服务器分成两类角色。控制面(Control Plane)节点相当于酒店的管理区,工作节点(Worker Node)相当于客房楼层。控制面通常由 4 个组件协作完成决策:API Server 负责接单,etcd 负责存档,Scheduler 负责排班,Controller Manager 负责质检。工作节点则运行 kubelet(楼层领班)、容器运行时(清扫工具)和 kube-proxy(礼宾接线)。控制面一般不放业务,专注协调;真正承载业务服务的 Pod 落在工作节点上。

从数学上看,一个 K8s 集群就是控制面集合与工作节点集合的并集。

把集群看作一个整体,理解这层结构后就会发现:控制面再怎么聪明,没有工作节点去执行就是纸上谈兵;工作节点再拼命,没有控制面的调度和校验也会各自为战。酒店的“管理区+楼层区”缺一不可,Kubernetes 的“控制面+工作节点”也正是这样形成合力的。

Cluster=Control Plane∪Worker Nodes\displaystyle \text{Cluster} = \text{Control Plane} \cup \text{Worker Nodes}
集群由两大部分组成:控制面负责决策,工作节点负责执行,中间通过内部网络通信。
  1. 集群等号左边代表整个 K8s 集群,右边说明它由两部分拼接而成。
    Cluster\text{Cluster}
  2. 控制面集合包含 API Server、etcd、Scheduler、Controller Manager 的组件组,是集群的大脑。
    Control Plane\text{Control Plane}
  3. 并集符号表示两个区域通过网络连成一个整体,缺一不可。
    ∪\cup
  4. 工作节点集合包含 kubelet、容器运行时、kube-proxy 的机器,负责运行业务容器。
    Worker Nodes\text{Worker Nodes}

统一入口

在酒店里,客人不会直接冲进档案室或厨房,所有入住、换房、点餐都要从总台登记。总台是唯一的对外窗口,也是唯一有权限修改房态记录的地方。K8s 里的 API Server 就是这样一个总台。

不管你是敲 kubectl 命令,还是用 SDK 调用,所有操作最终都会变成 REST 请求打到 API Server。它是集群里唯一的“写入口”,其他组件都不许绕过它私自改状态。API Server 会先做身份认证和权限校验,再经过准入控制,最后把资源状态写入 etcd。它的 Watch 机制还会主动把变化推送给订阅方,让其他组件第一时间感知。

一次普通请求的流转链路可以写成:

正因为一切都要过总台,K8s 才能保证订单的流程、校验、留痕都统一。设想一下,如果每个管理员都能直接改档案室,酒店必然乱套;让 API Server 大权独揽,虽然多了一道排队,却换来了整个集群的秩序。

Request→API Server→etcd\displaystyle \text{Request} \rightarrow \text{API Server} \rightarrow \text{etcd}
用户请求先到 API Server,通过校验后再写入 etcd;Scheduler、Controller 等组件都依赖这条链路上的消息驱动。
  1. 请求对象用户执行 kubectl apply 或调用 SDK 时,生成一条包含资源期望状态的请求。
    Request\text{Request}
  2. 客户端工具kubectl 只是翻译官,它把命令格式化成 API Server 能理解的 HTTP 请求。
    →kubectl→\rightarrow \text{kubectl} \rightarrow
  3. API Server 网关集群唯一入口,负责认证、授权、准入控制,并转发写入。
    API Server\text{API Server}
  4. etcd 持久化API Server 通过 Raft 协议把状态写入分布式数据库,完成“存档”。
    →etcd\rightarrow \text{etcd}

状态仓库

档案室管理着一本大簿子,记录每个房间住的是谁、几点退房、是否有维修订单。任何人想了解房态,要么查档案,要么等档案室主动喊一嗓子。etcd 就是这本大簿子。

etcd 是 K8s 的分布式键值数据库,保存所有资源对象,包括 Deployment、Pod、Service 等。它不只存“配置”,而是整个集群的“唯一真相源”。为了不让数据混乱,etcd 通过 Raft 共识算法在多个副本之间同步,只有过半数副本确认才能写入。控制器们不需要反复轮询检查,而是用 Watch 机制盯着感兴趣的键,一旦发生变化立刻收到通知。

Raft 算法的关键数字是“法定人数”:

Raft 的法定人数规则就像开“紧急会议”:3 个档案员只要有 2 个确认就能拍板,5 个只要有 3 个确认。单个档案员请假不影响酒店运转。备份与恢复同样重要,因为档案一旦丢失,整个酒店的房态就成了谜。

q=⌊n2⌋+1\displaystyle q = \lfloor \frac{n}{2} \rfloor + 1
对 n 节点 etcd 集群,至少 q 个节点确认才能提交写入;少于一半节点故障,集群仍可工作。
  1. 法定人数 q一次写入需要至少多少个节点确认,q 是多数派的阈值。
    qq
  2. 半数取整n 个节点中先取一半,向下取整。
    ⌊n2⌋\lfloor \frac{n}{2} \rfloor
  3. 加一让数量严格超过一半,保证不会出现“两个多数派”分裂。
    +1+1
  4. 多数派保证3 节点集群 q=2,5 节点集群 q=3,这就是 Raft 的容错上限。
    n故障<n2n_{\text{故障}} < \frac{n}{2}

调度控制

排班经理拿到入住单,会先看哪些房间空着、资源是否满足要求,再决定派给哪个楼层。质检主管则不会检查一次就下班,而是每天对照标准手册巡逻,发现差距就安排整改。Scheduler 和 Controller Manager 正是这两位关键角色。

Scheduler 负责为新 Pod 选择最合适的工作节点:先过滤掉资源不足或不满足限制的节点,再对剩余候选节点打分,选出最优解。Controller Manager 里有一组控制器,例如 ReplicaSet 控制器,它们维护着一个控制循环:观察当前副本数,与期望副本数比较,若差异不为零就去创建或删除 Pod。你只需要在 YAML 里声明“我要 3 个副本”,系统就会持续调谐到满足期望,这就是声明式模型。

控制循环的“灵魂”是一个差值公式:

控制循环的核心思路,就是“盯着差距、反复修正”。这个逻辑让 K8s 具备强大的自愈能力:Pod 挂了就重新拉起,副本多了就自动回收,完全不需要工程师登录服务器手工处理。

Δ=Sdesired−Scurrent\displaystyle \Delta = S_{\text{desired}} - S_{\text{current}}
控制器反复计算期望状态与当前状态的差值,差值不为 0 就触发动作,直到差值归 0。
  1. 期望状态由用户在 YAML 中声明的目标,比如“运行 3 个副本”。
    SdesiredS_{\text{desired}}
  2. 当前状态集群中实际观察到的数量,比如现在只有 1 个副本。
    ScurrentS_{\text{current}}
  3. 差值二者相减。大于 0 表示不足,小于 0 表示多余。
    Δ\Delta
  4. 调谐目标不断调整直到 Δ=0,这是所有控制器的共同目标。
    Δ→0\Delta \rightarrow 0

节点执行

酒店管理区做了再完美的排班计划,还是要靠楼层领班敲开房门、检查床单、启用物品。楼层领班是管理区与客房之间的最后一道交接人。在 K8s 中,这道交接人就是 kubelet。

kubelet 运行在每个工作节点上,负责从 API Server 接收 Pod 的期望规格,然后调用容器运行时创建或销毁容器,并持续汇报运行状态。由于它只负责本节点,控制平面不必亲自登录每台机器。节点上的 kube-proxy 则像礼宾接线员:维护网络规则,让来自外部的访问能够负载均衡地转发到正确的 Pod。Pod 是 K8s 上最小的部署单元,可以装一个或多个容器,共享网络 IP 和存储卷。

Pod 的结构可以概括为:

你可以把 Pod 理解成“一间双人房”:几位客人共享同一个水电地址,楼层领班只检查整间房的状态。这样的设计让容器的生命周期、健康检查、流量接入被框进同一个管理单元,K8s 才能整齐划一地指挥成千上万个容器。

Pod=共享网络+共享存储+N×容器\displaystyle \text{Pod} = \text{共享网络} + \text{共享存储} + N\times\text{容器}
Pod 是 K8s 调度的最小单位,一组容器共享网络和存储,对外表现为一个整体环境。
  1. 调度单元K8s 不直接调度单个容器,而是把关系紧密的容器打包成 Pod。
    Pod\text{Pod}
  2. 共享网络一个 Pod 一个 IP,容器之间通过 localhost 互通,共用一个网络命名空间。
    共享网络\text{共享网络}
  3. 共享存储Pod 内容器可挂载同一个卷,数据交换不依赖网络。
    共享存储\text{共享存储}
  4. N 个容器通常一个主容器加若干边车容器,协作完成一个完整任务。
    N×容器N\times\text{容器}

运维实践

酒店经营久了,你会发现总台高峰排队、档案室磁盘变慢、某个楼层领班失联。成熟酒店会配置多套总台、定期备份档案,并对每个楼层做心跳巡检。K8s 的运维实践也围绕这几点展开。

首先是高可用设计:控制面通常部署多个节点,etcd 也做多副本,避免单点故障;工作节点通过资源预留避免 Pod 与系统组件争抢资源。其次是调优:给 API Server 配置合理的 QPS 和审计级别,给 etcd 更换高性能磁盘并开启压缩与定期快照,给 Scheduler 调整抢占策略和过滤逻辑。故障排查时,可以先用 kubectl describe、kubectl get events 看事件,再沿着“API Server → etcd → Controller → kubelet”的链路逐层定位。

系统可用性可以用这个公式表达:

可用性公式告诉我们:想让系统更可靠,要么延长“好日子”,要么缩短“坏日子”。K8s 的高可用架构和监控告警,本质上都是为了把这个分数做到 99.99%。

A=MTBFMTBF+MTTR\displaystyle A = \frac{\text{MTBF}}{\text{MTBF} + \text{MTTR}}
可用性的高低同时取决于“稳定运行时长 MTBF”和“故障恢复时长 MTTR”,两者都会直接影响 A。
  1. 可用性 A系统实际可用的时间占比,生产环境通常追求 99.9% 以上。
    AA
  2. 平均无故障时间 MTBF两次故障之间平均能撑多久,越长越好。
    MTBF\text{MTBF}
  3. 平均修复时间 MTTR从故障发生到恢复需要多久,越短越能减少损失。
    MTTR\text{MTTR}
  4. 比值关系MTTR 越小或 MTBF 越大,A 越接近 1,这就是高可用的底层逻辑。
    MTBFMTBF+MTTR\frac{\text{MTBF}}{\text{MTBF} + \text{MTTR}}

AI 应用场景

GitOps 发布平台

阶段:部署 / 交付

解决的问题:传统做法是用 SSH 登录服务器手动改配置,操作零散、容易漂移;GitOps 把“期望状态”写进 Git,AI 平台自动监听并同步,实现可审计、可回滚的发布。

具体案例:某金融团队把数百个微服务的 Deployment YAML 都放进 Git 仓库,ArgoCD 持续比较 Git 中的期望状态与集群当前状态。工程师只需合并代码,API Server 就会自动接收新期望,Controller Manager 和 Scheduler 随之完成滚动更新。

弹性扩缩容

阶段:资源调度与弹性伸缩

解决的问题:人工预估流量既不及时也容易浪费;K8s 的 HPA 控制器持续采集 CPU 与请求量指标,根据公式计算期望副本数,并用 API Server 更新副本数,让系统自动贴合流量曲线。

具体案例:电商大促时订单量短时间翻倍,HPA 在几分钟内把核心服务从 20 个副本扩到 80 个副本;流量回落后再自动缩容,节省大批成本。

故障自愈

阶段:故障恢复

解决的问题:传统环境某个节点宕机,需要人工到场处理,恢复周期以小时计;K8s 的 Controller Manager 通过心跳发现节点失联,自动在其他健康节点重建 Pod。

具体案例:某游戏公司的云供应商节点突然宕机,kubelet 失联后,控制面自动把游戏大厅 Pod 迁移到剩余节点,玩家几乎无感。

Python 演示

python37 行
import time class ReplicaSetSimulator:    def __init__(self, desired, initial, max_step=2):        self.desired = desired        self.current = initial        self.max_step = max_step     def observe(self):        return self.current     def compute_delta(self):        return self.desired - self.observe()     def reconcile(self):        diff = self.compute_delta()        if diff > 0:            action = min(diff, self.max_step)        elif diff < 0:            action = max(diff, -self.max_step)        else:            action = 0        self.current += action        return action def main():    sim = ReplicaSetSimulator(desired=5, initial=1)    for t in range(8):        action = sim.reconcile()        status = "已到达期望副本数" if sim.current == sim.desired else "继续调谐"        print(f"t={t}: current={sim.current}, delta={sim.desired - sim.current:>+d}, action={action:>+d}, {status}")        if sim.current == sim.desired:            break        time.sleep(0.2) if __name__ == "__main__":    main()
目的:用最简语言实现 Kubernetes 控制循环的核心逻辑:观察、对比、调谐,直到当前状态收敛到期望状态。
  1. def compute_delta(self):计算当前状态与期望状态的差值,这就是控制循环中的核心变量 Δ。
  2. def reconcile(self):执行一次调谐动作,对应 Controller Manager 每次循环所做的“纠偏”。
  3. action = min(diff, self.max_step)限制单次最大伸缩量,避免系统震荡。
  4. if sim.current == sim.desired: break当 Δ=0 时停止调谐,对应 K8s 中“已达到期望状态”。

常见误区

误区我以为执行 `kubectl apply` 后,YAML 会直接发送到工作节点的 kubelet,然后 kubelet 立刻创建容器。

正解kubectl apply 只是把资源对象交给 API Server。API Server 校验后写入 etcd,Controller 看到期望状态后创建副本,Scheduler 选定节点,最后 kubelet 才拉镜像并启动容器。整个过程是异步的,没有“直接推给 kubelet”这一步。

为何常见:用户看到容器最终启动了,就把“最终执行者”当成了“唯一执行者”,忽略了中间的控制面链条。

误区既然 etcd 存数据,那我可以直接连上去改几个 key 来修复 K8s 配置。

正解etcd 是集群的唯一真相源,但只有 API Server 能按规则写入。直接修改 etcd 会绕过认证、准入控制和版本校验,极易造成数据不一致,甚至让整个集群控制面崩溃。

为何常见:工程师习惯“连数据库改数据”的运维方式,却不理解 K8s 把写入权限收口到 API Server 的设计意图。

误区Scheduler 选定节点后,会直接在该节点上启动 Pod 进程。

正解Scheduler 只做“决策”,把 Pod 的节点归属写进资源对象;真正创建容器的动作由 kubelet 调用容器运行时完成。这就像排班经理只写排班表,楼层领班才实际去敲门保洁。

为何常见:调度和启动通常在很短时间内连续发生,感官上像同一个动作。

误区需要手动把 Deployment 副本数从 2 改成 5,然后 Controller Manager 会一次性创建 3 个 Pod。

正解Controller Manager 是持续运行的控制循环:不断观察当前数量、计算差值、发出变更请求。它不是被工程师触发的一次性工具,而是一个永远在“观察-比较-调谐”的自动化线程。

为何常见:用户只观察到“修改 YAML 后副本数变化”,却看不到后台一直在运行中的循环。

面试题

Q1. 以下哪个是 K8s 集群唯一的请求入口?

单选题 · easy

  • A.调度器组件
  • B.API 前端组件← 正确答案
  • C.注册中心组件
  • D.节点代理组件

答案:B。API Server 相当于酒店总台,所有 kubectl 和 SDK 请求都必须经过它。Scheduler 负责排班,etcd 负责存储,kubelet 负责执行,它们都不是用户请求的统一入口。

Q2. 在 K8s 中保存整个集群资源状态的是?

单选题 · easy

  • A.容器运行时组件
  • B.资源调度器组件
  • C.键值仓库组件← 正确答案
  • D.服务代理组件

答案:C。etcd 是 K8s 的“唯一真相源”,保存所有资源对象。容器运行时只负责跑容器,调度器负责选节点,代理负责网络转发。

Q3. 工作节点上常驻的关键组件是?

单选题 · easy

  • A.API 服务组件
  • B.控制循环组件
  • C.节点代理组件← 正确答案
  • D.键值存储组件

答案:C。kubelet 是典型的节点代理组件,工作节点通过它与 API Server 通信并管理 Pod。API Server、etcd、Scheduler 和 Controller Manager 都运行在控制面。

Q4. 声明式模型的核心思想是?

单选题 · mid

  • A.逐步下发命令
  • B.只看当前状态
  • C.声明期望后自愈← 正确答案
  • D.依靠人工修正

答案:C。声明式模型强调“告诉我你要什么,而不是怎么做”。用户声明期望状态,Controller 通过控制循环自动调谐,这就是自愈能力的关键。

Q5. 谁负责为 Pod 选择最合适的工作节点?

单选题 · mid

  • A.控制器组件
  • B.节点代理组件
  • C.调度器组件← 正确答案
  • D.API 服务组件

答案:C。Scheduler 负责对新 Pod 进行过滤和打分,最终决定调度到哪个节点;kubelet 只在节点上执行,Controller 负责调谐副本数。

Q6. 5 节点 etcd 集群写入数据至少需要几个节点确认?

单选题 · extreme

  • A.至少 1 个
  • B.至少 2 个
  • C.至少 3 个← 正确答案
  • D.至少 4 个

答案:C。Raft 要求多数派确认,q=⌊5/2⌋+1=3。因此集群最多允许 2 个节点故障,相当于开投票会议必须过半数组人员到场。

Q7. 当控制器发现实际副本数大于期望副本数时,它通常会怎么做?

单选题 · hard

  • A.修改期望副本值
  • B.直接杀掉进程
  • C.请求删除多余 Pod← 正确答案
  • D.等待用户来处理

答案:C。控制器不会修改用户声明,而是通过 API Server 删除多余的 Pod,让当前状态收敛回期望状态。这对应控制循环中 Δ<0 时的调谐动作。

Q8. 控制面节点上包含哪些核心组件?

多选题 · mid

  • A.API 服务组件← 正确答案
  • B.键值存储组件← 正确答案
  • C.调度器组件← 正确答案
  • D.节点代理组件

答案:ABC。API Server、etcd、Scheduler、Controller Manager 都部署在控制面;kubelet 属于工作节点,不运行在控制面节点上。

Q9. 控制循环的经典步骤包括?

多选题 · mid

  • A.观察当前状态← 正确答案
  • B.对比期望状态← 正确答案
  • C.执行调谐动作← 正确答案
  • D.直接改用户配置

答案:ABC。控制循环是“观察→对比→调谐”的闭环:先观察当前状态,再和期望状态比较,最后执行动作拉平差距。它不会修改用户的 YAML 配置。

Q10. 关于 API Server 的说法,正确的是?

多选题 · hard

  • A.它是集群唯一写入口← 正确答案
  • B.它支持 Watch 订阅机制← 正确答案
  • C.所有请求都经过它← 正确答案
  • D.它直接运行用户容器

答案:ABC。API Server 是所有请求的必经之路,且只有它能写 etcd;它的 Watch 机制让 Scheduler、Controller 能实时感知变化。但它不直接管理容器,那是 kubelet 的职责。