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)   │       │
       │   └─────────┘    └─────────┘    └─────────┘       │
       │        ▲                            │              │
       │        └────────────────────────────┘              │
       │              持续循环,不断调谐                      │
       └──────────────────────────────────────────────────────┘
  1. 观察(Observe) :控制器通过 API Server 获取资源的当前实际状态。
  2. 比较(Compare) :将实际状态与用户定义的期望状态进行对比。
  3. 执行(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 并处理所有请求。

核心职责:

  1. 唯一入口:所有操作——无论是用户通过 kubectl 发出的命令、各组件之间的通信,还是对集群状态的任何变更——都必须经过 API Server。
  2. 认证(Authentication) :验证请求发起者的身份(X.509 证书、Bearer Token 等)。
  3. 授权(Authorization) :基于 RBAC 策略验证该身份是否有权执行所请求的操作。
  4. 准入控制(Admission Control) :在对象持久化之前,通过 MutatingWebhook 和 ValidatingWebhook 对资源进行修改或校验。
  5. 数据持久化:只有 API Server 能直接与 etcd 交互,它将验证通过的数据存入 etcd。

关键特性:kube-apiserver 设计上考虑了水平扩缩,可通过部署多个实例并在它们之间平衡流量来实现高可用。

3.2 etcd —— 集群的“档案室”

etcd 是一个一致且高可用的分布式键值存储,用作 Kubernetes 所有集群数据的后台数据库。

核心职责:

  1. 数据存储:存储所有的集群数据,包括节点信息、Pod 信息、Service 配置、Secret 等。
  2. 一致性保证:通过 Raft 一致性算法保证数据在多个副本间的一致性和可靠性。
  3. 高可用性:生产环境通常部署奇数个节点(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

详细步骤说明

  1. 资源提交:用户通过 kubectl apply 提交 YAML 配置文件。
  2. 认证授权链:API Server 依次进行身份认证、权限验证和准入控制。
  3. 状态持久化:验证通过后,API Server 将资源对象通过 gRPC 协议写入 etcd 集群,采用乐观并发控制保证数据一致性。
  4. 控制器响应
    • Deployment Controller 监听到新的 Deployment 对象,创建对应的 ReplicaSet。
    • ReplicaSet Controller 监听到新的 ReplicaSet,创建指定数量的 Pod。
  5. 调度决策Scheduler 监听到未调度的 Pod,经过预选和优选,选择一个最合适的节点,更新 Pod 的 nodeName 字段。
  6. 节点执行:目标节点上的 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节点上是否有指定的主机端口可用
PodFitsHostPod 是否要求运行在特定的节点上
NoDiskConflict节点上是否有 Pod 使用了同一持久卷
MatchNodeSelector节点标签是否满足 Pod 的节点选择器
PodToleratesNodeTaintsPod 是否容忍节点的污点(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)

调谐循环是控制器的核心执行逻辑:

  1. 获取对象:从本地缓存或 API Server 获取目标资源的当前状态。
  2. 计算差异:将当前状态与期望状态(Spec)进行对比。
  3. 执行调谐:如果存在差异,执行必要的操作(创建、更新或删除资源)来消除差异。
  4. 更新状态:操作完成后,更新资源的 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 和容器正常运行。

核心职责

  1. Pod 生命周期管理:接收 API Server 分配的 PodSpec(通过监听 API Server、本地配置文件或 HTTP 端点等方式),调用容器运行时创建、启动、停止和删除容器。
  2. 同步循环(Sync Loop) :kubelet 运行一个周期性同步循环,不断将期望状态(Pod 规约)与运行中容器的实际状态进行协调。
  3. 健康检查:定期执行存活探针(Liveness Probe)和就绪探针(Readiness Probe),检查容器的健康状态。
  4. 节点状态上报:定期向 API Server 上报节点状态(心跳)和资源使用情况。
  5. 节点压力驱逐(Node-pressure Eviction) :当节点资源(内存、磁盘空间、inode 等)达到特定消耗水平时,kubelet 主动终止 Pod 以回收资源。

关键机制:kubelet 使用 PLEG(Pod Lifecycle Event Generator,Pod 生命周期事件生成器) 来感知容器何时启动、停止或失败。

7.2 kube-proxy —— 节点的“网络接线员”

kube-proxy 运行在每个节点上,负责维护节点上的网络规则,实现 Service 的网络代理和负载均衡功能。

核心职责

  1. 监听变化:kube-proxy 持续监听 API Server 中 Service 和 Endpoint 对象的变化。
  2. 规则编程:根据监听到的变化,动态更新节点上的网络规则(iptables 或 IPVS 规则)。
  3. 流量转发:当访问 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 网络模型遵循四个基本原则:

  1. 节点上的 Pod 可以不通过 NAT 和其他节点上的 Pod 通信
  2. 节点上的代理(如 kubelet)可以不通过 NAT 和该节点上的 Pod 通信
  3. 运行在节点上的 Pod 可以不通过 NAT 和该节点上的代理通信
  4. 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 的逻辑集合以及访问它们的策略。

工作流程

  1. 用户创建 Service,通过 Label Selector 选择后端 Pod。
  2. kube-proxy 监听到 Service 和 Endpoint 的变化。
  3. kube-proxy 在节点上更新 iptables/IPVS 规则。
  4. 访问 Service IP 的流量被重定向到后端的 Pod。

跨节点 Pod 通信(Overlay 模式示例)

  1. 发送节点将原始 IP 包封装在 VXLAN/UDP 头中,添加外层源/目的 IP(节点间通信地址)。
  2. 数据包通过物理网络传输到目标节点。
  3. 接收节点解封装后,根据内层 IP 查找目标 Pod。
  4. 通过 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 驱动的工作流程

  1. 用户创建 PVC 后,控制器管理器调用 CSI 驱动的 CreateVolume 接口。
  2. 驱动在底层存储系统中创建实际的存储卷,返回卷标识。
  3. 调度器确定 Pod 运行的节点后,该节点上的 kubelet 调用 CSI 驱动的 NodePublishVolume 将卷挂载到容器。
  4. 删除 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 官方文档

更多推荐