# Kubernetes 核心原理深度解析 ##
Kubernetes 核心原理深度解析
文档概述
本文档深入解析 Kubernetes 的核心工作原理,从声明式 API 与控制循环的设计哲学出发,系统阐述控制平面与数据平面各组件的职责、交互机制与协作流程,帮助读者理解 Kubernetes 如何通过**“观察-比较-执行”**的闭环控制模型,实现分布式系统的自动化管理与自愈能力。
第一章:Kubernetes 的设计哲学
1.1 声明式 API:告诉系统“要什么”,而不是“怎么做”
Kubernetes 最核心的设计思想是声明式 API。用户通过 YAML 或 JSON 格式的配置文件定义资源的期望状态(Desired State) ,系统负责自动实现并维持这一状态。
命令式 vs 声明式:
| 模式 | 用户行为 | 系统行为 | 类比 |
|---|---|---|---|
| 命令式 | 告诉系统“怎么做”,一步步下达指令 | 被动执行每一步 | 告诉厨师“先切菜、再热锅、再翻炒……” |
| 声明式 | 告诉系统“要什么”,描述最终目标 | 自动规划并执行,持续维持目标 | 告诉服务员“我要一份宫保鸡丁” |
在 Kubernetes 中,声明式 API 的具体体现是:用户提交一份 YAML 文件(例如“我需要 3 个 Nginx 副本一直运行”),Kubernetes 不会仅仅执行一次创建操作就结束,而是持续监控,确保这个状态始终被维持。
1.2 控制循环(Control Loop):Kubernetes 的“自动驾驶”机制
Kubernetes 的架构设计遵循 “控制循环” 这一核心理念。控制循环是一种持续监控系统状态并与期望状态进行比对,自动执行必要调整操作的机制。
控制循环的工作流程:
┌──────────────────────────────────────────────────────┐
│ 控制循环 │
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ 观察 │───▶│ 比较 │───▶│ 执行 │ │
│ │(Observe)│ │(Compare)│ │(Act) │ │
│ └─────────┘ └─────────┘ └─────────┘ │
│ ▲ │ │
│ └────────────────────────────┘ │
│ 持续循环,不断调谐 │
└──────────────────────────────────────────────────────┘
- 观察(Observe) :控制器通过 API Server 获取资源的当前实际状态。
- 比较(Compare) :将实际状态与用户定义的期望状态进行对比。
- 执行(Act) :如果发现偏差,执行调谐操作(创建、更新或删除资源),使实际状态向期望状态收敛。
这个循环永不停止——即使状态已经匹配,控制器依然会持续监控,确保一旦发生故障(如 Pod 崩溃、节点宕机),系统能立刻响应并恢复。
1.3 一切皆资源(Everything is a Resource)
在 Kubernetes 中,一切都是资源(Resource) 。Pod、Deployment、Service、ConfigMap 等,都是 API 中的资源对象。每种资源都有:
- 一个 API 版本(如
apps/v1) - 一个 Kind(资源类型,如
Deployment) - 一个 metadata(名称、命名空间、标签等)
- 一个 spec(期望状态,由用户定义)
- 一个 status(实际状态,由系统维护)
这种“一切皆资源”的设计,使得 Kubernetes 可以通过统一的 API 接口管理所有对象,并且极其可扩展——用户可以定义自己的资源类型(Custom Resource),编写自定义控制器来实现任何想要的自动化逻辑。
第二章:集群架构总览
Kubernetes 集群由两大部分组成:控制平面(Control Plane) 和工作节点(Worker Nodes) 。
┌─────────────────────────────────────────────────────────────────────┐
│ Kubernetes 集群 │
│ ┌───────────────────────────────────────────────────────────────┐ │
│ │ 控制平面 (Control Plane) │ │
│ │ ┌──────────────┐ ┌──────────────┐ ┌────────────────────┐ │ │
│ │ │ API Server │ │ Scheduler │ │ Controller Manager │ │ │
│ │ │ (唯一入口) │ │ (调度决策) │ │ (状态调谐) │ │ │
│ │ └──────────────┘ └──────────────┘ └────────────────────┘ │ │
│ │ ┌──────────────────────────────────────────────────────────┐ │ │
│ │ │ etcd (状态存储) │ │ │
│ │ └──────────────────────────────────────────────────────────┘ │ │
│ └───────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌─────────────────┼─────────────────┐ │
│ ▼ ▼ ▼ │
│ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │
│ │ Node 1 │ │ Node 2 │ │ Node 3 │ │
│ │ ┌────────────┐ │ │ ┌────────────┐ │ │ ┌────────────┐ │ │
│ │ │ Pod A │ │ │ │ Pod B │ │ │ │ Pod C │ │ │
│ │ └────────────┘ │ │ └────────────┘ │ │ └────────────┘ │ │
│ │ kubelet │ │ kubelet │ │ kubelet │ │
│ │ kube-proxy │ │ kube-proxy │ │ kube-proxy │ │
│ │ 容器运行时 │ │ 容器运行时 │ │ 容器运行时 │ │
│ └──────────────────┘ └──────────────────┘ └──────────────────┘ │
└─────────────────────────────────────────────────────────────────────┘
控制平面负责管理集群的整体状态,做出全局决策(如调度),并检测和响应集群事件。工作节点则是实际运行容器化应用的地方。
第三章:控制平面组件详解
控制平面是 Kubernetes 集群的 “大脑” 。生产环境中,控制平面通常跨多台计算机运行,以提供容错和高可用。
3.1 API Server(kube-apiserver)—— 集群的“唯一入口”
API Server 是 Kubernetes 控制平面的前端,负责公开 Kubernetes API 并处理所有请求。
核心职责:
- 唯一入口:所有操作——无论是用户通过
kubectl发出的命令、各组件之间的通信,还是对集群状态的任何变更——都必须经过 API Server。 - 认证(Authentication) :验证请求发起者的身份(X.509 证书、Bearer Token 等)。
- 授权(Authorization) :基于 RBAC 策略验证该身份是否有权执行所请求的操作。
- 准入控制(Admission Control) :在对象持久化之前,通过 MutatingWebhook 和 ValidatingWebhook 对资源进行修改或校验。
- 数据持久化:只有 API Server 能直接与 etcd 交互,它将验证通过的数据存入 etcd。
关键特性:kube-apiserver 设计上考虑了水平扩缩,可通过部署多个实例并在它们之间平衡流量来实现高可用。
3.2 etcd —— 集群的“档案室”
etcd 是一个一致且高可用的分布式键值存储,用作 Kubernetes 所有集群数据的后台数据库。
核心职责:
- 数据存储:存储所有的集群数据,包括节点信息、Pod 信息、Service 配置、Secret 等。
- 一致性保证:通过 Raft 一致性算法保证数据在多个副本间的一致性和可靠性。
- 高可用性:生产环境通常部署奇数个节点(3、5 或 7 个)组成 etcd 集群,支持故障自动恢复。
⚠️ 重要提示:etcd 中存储着集群的全部数据,务必制定并执行定期备份计划。etcd 损坏将导致整个集群瘫痪。
3.3 Scheduler(kube-scheduler)—— 集群的“调度员”
Scheduler 负责监视新创建的、尚未指定运行节点的 Pod,并为它们选择最合适的节点来运行。
调度决策考虑的因素包括:单个 Pod 及多个 Pod 集合的资源需求、软硬件及策略约束、亲和性与反亲和性规范、数据位置、工作负载间的干扰以及最后时限。
调度器的工作流程分为两个阶段(详见第四章)。
3.4 Controller Manager(kube-controller-manager)—— 集群的“监工”
Controller Manager 是一个在单个二进制文件中运行多个控制器的守护进程。每个控制器负责管理一种特定类型的资源。
核心控制器及其功能:
| 控制器 | 主要功能 | 适用场景 |
|---|---|---|
| ReplicaSet Controller | 确保指定数量的 Pod 副本始终运行 | 无状态应用部署 |
| Deployment Controller | 管理 ReplicaSet 的声明式更新和回滚 | 无状态应用的滚动更新 |
| StatefulSet Controller | 提供有序部署、稳定网络标识和持久存储 | 数据库、有状态中间件 |
| DaemonSet Controller | 确保所有(或部分)节点运行一个 Pod 副本 | 日志收集、节点监控 |
| Job/CronJob Controller | 运行一次性任务或定时任务 | 批处理作业、定时任务 |
| Node Controller | 监控节点健康状态,处理节点故障 | 节点生命周期管理 |
| Endpoint Controller | 填充 Service 和 Pod 之间的端点信息 | 服务发现 |
| Persistent Volume Controller | 管理 PV 与 PVC 的绑定 | 持久化存储 |
Controller Manager 的工作方式:每个控制器都运行在一个调谐循环(Reconciliation Loop) 中,持续将集群的当前状态与资源清单中定义的期望状态进行比对,一旦发现差异就采取行动来消除差异。
第四章:核心工作流程——组件如何协作
4.1 声明式 API 的完整处理流程
以用户通过 kubectl apply 提交一个 Deployment 为例,完整的处理流程如下:
用户 ── kubectl apply ──▶ API Server ──▶ 认证/授权/准入 ──▶ etcd(持久化)
│
▼
┌─────────────┐
│ 期望状态 │
│ 已保存 │
└─────────────┘
│
┌─────────────────────┼─────────────────────┐
▼ ▼ ▼
Deployment ReplicaSet Scheduler
Controller Controller (监听新Pod)
监听到变化 监听到变化 │
│ │ ▼
▼ ▼ 选择节点
创建ReplicaSet 创建Pod 更新Pod的nodeName
│ │ │
└─────────────────────┼─────────────────────┘
▼
kubelet(目标节点)
│
▼
容器运行时启动容器
│
▼
Pod 进入 Running
详细步骤说明:
- 资源提交:用户通过
kubectl apply提交 YAML 配置文件。 - 认证授权链:API Server 依次进行身份认证、权限验证和准入控制。
- 状态持久化:验证通过后,API Server 将资源对象通过 gRPC 协议写入 etcd 集群,采用乐观并发控制保证数据一致性。
- 控制器响应:
- Deployment Controller 监听到新的 Deployment 对象,创建对应的 ReplicaSet。
- ReplicaSet Controller 监听到新的 ReplicaSet,创建指定数量的 Pod。
- 调度决策:Scheduler 监听到未调度的 Pod,经过预选和优选,选择一个最合适的节点,更新 Pod 的
nodeName字段。 - 节点执行:目标节点上的 kubelet 监听到被分配到自己这里的 Pod,调用容器运行时拉取镜像并启动容器。
4.2 Informer 机制:高效的状态同步
为了实现高效的状态监控,Kubernetes 采用 Informer 机制:
- List-Watch 长连接:控制器与 API Server 之间建立长连接,监听特定资源的变化事件。
- 本地缓存:控制器在本地维护一份资源缓存(Delta FIFO + Local Store),减少对 API Server 的直接调用压力。
- 事件分发:通过共享索引器(SharedIndexInformer)将事件分发给对应的处理器。
这种设计使得控制器无需频繁轮询 API Server,而是被动接收事件通知,大幅降低了 API Server 的负载。
第五章:调度器(Scheduler)工作原理
Scheduler 的核心任务是将 PodSpec.NodeName 为空的 Pod,经过预选(Predicates/Filtering) 和优选(Priorities/Scoring) 两个步骤,挑选最合适的节点作为该 Pod 的目标节点。
5.1 调度流程概览
新创建的 Pod(未调度)
│
▼
┌───────────────────┐
│ 预选(Filter) │ ← 过滤掉不满足条件的节点
│ 强制性规则 │
└─────────┬─────────┘
│ 候选节点列表
▼
┌───────────────────┐
│ 优选(Score) │ ← 为每个候选节点打分
│ 按优先级排序 │
└─────────┬─────────┘
│ 得分最高的节点
▼
┌───────────────────┐
│ 绑定(Bind) │ ← 将 Pod 绑定到该节点
└───────────────────┘
5.2 预选阶段(Filtering / Predicates)
预选阶段的目标是过滤掉所有不满足调度条件的节点。这是强制性规则——如果一个节点不满足任何一条预选策略,它就会被直接排除。
常见的预选策略:
| 预选策略 | 检查内容 |
|---|---|
PodFitsResources | 节点是否有足够的 CPU、内存等资源 |
PodFitsHostPorts | 节点上是否有指定的主机端口可用 |
PodFitsHost | Pod 是否要求运行在特定的节点上 |
NoDiskConflict | 节点上是否有 Pod 使用了同一持久卷 |
MatchNodeSelector | 节点标签是否满足 Pod 的节点选择器 |
PodToleratesNodeTaints | Pod 是否容忍节点的污点(Taints) |
CheckNodeUnschedulable | 节点是否被标记为不可调度 |
如果所有节点都不满足预选条件,Pod 将一直处于 Pending 状态,直到有节点满足条件。
5.3 优选阶段(Scoring / Priorities)
预选阶段之后,剩余的候选节点进入优选阶段。Scheduler 为每个候选节点打分,最终选择得分最高的节点。
常见的优选策略:
| 优选策略 | 打分依据 |
|---|---|
LeastRequestedPriority | 优先选择资源请求最少的节点(负载最低) |
BalancedResourceAllocation | 优先选择资源分配最平衡的节点 |
NodeAffinityPriority | 依据节点亲和性规则打分 |
TaintTolerationPriority | 依据污点容忍规则打分 |
节点分数 = 各插件打分 × 插件权重,然后排序选出分数最高的节点。
5.4 高级调度特性
节点亲和性(Node Affinity) :允许用户定义 Pod 只能调度到具有特定标签的节点上,是节点选择器(NodeSelector)的更灵活形式。
Pod 亲和性与反亲和性(Pod Affinity / Anti-Affinity) :允许用户定义 Pod 之间的调度关系——例如,某些 Pod 必须调度到同一节点(亲和性),或必须避免调度到同一节点(反亲和性)。
污点(Taints)与容忍度(Tolerations) :节点可以设置污点(Taints),只有声明了对应容忍度(Tolerations)的 Pod 才能被调度到该节点上。
第六章:控制器(Controller)工作原理
控制器是 Kubernetes “自愈能力” 的执行者。
6.1 控制器的核心模型
每个控制器都遵循相同的核心模型:
┌─────────────────────────────────────┐
│ 控制器工作模型 │
│ │
期望状态(Spec) ──▶│ ┌─────────┐ ┌─────────┐ │
│ │ Informer│───▶│ 工作队列 │ │
│ │ (事件监听)│ │(待处理任务)│ │
实际状态(Status)─▶│ └─────────┘ └────┬────┘ │
│ │ │
│ ▼ │
│ ┌─────────────┐ │
│ │ Reconcile │ │
│ │ (调谐函数) │ │
│ └─────────────┘ │
│ │ │
│ ▼ │
│ 创建/更新/删除资源 │
└─────────────────────────────────────┘
6.2 调谐循环(Reconcile Loop)
调谐循环是控制器的核心执行逻辑:
- 获取对象:从本地缓存或 API Server 获取目标资源的当前状态。
- 计算差异:将当前状态与期望状态(Spec)进行对比。
- 执行调谐:如果存在差异,执行必要的操作(创建、更新或删除资源)来消除差异。
- 更新状态:操作完成后,更新资源的 Status 字段,反映最新的实际状态。
伪代码示例(Deployment 控制器的核心逻辑):
func reconcileDeployment(key string) error {
// 1. 从缓存获取 Deployment 对象
deploy := getDeployment(key)
// 2. 获取该 Deployment 管理的所有 ReplicaSet
rsList := getReplicaSetsForDeployment(deploy)
// 3. 计算期望副本数与实际副本数的差异
desired := deploy.Spec.Replicas
actual := calculateCurrentReplicas(rsList)
// 4. 执行调谐操作
if actual < desired {
scaleUp(deploy, rsList) // 创建新的 ReplicaSet 或扩容
} else if actual > desired {
scaleDown(deploy, rsList) // 缩容
}
// 5. 更新 Deployment 的 Status
updateStatus(deploy, actual)
}
6.3 控制器的高可用机制
在高可用部署中,可能会运行多个 Controller Manager 实例,但只有一个实例作为活跃的领导者(Leader) 来执行操作,避免冲突。Kubernetes 使用 Leader Election 机制来决定哪个实例获得控制权。
第七章:节点组件(Node Components)工作原理
7.1 kubelet —— 节点的“管家”
kubelet 是运行在每个节点上的主要节点代理,负责确保节点上的 Pod 和容器正常运行。
核心职责:
- Pod 生命周期管理:接收 API Server 分配的 PodSpec(通过监听 API Server、本地配置文件或 HTTP 端点等方式),调用容器运行时创建、启动、停止和删除容器。
- 同步循环(Sync Loop) :kubelet 运行一个周期性同步循环,不断将期望状态(Pod 规约)与运行中容器的实际状态进行协调。
- 健康检查:定期执行存活探针(Liveness Probe)和就绪探针(Readiness Probe),检查容器的健康状态。
- 节点状态上报:定期向 API Server 上报节点状态(心跳)和资源使用情况。
- 节点压力驱逐(Node-pressure Eviction) :当节点资源(内存、磁盘空间、inode 等)达到特定消耗水平时,kubelet 主动终止 Pod 以回收资源。
关键机制:kubelet 使用 PLEG(Pod Lifecycle Event Generator,Pod 生命周期事件生成器) 来感知容器何时启动、停止或失败。
7.2 kube-proxy —— 节点的“网络接线员”
kube-proxy 运行在每个节点上,负责维护节点上的网络规则,实现 Service 的网络代理和负载均衡功能。
核心职责:
- 监听变化:kube-proxy 持续监听 API Server 中 Service 和 Endpoint 对象的变化。
- 规则编程:根据监听到的变化,动态更新节点上的网络规则(iptables 或 IPVS 规则)。
- 流量转发:当访问 Service IP 时,网络规则将流量重定向到后端 Pod。
两种代理模式:
| 模式 | 原理 | 适用场景 |
|---|---|---|
| iptables | 通过 iptables 规则实现流量转发,是默认模式 | 中小型集群,兼容性广泛 |
| IPVS | 使用 Linux 内核的 IPVS 模块实现负载均衡,性能更高 | 大型集群,需要高性能负载均衡 |
IPVS 模式相比 iptables 模式具有更好的可扩展性和性能,因为 IPVS 专为大量服务的负载均衡而设计,使用优化的查找算法而非顺序规则匹配。
注意:一些网络插件(如 Cilium)提供了自己的 kube-proxy 替代实现,这种情况下节点可以不运行 kube-proxy。
7.3 容器运行时(Container Runtime)
容器运行时是真正运行容器的软件。
- 功能:拉取镜像、创建容器、启动容器、停止容器——所有和“运行容器”相关的底层操作。
- 常见选择:containerd(最常用)、CRI-O、Docker 等。
- 接口标准:Kubernetes 通过 CRI(Container Runtime Interface,容器运行时接口) 与容器运行时交互,实现了运行时与 Kubernetes 的解耦。
第八章:网络原理
Kubernetes 网络模型的核心目标是实现 “所有 Pod 可直接通信” 的扁平化网络架构。
8.1 网络模型的基本原则
Kubernetes 网络模型遵循四个基本原则:
- 节点上的 Pod 可以不通过 NAT 和其他节点上的 Pod 通信。
- 节点上的代理(如 kubelet)可以不通过 NAT 和该节点上的 Pod 通信。
- 运行在节点上的 Pod 可以不通过 NAT 和该节点上的代理通信。
- Pod 看到的自己的 IP 与其他 Pod 看到的一致。
8.2 CNI(容器网络接口)
CNI 是容器网络的标准接口,定义了网络插件的接入规范。Kubernetes 通过 CNI 插件来配置 Pod 的网络。
CNI 插件的职责:
- 为 Pod 分配 IP 地址(通过 IPAM 模块)
- 配置节点上的路由表
- 创建 veth pair 将 Pod 的网络命名空间连接到主机网络
常见的 CNI 插件:Calico、Flannel、Weave、Cilium 等。
8.3 Service 与 kube-proxy 的网络实现
Service 是 Kubernetes 中一种抽象,它定义了一组 Pod 的逻辑集合以及访问它们的策略。
工作流程:
- 用户创建 Service,通过 Label Selector 选择后端 Pod。
- kube-proxy 监听到 Service 和 Endpoint 的变化。
- kube-proxy 在节点上更新 iptables/IPVS 规则。
- 访问 Service IP 的流量被重定向到后端的 Pod。
跨节点 Pod 通信(Overlay 模式示例) :
- 发送节点将原始 IP 包封装在 VXLAN/UDP 头中,添加外层源/目的 IP(节点间通信地址)。
- 数据包通过物理网络传输到目标节点。
- 接收节点解封装后,根据内层 IP 查找目标 Pod。
- 通过 veth pair 将数据包转发到目标容器的网络命名空间。
8.4 网络策略(NetworkPolicy)
NetworkPolicy 是一种声明式的 Pod 间网络访问控制机制。
- Ingress(入站) :控制哪些源可以访问被选中的 Pod。
- Egress(出站) :控制被选中的 Pod 可以访问哪些目标。
- 默认行为:如果命名空间中不存在 NetworkPolicy,则所有进出该命名空间 Pod 的流量都被允许。
- 实现:NetworkPolicy 由实现了 CNI 接口的网络插件(如 Calico、Cilium)提供支持。
第九章:存储原理
9.1 为什么需要持久化存储?
容器默认是无状态的——Pod 删除后,容器内的所有数据都会丢失。对于数据库、消息队列等有状态应用,需要持久化存储来保存数据。
9.2 PV / PVC / StorageClass 三级架构
Kubernetes 通过 PV(PersistentVolume)、PVC(PersistentVolumeClaim)和 StorageClass 三级架构实现存储资源的抽象与管理。
| 概念 | 说明 | 类比 |
|---|---|---|
| PV | 集群级别的存储资源,由管理员预先配置 | 物理硬盘 |
| PVC | 用户对存储的申请,描述存储需求(大小、访问模式等) | 租用硬盘的申请单 |
| StorageClass | 定义存储类型和动态供应策略 | 硬盘型号目录 |
PVC 消耗 PV 资源,就像 Pod 消耗 Node 资源一样。开发者只需像申请 CPU 和内存一样声明所需的存储容量和访问模式,Kubernetes 会自动完成与底层存储的对接与挂载。
9.3 CSI(容器存储接口)
CSI(Container Storage Interface)是行业标准的容器存储接口。
CSI 的设计目标:
- 解耦:将存储插件从 Kubernetes 核心代码中解耦出来。
- 标准化:使存储供应商基于 CSI 标准开发的插件可以在不同容器编排系统中工作。
CSI 驱动的工作流程:
- 用户创建 PVC 后,控制器管理器调用 CSI 驱动的
CreateVolume接口。 - 驱动在底层存储系统中创建实际的存储卷,返回卷标识。
- 调度器确定 Pod 运行的节点后,该节点上的 kubelet 调用 CSI 驱动的
NodePublishVolume将卷挂载到容器。 - 删除 PVC 时,驱动根据
ReclaimPolicy(回收策略)决定保留还是删除卷。
第十章:总结——Kubernetes 的设计哲学
Kubernetes 的核心原理可以概括为以下几个层面:
10.1 声明式 API
用户通过 YAML 文件定义期望状态(Desired State),系统负责将实际状态收敛到期望状态。这种设计将用户从繁琐的“如何做”中解放出来,只需关注“要什么”。
10.2 控制循环
Kubernetes 通过**“观察-比较-执行”的闭环控制模型,持续驱动系统状态向目标收敛。这个模型赋予了 Kubernetes 强大的自愈能力和自动化管理**能力。
10.3 分层协作
控制平面(API Server、etcd、Scheduler、Controller Manager)与数据平面(kubelet、kube-proxy、容器运行时)分工明确、分层协作:
- 控制平面负责决策(调度、状态管理、事件响应)
- 数据平面负责执行(运行容器、管理网络、上报状态)
10.4 可扩展性
通过 CRD(自定义资源) 、Operator 模式、CSI(存储接口) 、CNI(网络接口) 和 CRI(运行时接口) ,Kubernetes 构建了一个高度可扩展的生态系统。
10.5 最终一致性
Kubernetes 不保证即时一致性,而是保证最终一致性(Eventual Consistency) ——系统会持续调谐,直到实际状态完全匹配期望状态。这种设计使得 Kubernetes 能够从容应对各种故障场景,实现自我修复。
文档版本:v1.0
适用环境:Kubernetes v1.28+
延伸阅读:Kubernetes 官方架构文档、etcd 官方文档
更多推荐
所有评论(0)