Kubernetes 总览架构深度分析
基于 Kubernetes 源码(
github.com/kubernetes/)的系统性架构分析文档。
目录
- 一、项目定位与业务职责
- 二、目录结构总览
- 三、整体架构图
- 四、组件交互图
- 五、数据流图
- 六、请求处理链路图
- [七、Etcd 存储架构图](#七、Etcd 存储架构图)
- 八、认证授权链路图
- 九、控制器协同图
- 十、调度框架与流程图
- [十一、Kubelet 节点架构图](#十一、Kubelet 节点架构图)
- [十二、网络模型与 Service 架构图](#十二、网络模型与 Service 架构图)
- [十三、Informer/Cache 机制图](#十三、Informer/Cache 机制图)
- 十四、插件化与扩展架构图
- [十五、声明式 API 与 Reconcile 模式](#十五、声明式 API 与 Reconcile 模式)
- [十六、Leader Election 高可用模式](#十六、Leader Election 高可用模式)
- 十七、核心设计模式汇总
- 十八、架构优势与设计原则
一、项目定位与业务职责
1.1 项目定位
Kubernetes(简称 K8s)是业界事实标准的容器编排平台,用于自动化部署、扩展和管理容器化应用。其核心价值在于:
- 声明式配置:用户描述"期望状态",系统自动驱动"实际状态"趋近期望
- 自愈能力:控制器持续 Reconcile,故障 Pod 自动重建、节点异常自动标记
- 水平扩展:基于指标自动伸缩应用副本数
- 服务发现与负载均衡:内置 DNS + Service + Endpoints 机制
- 滚动更新与回滚:Deployment 控制器管理应用版本的渐进式升级
1.2 业务职责矩阵
| 职责域 | 核心组件 | 关键能力 |
|---|---|---|
| 集群状态存储 | Etcd + API Server | 分布式一致性存储、RESTful CRUD、Watch 机制 |
| 工作负载编排 | Controller Manager + Kubelet | Deployment/StatefulSet/DaemonSet/Job 生命周期管理 |
| 调度决策 | Scheduler | 资源过滤、打分、亲和性、拓扑分布、抢占 |
| 网络代理 | kube-proxy + CNI | Service ClusterIP/NodePort/LoadBalancer、iptables/IPVS 规则 |
| 节点管理 | Kubelet | Pod 生命周期、容器运行时交互、卷挂载、健康探测 |
| 安全控制 | API Server Auth 模块 | 认证(Token/Cert/OAuth)、授权(RBAC/ABAC/Webhook)、准入控制 |
| 存储编排 | PV/PVC Controller + CSI | 动态供给、卷挂载/卸载、存储类管理 |
1.3 技术栈
- 编程语言:Go(全部核心组件均用 Go 实现)
- 持久化存储:Etcd v3(基于 Raft 的分布式 KV 存储,gRPC 协议)
- 容器运行时接口:CRI(Container Runtime Interface,支持 containerd、CRI-O 等)
- 网络接口:CNI(Container Network Interface,支持 Calico、Flannel、Cilium 等)
- 存储接口:CSI(Container Storage Interface,标准化存储插件协议)
- 通信协议:HTTP/REST(API Server 对外)、gRPC(Etcd 通信、CRI 通信)、Watch(长轮询/流式)
二、目录结构总览
基于源码实际目录的完整结构:
kubernetes/
├── api/ # OpenAPI / Swagger 规范定义
├── build/ # 构建系统
│ ├── build-image/ # 构建基础镜像
│ ├── server-image/ # 服务器镜像
│ └── pause/ # Pause 容器镜像(Pod 基础设施容器)
├── cluster/ # 集群部署与配置
│ ├── addons/ # 集群附加组件(DNS、Metrics、Storage)
│ ├── gce/ # GCP 平台特定配置
│ ├── kubemark/ # 虚拟集群框架(性能压测用)
│ └── skeleton/ # 集群骨架模板
├── cmd/ # ⭐ 命令行入口程序(核心组件可执行文件)
│ ├── kube-apiserver/ # API 服务器入口
│ ├── kube-controller-manager/ # 控制器管理器入口
│ ├── kube-scheduler/ # 调度器入口
│ ├── kubelet/ # 节点代理入口
│ ├── kube-proxy/ # 网络代理入口
│ ├── kubeadm/ # 集群引导工具入口
│ ├── kubectl/ # CLI 命令行工具入口
│ ├── kubectl-convert/ # kubectl 资源转换插件
│ ├── cloud-controller-manager/ # 云控制器管理器入口
│ └── kubemark/ # 性能压测代理入口
├── docs/ # 文档
├── hack/ # 构建/测试/发布脚本
├── logo/ # 项目 Logo
├── pkg/ # ⭐ 核心实现代码包
│ ├── apis/ # API 类型定义(含各子模块 admission/rbac/abac 等)
│ ├── controller/ # 控制器实现(~30+ 控制器)
│ ├── kubeapiserver/ # API Server 核心实现
│ ├── kubelet/ # Kubelet 核心实现(Pod 管理/容器运行时/卷管理等)
│ ├── scheduler/ # 调度器核心实现
│ ├── proxy/ # kube-proxy 实现(iptables/ipvs/userspace)
│ ├── volume/ # 存储卷管理(~30+ 卷插件)
│ ├── registry/ # REST Storage 注册表(各资源的 CRUD 实现)
│ ├── auth/ # 认证/授权实现
│ ├── client/ # 客户端库
│ ├── cloudprovider/ # 云平台集成接口
│ ├── controlplane/ # 控制平面辅助组件
│ ├── security/ # 安全上下文
│ ├── serviceaccount/ # ServiceAccount 管理
│ ├── features/ # Feature Gate 管理
│ └── util/ # 通用工具函数
├── plugin/ # 插件系统(admission 等)
├── staging/ # ⭐ 可独立版本化的组件(k8s.io 标准库)
│ └── src/k8s.io/
│ ├── apimachinery/ # API 机器库(meta/types/watch/codec)
│ ├── apiserver/ # 通用 API Server 框架
│ ├── client-go/ # 官方 Go 客户端库
│ ├── component-base/ # 组件基础库(metrics/healthz/cli)
│ ├── controller-manager/ # 控制器管理器共享代码
│ ├── kube-aggregator/ # API 聚合层
│ ├── apiextensions-apiserver/ # CRD API Server
│ ├── cri-api/ # 容器运行时接口定义
│ ├── metrics/ # 指标库
│ ├── code-generator/ # 代码生成器
│ ├── sample-controller/ # 示例控制器
│ └── ... (共 25+ 子仓库)
├── test/ # 测试代码(e2e/integration/benchmark)
├── third_party/ # 第三方依赖
└── vendor/ # Go 依赖库(dep/vendor 管理)
关键洞察:
cmd/是组件入口 :每个 Kubernetes 组件都有独立的cmd/子目录,入口文件统一为app/server.go,使用 Cobra 命令行框架pkg/是核心实现 :与cmd/一一对应,pkg/controller对应cmd/kube-controller-manager,pkg/kubelet对应cmd/kubeletstaging/是标准库 :将可复用的库独立版本化,通过k8s.io/前缀导入,如k8s.io/client-go、k8s.io/apimachinerypkg/registry/是 REST 层:每个 Kubernetes 资源(Pod/Service/Deployment 等)在 registry 中都有对应的 Storage 实现,负责 CRUD + Watch
三、整体架构图
Kubernetes 采用经典的主从架构(Master-Worker),控制平面与数据平面分离,组件间通过 API Server 进行松耦合通信。
#mermaid-svg-KQiC3NWtxkY7C07q{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-KQiC3NWtxkY7C07q .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-KQiC3NWtxkY7C07q .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-KQiC3NWtxkY7C07q .error-icon{fill:#552222;}#mermaid-svg-KQiC3NWtxkY7C07q .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-KQiC3NWtxkY7C07q .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-KQiC3NWtxkY7C07q .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-KQiC3NWtxkY7C07q .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-KQiC3NWtxkY7C07q .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-KQiC3NWtxkY7C07q .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-KQiC3NWtxkY7C07q .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-KQiC3NWtxkY7C07q .marker{fill:#333333;stroke:#333333;}#mermaid-svg-KQiC3NWtxkY7C07q .marker.cross{stroke:#333333;}#mermaid-svg-KQiC3NWtxkY7C07q svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-KQiC3NWtxkY7C07q p{margin:0;}#mermaid-svg-KQiC3NWtxkY7C07q .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-KQiC3NWtxkY7C07q .cluster-label text{fill:#333;}#mermaid-svg-KQiC3NWtxkY7C07q .cluster-label span{color:#333;}#mermaid-svg-KQiC3NWtxkY7C07q .cluster-label span p{background-color:transparent;}#mermaid-svg-KQiC3NWtxkY7C07q .label text,#mermaid-svg-KQiC3NWtxkY7C07q span{fill:#333;color:#333;}#mermaid-svg-KQiC3NWtxkY7C07q .node rect,#mermaid-svg-KQiC3NWtxkY7C07q .node circle,#mermaid-svg-KQiC3NWtxkY7C07q .node ellipse,#mermaid-svg-KQiC3NWtxkY7C07q .node polygon,#mermaid-svg-KQiC3NWtxkY7C07q .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-KQiC3NWtxkY7C07q .rough-node .label text,#mermaid-svg-KQiC3NWtxkY7C07q .node .label text,#mermaid-svg-KQiC3NWtxkY7C07q .image-shape .label,#mermaid-svg-KQiC3NWtxkY7C07q .icon-shape .label{text-anchor:middle;}#mermaid-svg-KQiC3NWtxkY7C07q .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-KQiC3NWtxkY7C07q .rough-node .label,#mermaid-svg-KQiC3NWtxkY7C07q .node .label,#mermaid-svg-KQiC3NWtxkY7C07q .image-shape .label,#mermaid-svg-KQiC3NWtxkY7C07q .icon-shape .label{text-align:center;}#mermaid-svg-KQiC3NWtxkY7C07q .node.clickable{cursor:pointer;}#mermaid-svg-KQiC3NWtxkY7C07q .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-KQiC3NWtxkY7C07q .arrowheadPath{fill:#333333;}#mermaid-svg-KQiC3NWtxkY7C07q .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-KQiC3NWtxkY7C07q .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-KQiC3NWtxkY7C07q .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-KQiC3NWtxkY7C07q .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-KQiC3NWtxkY7C07q .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-KQiC3NWtxkY7C07q .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-KQiC3NWtxkY7C07q .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-KQiC3NWtxkY7C07q .cluster text{fill:#333;}#mermaid-svg-KQiC3NWtxkY7C07q .cluster span{color:#333;}#mermaid-svg-KQiC3NWtxkY7C07q div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-KQiC3NWtxkY7C07q .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-KQiC3NWtxkY7C07q rect.text{fill:none;stroke-width:0;}#mermaid-svg-KQiC3NWtxkY7C07q .icon-shape,#mermaid-svg-KQiC3NWtxkY7C07q .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-KQiC3NWtxkY7C07q .icon-shape p,#mermaid-svg-KQiC3NWtxkY7C07q .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-KQiC3NWtxkY7C07q .icon-shape .label rect,#mermaid-svg-KQiC3NWtxkY7C07q .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-KQiC3NWtxkY7C07q .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-KQiC3NWtxkY7C07q .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-KQiC3NWtxkY7C07q :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 📦 数据平面 Data Plane
🧠 控制平面 Control Plane
工作节点 3
工作节点 2
工作节点 1
HTTP/REST
gRPC
Watch/List
Watch/List
Watch/List
Update/Status
Bind
Watch/List
Watch/List
Watch/List
iptables/IPVS
iptables/IPVS
iptables/IPVS
Pod 沙箱
Pod E
Pod 沙箱
Pod C
Pod D
Pod 沙箱
Pod A
Pod B
Cloud-Controller-Manager
Node Controller
Route Controller
Service Controller
Kube-Scheduler
调度阶段
Filter 过滤
Score 评分
Bind 绑定
调度队列
PriorityQueue
调度框架
SchedulingFramework
Kube-Controller-Manager
基础设施控制器
Node Lifecycle
Service / Endpoints
PV Controller
Garbage Collector
ServiceAccount
工作负载控制器
Deployment
ReplicaSet
DaemonSet
StatefulSet
Job / CronJob
Leader Election
Kube-APIServer
认证模块
Token/Cert/OAuth
授权模块
RBAC/ABAC/Webhook
准入控制
Mutating/Validating
Webhook
REST Storage
Registry 层
🖥️ 外部客户端
kubectl CLI
CI/CD Pipeline
Dashboard / Web UI
Helm / Kustomize
Etcd 集群
分布式 KV 存储
Raft 共识
Kubelet
CRI Runtime
containerd/CRI-O
CNI 插件
Calico/Flannel
kube-proxy
iptables/IPVS
Kubelet
CRI Runtime
CNI 插件
kube-proxy
Kubelet
CRI Runtime
CNI 插件
kube-proxy
架构说明
- 控制平面(Control Plane):集群的大脑,负责全局决策(调度、资源分配、状态同步)。核心三大组件:API Server、Controller Manager、Scheduler
- 数据平面(Data Plane):工作节点承载实际业务负载,Kubelet 管理 Pod 生命周期,kube-proxy 管理网络规则
- 通信模式:所有组件只与 API Server 通信(通过 HTTP/REST + Watch),绝不直接互相调用,实现完全解耦
- Etcd:唯一的状态存储后端,API Server 是唯一与 Etcd 直接交互的组件
四、组件交互图
展示各组件之间的通信协议、数据流向和交互模式:
#mermaid-svg-U00ScLXVT4NdSKAF{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-U00ScLXVT4NdSKAF .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-U00ScLXVT4NdSKAF .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-U00ScLXVT4NdSKAF .error-icon{fill:#552222;}#mermaid-svg-U00ScLXVT4NdSKAF .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-U00ScLXVT4NdSKAF .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-U00ScLXVT4NdSKAF .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-U00ScLXVT4NdSKAF .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-U00ScLXVT4NdSKAF .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-U00ScLXVT4NdSKAF .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-U00ScLXVT4NdSKAF .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-U00ScLXVT4NdSKAF .marker{fill:#333333;stroke:#333333;}#mermaid-svg-U00ScLXVT4NdSKAF .marker.cross{stroke:#333333;}#mermaid-svg-U00ScLXVT4NdSKAF svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-U00ScLXVT4NdSKAF p{margin:0;}#mermaid-svg-U00ScLXVT4NdSKAF .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-U00ScLXVT4NdSKAF .cluster-label text{fill:#333;}#mermaid-svg-U00ScLXVT4NdSKAF .cluster-label span{color:#333;}#mermaid-svg-U00ScLXVT4NdSKAF .cluster-label span p{background-color:transparent;}#mermaid-svg-U00ScLXVT4NdSKAF .label text,#mermaid-svg-U00ScLXVT4NdSKAF span{fill:#333;color:#333;}#mermaid-svg-U00ScLXVT4NdSKAF .node rect,#mermaid-svg-U00ScLXVT4NdSKAF .node circle,#mermaid-svg-U00ScLXVT4NdSKAF .node ellipse,#mermaid-svg-U00ScLXVT4NdSKAF .node polygon,#mermaid-svg-U00ScLXVT4NdSKAF .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-U00ScLXVT4NdSKAF .rough-node .label text,#mermaid-svg-U00ScLXVT4NdSKAF .node .label text,#mermaid-svg-U00ScLXVT4NdSKAF .image-shape .label,#mermaid-svg-U00ScLXVT4NdSKAF .icon-shape .label{text-anchor:middle;}#mermaid-svg-U00ScLXVT4NdSKAF .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-U00ScLXVT4NdSKAF .rough-node .label,#mermaid-svg-U00ScLXVT4NdSKAF .node .label,#mermaid-svg-U00ScLXVT4NdSKAF .image-shape .label,#mermaid-svg-U00ScLXVT4NdSKAF .icon-shape .label{text-align:center;}#mermaid-svg-U00ScLXVT4NdSKAF .node.clickable{cursor:pointer;}#mermaid-svg-U00ScLXVT4NdSKAF .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-U00ScLXVT4NdSKAF .arrowheadPath{fill:#333333;}#mermaid-svg-U00ScLXVT4NdSKAF .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-U00ScLXVT4NdSKAF .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-U00ScLXVT4NdSKAF .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-U00ScLXVT4NdSKAF .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-U00ScLXVT4NdSKAF .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-U00ScLXVT4NdSKAF .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-U00ScLXVT4NdSKAF .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-U00ScLXVT4NdSKAF .cluster text{fill:#333;}#mermaid-svg-U00ScLXVT4NdSKAF .cluster span{color:#333;}#mermaid-svg-U00ScLXVT4NdSKAF div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-U00ScLXVT4NdSKAF .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-U00ScLXVT4NdSKAF rect.text{fill:none;stroke-width:0;}#mermaid-svg-U00ScLXVT4NdSKAF .icon-shape,#mermaid-svg-U00ScLXVT4NdSKAF .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-U00ScLXVT4NdSKAF .icon-shape p,#mermaid-svg-U00ScLXVT4NdSKAF .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-U00ScLXVT4NdSKAF .icon-shape .label rect,#mermaid-svg-U00ScLXVT4NdSKAF .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-U00ScLXVT4NdSKAF .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-U00ScLXVT4NdSKAF .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-U00ScLXVT4NdSKAF :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} HTTP/HTTPS
REST API
HTTP/HTTPS
REST API
gRPC
读写/Lease
Watch 流
资源变更事件
Watch 流
新 Pod 事件
Watch 流
Pod 分配事件
Watch 流
Service/Endpoint
HTTP/REST
Update Status
Create 子资源
HTTP/REST
Bind Pod 到 Node
HTTP/REST
Pod/Node Status
上报心跳
HTTP/REST
刷新规则
gRPC / CRI
容器操作
CNI
网络配置
CSI gRPC
卷操作
Netlink
iptables/IPVS
通信协议
kubectl
Kube-APIServer
Dashboard
Etcd 集群
Controller
Manager
Scheduler
Kubelet
kube-proxy
容器运行时
containerd/CRI-O
CNI 插件
CSI 插件
Linux Kernel
Netfilter
交互说明
| 通信路径 | 协议 | 方向 | 用途 |
|---|---|---|---|
| kubectl → API Server | HTTP/REST | 单向请求 | 资源 CRUD 操作 |
| API Server → Etcd | gRPC | 双向 | 持久化存储读写 |
| API Server → Controller Manager | Watch (HTTP Long Poll / WebSocket) | 服务器推送 | 资源变更通知 |
| Controller Manager → API Server | HTTP/REST | 请求-响应 | 状态更新、子资源创建 |
| API Server → Scheduler | Watch | 服务器推送 | 未调度 Pod 通知 |
| Scheduler → API Server | HTTP/REST | 请求-响应 | Pod 绑定(Bind) |
| API Server → Kubelet | Watch | 服务器推送 | 分配到本节点的 Pod 通知 |
| Kubelet → API Server | HTTP/REST | 请求-响应 | 状态上报、心跳 |
| Kubelet → CRI Runtime | gRPC | 双向 | 容器创建/停止/查询 |
| Kubelet → CNI | Exec + JSON | 单向调用 | Pod 网络配置 |
| kube-proxy → Kernel | Netlink/iptables | 系统调用 | 网络规则注入 |
关键原则:所有组件之间的交互必须经过 API Server,不存在组件间的直接调用。这种"中心化通信总线"设计使得:
- 任何组件故障不影响其他组件的通信
- API Server 成为唯一的安全策略执行点
- 组件可独立升级和替换
五、数据流图
以 Pod 创建为例,展示完整的端到端数据流:
CSI 插件 CNI 插件 CRI Runtime Kubelet (目标节点) Controller Manager Kube-Scheduler Etcd Kube-APIServer 用户 / kubectl CSI 插件 CNI 插件 CRI Runtime Kubelet (目标节点) Controller Manager Kube-Scheduler Etcd Kube-APIServer 用户 / kubectl #mermaid-svg-QItMbDXbVj2Z0MFL{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-QItMbDXbVj2Z0MFL .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-QItMbDXbVj2Z0MFL .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-QItMbDXbVj2Z0MFL .error-icon{fill:#552222;}#mermaid-svg-QItMbDXbVj2Z0MFL .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-QItMbDXbVj2Z0MFL .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-QItMbDXbVj2Z0MFL .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-QItMbDXbVj2Z0MFL .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-QItMbDXbVj2Z0MFL .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-QItMbDXbVj2Z0MFL .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-QItMbDXbVj2Z0MFL .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-QItMbDXbVj2Z0MFL .marker{fill:#333333;stroke:#333333;}#mermaid-svg-QItMbDXbVj2Z0MFL .marker.cross{stroke:#333333;}#mermaid-svg-QItMbDXbVj2Z0MFL svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-QItMbDXbVj2Z0MFL p{margin:0;}#mermaid-svg-QItMbDXbVj2Z0MFL .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-QItMbDXbVj2Z0MFL text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-QItMbDXbVj2Z0MFL .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-QItMbDXbVj2Z0MFL .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-QItMbDXbVj2Z0MFL .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-QItMbDXbVj2Z0MFL .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-QItMbDXbVj2Z0MFL #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-QItMbDXbVj2Z0MFL .sequenceNumber{fill:white;}#mermaid-svg-QItMbDXbVj2Z0MFL #sequencenumber{fill:#333;}#mermaid-svg-QItMbDXbVj2Z0MFL #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-QItMbDXbVj2Z0MFL .messageText{fill:#333;stroke:none;}#mermaid-svg-QItMbDXbVj2Z0MFL .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-QItMbDXbVj2Z0MFL .labelText,#mermaid-svg-QItMbDXbVj2Z0MFL .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-QItMbDXbVj2Z0MFL .loopText,#mermaid-svg-QItMbDXbVj2Z0MFL .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-QItMbDXbVj2Z0MFL .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-QItMbDXbVj2Z0MFL .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-QItMbDXbVj2Z0MFL .noteText,#mermaid-svg-QItMbDXbVj2Z0MFL .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-QItMbDXbVj2Z0MFL .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-QItMbDXbVj2Z0MFL .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-QItMbDXbVj2Z0MFL .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-QItMbDXbVj2Z0MFL .actorPopupMenu{position:absolute;}#mermaid-svg-QItMbDXbVj2Z0MFL .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-QItMbDXbVj2Z0MFL .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-QItMbDXbVj2Z0MFL .actor-man circle,#mermaid-svg-QItMbDXbVj2Z0MFL line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-QItMbDXbVj2Z0MFL :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 1️⃣ 认证阶段 2️⃣ 授权阶段 3️⃣ 准入控制阶段 4️⃣ 持久化阶段 5️⃣ 调度阶段 6️⃣ 执行阶段 7️⃣ 状态上报 8️⃣ 控制器协调(如 ReplicaSet) POST /api/v1/namespaces/default/pods {PodSpec JSON} Authentication 验证 Bearer Token / Client Cert Authorization RBAC 规则匹配 Mutating Webhooks (修改 PodSpec) Validating Webhooks (校验约束) Built-in Admission (LimitRanger/ResourceQuota等) Put /registry/pods/default/my-pod 存储 Pod 对象 写入成功 + Revision 201 Created {Pod 对象 + UID} Watch Pod (spec.nodeName == "") Pod 变更事件 (Added) Filter 阶段 排除不满足条件的节点 Score 阶段 对候选节点打分排序 POST /api/v1/namespaces/default/pods/my-pod/binding {nodeName: "node-2"} Update Pod.spec.nodeName = "node-2" Watch Pod (spec.nodeName == "node-2") Pod 变更事件 (Modified) 设置 Pod 网络(分配 IP、路由) 网络配置完成 挂载 Volume(如有 PVC) 卷挂载完成 RunPodSandbox(创建 Pause 容器) Sandbox ID CreateContainer(创建业务容器) Container ID StartContainer(启动容器) 启动成功 Update Pod.Status {phase: Running, conditions: Ready} 存储更新后的 Pod 状态 Watch ReplicaSet / Pod 资源变更事件 Reconcile: 期望副本数 vs 实际副本数 如果副本不足,创建新 Pod
数据流关键节点说明
- 认证→授权→准入:API Server 内部的三阶段安全处理链,任何请求都必须通过这三关
- Etcd 写入:是数据持久化的唯一路径,写入成功后才返回给用户
- Watch 传播:通过 Etcd Watch → API Server Watch → 组件 Watch 的三级 Watch 链路,变更事件高效推送到各组件
- 调度决策:Scheduler 是无状态的,通过 Watch 获取未调度 Pod,经过 Filter→Score→Bind 三阶段
- Kubelet 执行:严格按 CNI→CSI→CRI 顺序,先配网络、再挂卷、最后创建容器
- 状态闭环:Kubelet 持续上报状态,Controller Manager 持续 Reconcile,形成闭环
六、请求处理链路图
展示 API Server 内部处理一个 REST 请求的完整链路:
#mermaid-svg-U22dmqPVs1eg7LL3{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-U22dmqPVs1eg7LL3 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-U22dmqPVs1eg7LL3 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-U22dmqPVs1eg7LL3 .error-icon{fill:#552222;}#mermaid-svg-U22dmqPVs1eg7LL3 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-U22dmqPVs1eg7LL3 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-U22dmqPVs1eg7LL3 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-U22dmqPVs1eg7LL3 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-U22dmqPVs1eg7LL3 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-U22dmqPVs1eg7LL3 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-U22dmqPVs1eg7LL3 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-U22dmqPVs1eg7LL3 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-U22dmqPVs1eg7LL3 .marker.cross{stroke:#333333;}#mermaid-svg-U22dmqPVs1eg7LL3 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-U22dmqPVs1eg7LL3 p{margin:0;}#mermaid-svg-U22dmqPVs1eg7LL3 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-U22dmqPVs1eg7LL3 .cluster-label text{fill:#333;}#mermaid-svg-U22dmqPVs1eg7LL3 .cluster-label span{color:#333;}#mermaid-svg-U22dmqPVs1eg7LL3 .cluster-label span p{background-color:transparent;}#mermaid-svg-U22dmqPVs1eg7LL3 .label text,#mermaid-svg-U22dmqPVs1eg7LL3 span{fill:#333;color:#333;}#mermaid-svg-U22dmqPVs1eg7LL3 .node rect,#mermaid-svg-U22dmqPVs1eg7LL3 .node circle,#mermaid-svg-U22dmqPVs1eg7LL3 .node ellipse,#mermaid-svg-U22dmqPVs1eg7LL3 .node polygon,#mermaid-svg-U22dmqPVs1eg7LL3 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-U22dmqPVs1eg7LL3 .rough-node .label text,#mermaid-svg-U22dmqPVs1eg7LL3 .node .label text,#mermaid-svg-U22dmqPVs1eg7LL3 .image-shape .label,#mermaid-svg-U22dmqPVs1eg7LL3 .icon-shape .label{text-anchor:middle;}#mermaid-svg-U22dmqPVs1eg7LL3 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-U22dmqPVs1eg7LL3 .rough-node .label,#mermaid-svg-U22dmqPVs1eg7LL3 .node .label,#mermaid-svg-U22dmqPVs1eg7LL3 .image-shape .label,#mermaid-svg-U22dmqPVs1eg7LL3 .icon-shape .label{text-align:center;}#mermaid-svg-U22dmqPVs1eg7LL3 .node.clickable{cursor:pointer;}#mermaid-svg-U22dmqPVs1eg7LL3 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-U22dmqPVs1eg7LL3 .arrowheadPath{fill:#333333;}#mermaid-svg-U22dmqPVs1eg7LL3 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-U22dmqPVs1eg7LL3 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-U22dmqPVs1eg7LL3 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-U22dmqPVs1eg7LL3 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-U22dmqPVs1eg7LL3 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-U22dmqPVs1eg7LL3 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-U22dmqPVs1eg7LL3 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-U22dmqPVs1eg7LL3 .cluster text{fill:#333;}#mermaid-svg-U22dmqPVs1eg7LL3 .cluster span{color:#333;}#mermaid-svg-U22dmqPVs1eg7LL3 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-U22dmqPVs1eg7LL3 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-U22dmqPVs1eg7LL3 rect.text{fill:none;stroke-width:0;}#mermaid-svg-U22dmqPVs1eg7LL3 .icon-shape,#mermaid-svg-U22dmqPVs1eg7LL3 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-U22dmqPVs1eg7LL3 .icon-shape p,#mermaid-svg-U22dmqPVs1eg7LL3 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-U22dmqPVs1eg7LL3 .icon-shape .label rect,#mermaid-svg-U22dmqPVs1eg7LL3 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-U22dmqPVs1eg7LL3 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-U22dmqPVs1eg7LL3 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-U22dmqPVs1eg7LL3 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Kube-APIServer 请求处理链
5. REST Storage 存储层
- Handler Chain 过滤器链
gRPC Put
Etcd 集群
Raft Log
Replication
Raft Log
Replication
Raft Log
Replication
Member 1
Leader
Member 2
Follower
Member 3
Follower
4. Admission Control 准入控制
Validating 阶段
(校验请求)
ResourceQuota
配额检查
PodSecurity
安全标准
ValidatingAdmission
Webhook
Mutating 阶段
(修改请求)
NamespaceLifecycle
命名空间生命周期
LimitRanger
默认资源限制
ServiceAccount
自动注入 Token
DefaultToleration
默认容忍度
MutatingAdmission
Webhook
3. Authorization 授权
Node Authorizer
Kubelet 权限
RBAC
角色绑定规则
ABAC
属性访问控制
Webhook AuthZ
外部授权
AlwaysAllow/Deny
调试用
2. Authentication 认证
Token Review
ServiceAccount Token
X509 Client Cert
双向 TLS
OAuth Proxy
OIDC 集成
Webhook Auth
外部认证服务
Anonymous
匿名访问(可禁用)
客户端请求
POST /api/v1/namespaces/ns/pods
RequestHeader
过滤器
(清洗请求头)
RequestInfo
解析器
(提取资源/动词/命名空间)
Impersonation
代理检查
(禁止非法模拟用户)
MaxInFlight
限流器
(APF FlowControl)
Registry 路由
(资源→Storage 映射)
Strategy
(创建/更新策略)
Codec
(JSON/Protobuf 编解码)
Etcd Store
(gRPC 读写)
请求处理链说明
源码对应关系:
| 阶段 | 源码位置 | 核心逻辑 |
|---|---|---|
| Handler Chain | staging/src/k8s.io/apiserver/pkg/endpoints/filters/ |
请求预处理、限流 |
| Authentication | pkg/kubeapiserver/authenticator/ |
Token/Cert/Webhook 认证 |
| Authorization | pkg/auth/authorizer/ + pkg/auth/abac/rbac/ |
RBAC/ABAC/Webhook 授权 |
| Admission (Mutating) | staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/mutating/ |
修改请求对象 |
| Admission (Validating) | staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/validating/ |
校验请求合法性 |
| REST Storage | pkg/registry/core/pod/storage.go 等 |
资源 CRUD + Watch |
| Etcd Client | staging/src/k8s.io/apiserver/pkg/storage/etcd3/ |
gRPC 调用 Etcd |
准入控制的双阶段设计:
- Mutating 先执行:允许 Webhook 修改对象(如注入 Sidecar、设置默认值),修改后的对象进入 Validating
- Validating 后执行:在对象最终形态上做校验(如配额检查、安全策略),只读不修改
- 内置插件在 Webhook 之前/之后:部分内置 Admission Plugin 在 Webhook 之前运行(如 NamespaceLifecycle),确保基础约束先被检查
七、Etcd 存储架构图
#mermaid-svg-yDOe0PWgJ0DATkoU{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-yDOe0PWgJ0DATkoU .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-yDOe0PWgJ0DATkoU .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-yDOe0PWgJ0DATkoU .error-icon{fill:#552222;}#mermaid-svg-yDOe0PWgJ0DATkoU .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-yDOe0PWgJ0DATkoU .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-yDOe0PWgJ0DATkoU .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-yDOe0PWgJ0DATkoU .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-yDOe0PWgJ0DATkoU .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-yDOe0PWgJ0DATkoU .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-yDOe0PWgJ0DATkoU .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-yDOe0PWgJ0DATkoU .marker{fill:#333333;stroke:#333333;}#mermaid-svg-yDOe0PWgJ0DATkoU .marker.cross{stroke:#333333;}#mermaid-svg-yDOe0PWgJ0DATkoU svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-yDOe0PWgJ0DATkoU p{margin:0;}#mermaid-svg-yDOe0PWgJ0DATkoU .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-yDOe0PWgJ0DATkoU .cluster-label text{fill:#333;}#mermaid-svg-yDOe0PWgJ0DATkoU .cluster-label span{color:#333;}#mermaid-svg-yDOe0PWgJ0DATkoU .cluster-label span p{background-color:transparent;}#mermaid-svg-yDOe0PWgJ0DATkoU .label text,#mermaid-svg-yDOe0PWgJ0DATkoU span{fill:#333;color:#333;}#mermaid-svg-yDOe0PWgJ0DATkoU .node rect,#mermaid-svg-yDOe0PWgJ0DATkoU .node circle,#mermaid-svg-yDOe0PWgJ0DATkoU .node ellipse,#mermaid-svg-yDOe0PWgJ0DATkoU .node polygon,#mermaid-svg-yDOe0PWgJ0DATkoU .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-yDOe0PWgJ0DATkoU .rough-node .label text,#mermaid-svg-yDOe0PWgJ0DATkoU .node .label text,#mermaid-svg-yDOe0PWgJ0DATkoU .image-shape .label,#mermaid-svg-yDOe0PWgJ0DATkoU .icon-shape .label{text-anchor:middle;}#mermaid-svg-yDOe0PWgJ0DATkoU .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-yDOe0PWgJ0DATkoU .rough-node .label,#mermaid-svg-yDOe0PWgJ0DATkoU .node .label,#mermaid-svg-yDOe0PWgJ0DATkoU .image-shape .label,#mermaid-svg-yDOe0PWgJ0DATkoU .icon-shape .label{text-align:center;}#mermaid-svg-yDOe0PWgJ0DATkoU .node.clickable{cursor:pointer;}#mermaid-svg-yDOe0PWgJ0DATkoU .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-yDOe0PWgJ0DATkoU .arrowheadPath{fill:#333333;}#mermaid-svg-yDOe0PWgJ0DATkoU .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-yDOe0PWgJ0DATkoU .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-yDOe0PWgJ0DATkoU .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-yDOe0PWgJ0DATkoU .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-yDOe0PWgJ0DATkoU .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-yDOe0PWgJ0DATkoU .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-yDOe0PWgJ0DATkoU .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-yDOe0PWgJ0DATkoU .cluster text{fill:#333;}#mermaid-svg-yDOe0PWgJ0DATkoU .cluster span{color:#333;}#mermaid-svg-yDOe0PWgJ0DATkoU div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-yDOe0PWgJ0DATkoU .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-yDOe0PWgJ0DATkoU rect.text{fill:none;stroke-width:0;}#mermaid-svg-yDOe0PWgJ0DATkoU .icon-shape,#mermaid-svg-yDOe0PWgJ0DATkoU .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-yDOe0PWgJ0DATkoU .icon-shape p,#mermaid-svg-yDOe0PWgJ0DATkoU .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-yDOe0PWgJ0DATkoU .icon-shape .label rect,#mermaid-svg-yDOe0PWgJ0DATkoU .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-yDOe0PWgJ0DATkoU .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-yDOe0PWgJ0DATkoU .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-yDOe0PWgJ0DATkoU :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Etcd v3 集群
API Server 存储抽象层
Leader 成员
gRPC
Raft Append
Raft Replicate
Raft Replicate
Etcd Key 布局
/registry/pods/default/nginx-pod
/registry/services/default/nginx-svc
/registry/deployments/default/nginx-deploy
/registry/rbac/roles/default/admin
/registry/leases/kube-node-worker1
Follower 2
KV Store 副本
Follower 1
KV Store 副本
Storage 接口
Create()
Get()
List()
Watch()
Update()
Delete()
Registry 路由层
/registry/pods//
/registry/services//
/registry/deployments//
/registry/nodes/
/registry/configmaps//
/registry/secrets//
/registry/persistentvolumes/
/registry/apiextensions.k8s.io/
KV Store
BoltDB 后端
全局单调递增 Revision
Lease Manager
TTL 管理
Compactor
历史压缩
Raft WAL Log
预写日志
Snapshot
定期快照
Etcd 存储架构说明
Key 前缀设计 (源码:pkg/registry/):
| 资源类型 | Key 前缀 | 示例 |
|---|---|---|
| Pod | /registry/pods/ |
/registry/pods/default/nginx-7f8b5 |
| Service | /registry/services/ |
/registry/services/default/nginx-svc |
| Deployment | /registry/deployments/ |
/registry/deployments/default/nginx-deploy |
| Node | /registry/nodes/ |
/registry/nodes/worker-1 |
| ConfigMap | /registry/configmaps/ |
/registry/configmaps/default/app-config |
| Secret | /registry/secrets/ |
/registry/secrets/default/db-password |
| PV | /registry/persistentvolumes/ |
/registry/persistentvolumes/pv-001 |
| RBAC Role | /registry/rbac/roles/ |
/registry/rbac/roles/default/admin |
| Lease | /registry/leases/ |
/registry/leases/kube-node-worker1 |
| CRD | /registry/apiextensions.k8s.io/ |
/registry/apiextensions.k8s.io/customresources |
核心机制:
- Revision 机制:Etcd 维护全局单调递增的 Revision,每次写操作 Revision+1,Watch 基于 Revision 实现增量推送
- Lease 机制:Kubelet 心跳、Leader Election 均基于 Lease,Lease 到期自动删除关联 Key
- Compaction:定期压缩历史 Revision,释放存储空间,但保留最近 N 个 Revision 供 Watch 回放
- Quorum 写入:写入需经多数成员(≥2/3)确认才算成功,保证强一致性
- Storage 接口抽象 :API Server 通过
storage.Interface抽象层访问 Etcd,理论上可替换为其他后端(实际均用 Etcd)
八、认证授权链路图
Etcd REST Storage Admission 准入控制 Authorization 授权模块 Authentication 认证模块 API Server Handler Chain 客户端 (kubectl / Pod / Dashboard) Etcd REST Storage Admission 准入控制 Authorization 授权模块 Authentication 认证模块 API Server Handler Chain 客户端 (kubectl / Pod / Dashboard) #mermaid-svg-vhxvqwZEGTxUXOVq{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-vhxvqwZEGTxUXOVq .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-vhxvqwZEGTxUXOVq .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-vhxvqwZEGTxUXOVq .error-icon{fill:#552222;}#mermaid-svg-vhxvqwZEGTxUXOVq .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-vhxvqwZEGTxUXOVq .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-vhxvqwZEGTxUXOVq .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-vhxvqwZEGTxUXOVq .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-vhxvqwZEGTxUXOVq .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-vhxvqwZEGTxUXOVq .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-vhxvqwZEGTxUXOVq .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-vhxvqwZEGTxUXOVq .marker{fill:#333333;stroke:#333333;}#mermaid-svg-vhxvqwZEGTxUXOVq .marker.cross{stroke:#333333;}#mermaid-svg-vhxvqwZEGTxUXOVq svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-vhxvqwZEGTxUXOVq p{margin:0;}#mermaid-svg-vhxvqwZEGTxUXOVq .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-vhxvqwZEGTxUXOVq text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-vhxvqwZEGTxUXOVq .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-vhxvqwZEGTxUXOVq .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-vhxvqwZEGTxUXOVq .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-vhxvqwZEGTxUXOVq .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-vhxvqwZEGTxUXOVq #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-vhxvqwZEGTxUXOVq .sequenceNumber{fill:white;}#mermaid-svg-vhxvqwZEGTxUXOVq #sequencenumber{fill:#333;}#mermaid-svg-vhxvqwZEGTxUXOVq #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-vhxvqwZEGTxUXOVq .messageText{fill:#333;stroke:none;}#mermaid-svg-vhxvqwZEGTxUXOVq .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-vhxvqwZEGTxUXOVq .labelText,#mermaid-svg-vhxvqwZEGTxUXOVq .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-vhxvqwZEGTxUXOVq .loopText,#mermaid-svg-vhxvqwZEGTxUXOVq .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-vhxvqwZEGTxUXOVq .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-vhxvqwZEGTxUXOVq .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-vhxvqwZEGTxUXOVq .noteText,#mermaid-svg-vhxvqwZEGTxUXOVq .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-vhxvqwZEGTxUXOVq .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-vhxvqwZEGTxUXOVq .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-vhxvqwZEGTxUXOVq .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-vhxvqwZEGTxUXOVq .actorPopupMenu{position:absolute;}#mermaid-svg-vhxvqwZEGTxUXOVq .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-vhxvqwZEGTxUXOVq .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-vhxvqwZEGTxUXOVq .actor-man circle,#mermaid-svg-vhxvqwZEGTxUXOVq line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-vhxvqwZEGTxUXOVq :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 认证阶段 (Authentication) alt Bearer Token X509 Client Certificate Webhook Authentication Anonymous alt 认证成功 认证失败 授权阶段 (Authorization) alt Node Authorizer RBAC ABAC Webhook Authorization alt 授权允许 授权拒绝 准入控制阶段 (Admission Control) loop Mutating Phase (按优先级) loop Validating Phase (按优先级) alt 准入通过 准入拒绝 HTTPS 请求 携带认证凭证 提取凭证 Token / Cert / Basic Auth TokenReview 验证 ServiceAccount JWT 验证证书签名 + CN/O 提取 调用外部认证服务 TokenReview Webhook 匿名用户 system:anonymous User.Info{ Name: "alice", Groups: "system:authenticated" } 401 Unauthorized 401 Unauthorized AuthorizeRequest (User, Verb, Resource, Namespace) Kubelet 专用授权 NodeRestriction RoleBinding 查找 Role → PolicyRule 匹配 策略文件匹配 属性规则检查 SubjectAccessReview 外部授权服务 Decision: Allow Decision: Deny 403 Forbidden 运行 Admission Plugins NamespaceLifecycle DefaultTolerationSeconds LimitRanger ServiceAccount MutatingAdmissionWebhook ResourceQuota PodSecurity ValidatingAdmissionWebhook Allow Reject (原因) 403 Forbidden (原因) 操作请求 持久化 结果 响应对象 200 OK / 201 Created
认证授权源码结构
| 模块 | 源码位置 | 核心文件 |
|---|---|---|
| Authentication | pkg/kubeapiserver/authenticator/ |
config.go - 认证配置构建 |
| Token 认证 | staging/src/k8s.io/apiserver/pkg/authentication/request/bearertoken/ |
JWT Token 验证 |
| 证书认证 | staging/src/k8s.io/apiserver/pkg/authentication/request/x509/ |
CN/O 提取 |
| Webhook 认证 | staging/src/k8s.io/apiserver/pkg/authentication/request/webhook/ |
外部 TokenReview |
| RBAC 授权 | pkg/auth/authorizer/rbac/ |
Role/RoleBinding 匹配 |
| Node 授权 | pkg/auth/authorizer/node/ |
Kubelet 权限限制 |
| ABAC 授权 | pkg/auth/abac/ |
策略文件解析 |
| Admission 插件 | pkg/apis/admission/ + staging/src/k8s.io/apiserver/pkg/admission/ |
插件注册与链式调用 |
九、控制器协同图
Kubernetes 控制器管理器内运行 ~30+ 控制器,它们通过 Informer 共享缓存和 Watch 机制协同工作:
#mermaid-svg-XTFviAOLKHzQ2WWX{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-XTFviAOLKHzQ2WWX .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-XTFviAOLKHzQ2WWX .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-XTFviAOLKHzQ2WWX .error-icon{fill:#552222;}#mermaid-svg-XTFviAOLKHzQ2WWX .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-XTFviAOLKHzQ2WWX .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-XTFviAOLKHzQ2WWX .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-XTFviAOLKHzQ2WWX .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-XTFviAOLKHzQ2WWX .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-XTFviAOLKHzQ2WWX .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-XTFviAOLKHzQ2WWX .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-XTFviAOLKHzQ2WWX .marker{fill:#333333;stroke:#333333;}#mermaid-svg-XTFviAOLKHzQ2WWX .marker.cross{stroke:#333333;}#mermaid-svg-XTFviAOLKHzQ2WWX svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-XTFviAOLKHzQ2WWX p{margin:0;}#mermaid-svg-XTFviAOLKHzQ2WWX .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-XTFviAOLKHzQ2WWX .cluster-label text{fill:#333;}#mermaid-svg-XTFviAOLKHzQ2WWX .cluster-label span{color:#333;}#mermaid-svg-XTFviAOLKHzQ2WWX .cluster-label span p{background-color:transparent;}#mermaid-svg-XTFviAOLKHzQ2WWX .label text,#mermaid-svg-XTFviAOLKHzQ2WWX span{fill:#333;color:#333;}#mermaid-svg-XTFviAOLKHzQ2WWX .node rect,#mermaid-svg-XTFviAOLKHzQ2WWX .node circle,#mermaid-svg-XTFviAOLKHzQ2WWX .node ellipse,#mermaid-svg-XTFviAOLKHzQ2WWX .node polygon,#mermaid-svg-XTFviAOLKHzQ2WWX .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-XTFviAOLKHzQ2WWX .rough-node .label text,#mermaid-svg-XTFviAOLKHzQ2WWX .node .label text,#mermaid-svg-XTFviAOLKHzQ2WWX .image-shape .label,#mermaid-svg-XTFviAOLKHzQ2WWX .icon-shape .label{text-anchor:middle;}#mermaid-svg-XTFviAOLKHzQ2WWX .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-XTFviAOLKHzQ2WWX .rough-node .label,#mermaid-svg-XTFviAOLKHzQ2WWX .node .label,#mermaid-svg-XTFviAOLKHzQ2WWX .image-shape .label,#mermaid-svg-XTFviAOLKHzQ2WWX .icon-shape .label{text-align:center;}#mermaid-svg-XTFviAOLKHzQ2WWX .node.clickable{cursor:pointer;}#mermaid-svg-XTFviAOLKHzQ2WWX .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-XTFviAOLKHzQ2WWX .arrowheadPath{fill:#333333;}#mermaid-svg-XTFviAOLKHzQ2WWX .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-XTFviAOLKHzQ2WWX .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-XTFviAOLKHzQ2WWX .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-XTFviAOLKHzQ2WWX .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-XTFviAOLKHzQ2WWX .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-XTFviAOLKHzQ2WWX .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-XTFviAOLKHzQ2WWX .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-XTFviAOLKHzQ2WWX .cluster text{fill:#333;}#mermaid-svg-XTFviAOLKHzQ2WWX .cluster span{color:#333;}#mermaid-svg-XTFviAOLKHzQ2WWX div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-XTFviAOLKHzQ2WWX .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-XTFviAOLKHzQ2WWX rect.text{fill:none;stroke-width:0;}#mermaid-svg-XTFviAOLKHzQ2WWX .icon-shape,#mermaid-svg-XTFviAOLKHzQ2WWX .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-XTFviAOLKHzQ2WWX .icon-shape p,#mermaid-svg-XTFviAOLKHzQ2WWX .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-XTFviAOLKHzQ2WWX .icon-shape .label rect,#mermaid-svg-XTFviAOLKHzQ2WWX .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-XTFviAOLKHzQ2WWX .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-XTFviAOLKHzQ2WWX .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-XTFviAOLKHzQ2WWX :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Work Queues
(RateLimitingInterface)
控制器群
SharedInformerFactory
共享 Informer 工厂
Kube-APIServer
存储控制器
基础设施控制器
工作负载控制器
OnAdd/OnUpdate/OnDelete
创建/更新 ReplicaSet
创建/删除 Pod
创建/更新 EndpointSlice
更新 Node 状态
更新 PV/PVC 状态
Watch
策略控制器
ResourceQuota Controller
Garbage Collector
Disruption Controller
HPA Controller
REST API
Shared Cache
(本地内存缓存)
Pod Informer
ReplicaSet Informer
Deployment Informer
Service Informer
Node Informer
EndpointSlice Informer
PV Informer
PVC Informer
Deployment Controller
ReplicaSet Controller
DaemonSet Controller
StatefulSet Controller
Job Controller
CronJob Controller
EndpointSlice Controller
Service Controller
Node Lifecycle Controller
Node IPAM Controller
ServiceAccount Controller
PV Controller
PVC Controller
Attach/Detach Controller
Volume Expand Controller
Deployment Queue
ReplicaSet Queue
Pod Queue
EndpointSlice Queue
Node Queue
控制器协同关系详解
源码位置 :pkg/controller/ 各子目录 + cmd/kube-controller-manager/app/controllers.go
关键协同链路:
-
Deployment → ReplicaSet → Pod 链:
- 用户创建 Deployment → Deployment Controller Watch 到事件 → 创建 ReplicaSet
- ReplicaSet Controller Watch 到新 ReplicaSet → 根据
.spec.replicas创建/删除 Pod - 这形成了一条级联创建链:Deployment → ReplicaSet → Pod
-
Service → EndpointSlice → kube-proxy 链:
- 用户创建 Service → EndpointSlice Controller Watch 到事件
- Controller 根据 Service Selector 匹配 Pod → 创建 EndpointSlice
- kube-proxy Watch EndpointSlice → 更新 iptables/IPVS 规则
-
PVC → PV → Volume 链:
- 用户创建 PVC → PV Controller Watch 到事件
- Controller 匹配可用 PV 或触发动态供给 → 绑定 PVC 与 PV
- Kubelet 的 Volume Manager 挂载卷到 Pod
-
控制器间的资源依赖:
- Namespace Controller 在删除 Namespace 时,通知 Garbage Collector 级联删除该 Namespace 下所有资源
- Node Lifecycle Controller 标记 NotReady 节点后,Pod GC Controller 清理该节点上的 Terminating Pod
SharedInformerFactory 设计:
- 所有控制器共享同一套 Informer,避免重复 Watch API Server
- 本地缓存(Cache)避免频繁 List 调用,降低 API Server 负载
- 事件处理器仅将 Key 入队,不做复杂逻辑,保证事件处理吞吐量
十、调度框架与流程图
10.1 调度框架架构
源码位置:pkg/scheduler/framework/
#mermaid-svg-LsfvjhprBJvOFoxf{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-LsfvjhprBJvOFoxf .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-LsfvjhprBJvOFoxf .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-LsfvjhprBJvOFoxf .error-icon{fill:#552222;}#mermaid-svg-LsfvjhprBJvOFoxf .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-LsfvjhprBJvOFoxf .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-LsfvjhprBJvOFoxf .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-LsfvjhprBJvOFoxf .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-LsfvjhprBJvOFoxf .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-LsfvjhprBJvOFoxf .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-LsfvjhprBJvOFoxf .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-LsfvjhprBJvOFoxf .marker{fill:#333333;stroke:#333333;}#mermaid-svg-LsfvjhprBJvOFoxf .marker.cross{stroke:#333333;}#mermaid-svg-LsfvjhprBJvOFoxf svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-LsfvjhprBJvOFoxf p{margin:0;}#mermaid-svg-LsfvjhprBJvOFoxf .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-LsfvjhprBJvOFoxf .cluster-label text{fill:#333;}#mermaid-svg-LsfvjhprBJvOFoxf .cluster-label span{color:#333;}#mermaid-svg-LsfvjhprBJvOFoxf .cluster-label span p{background-color:transparent;}#mermaid-svg-LsfvjhprBJvOFoxf .label text,#mermaid-svg-LsfvjhprBJvOFoxf span{fill:#333;color:#333;}#mermaid-svg-LsfvjhprBJvOFoxf .node rect,#mermaid-svg-LsfvjhprBJvOFoxf .node circle,#mermaid-svg-LsfvjhprBJvOFoxf .node ellipse,#mermaid-svg-LsfvjhprBJvOFoxf .node polygon,#mermaid-svg-LsfvjhprBJvOFoxf .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-LsfvjhprBJvOFoxf .rough-node .label text,#mermaid-svg-LsfvjhprBJvOFoxf .node .label text,#mermaid-svg-LsfvjhprBJvOFoxf .image-shape .label,#mermaid-svg-LsfvjhprBJvOFoxf .icon-shape .label{text-anchor:middle;}#mermaid-svg-LsfvjhprBJvOFoxf .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-LsfvjhprBJvOFoxf .rough-node .label,#mermaid-svg-LsfvjhprBJvOFoxf .node .label,#mermaid-svg-LsfvjhprBJvOFoxf .image-shape .label,#mermaid-svg-LsfvjhprBJvOFoxf .icon-shape .label{text-align:center;}#mermaid-svg-LsfvjhprBJvOFoxf .node.clickable{cursor:pointer;}#mermaid-svg-LsfvjhprBJvOFoxf .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-LsfvjhprBJvOFoxf .arrowheadPath{fill:#333333;}#mermaid-svg-LsfvjhprBJvOFoxf .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-LsfvjhprBJvOFoxf .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-LsfvjhprBJvOFoxf .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-LsfvjhprBJvOFoxf .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-LsfvjhprBJvOFoxf .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-LsfvjhprBJvOFoxf .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-LsfvjhprBJvOFoxf .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-LsfvjhprBJvOFoxf .cluster text{fill:#333;}#mermaid-svg-LsfvjhprBJvOFoxf .cluster span{color:#333;}#mermaid-svg-LsfvjhprBJvOFoxf div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-LsfvjhprBJvOFoxf .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-LsfvjhprBJvOFoxf rect.text{fill:none;stroke-width:0;}#mermaid-svg-LsfvjhprBJvOFoxf .icon-shape,#mermaid-svg-LsfvjhprBJvOFoxf .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-LsfvjhprBJvOFoxf .icon-shape p,#mermaid-svg-LsfvjhprBJvOFoxf .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-LsfvjhprBJvOFoxf .icon-shape .label rect,#mermaid-svg-LsfvjhprBJvOFoxf .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-LsfvjhprBJvOFoxf .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-LsfvjhprBJvOFoxf .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-LsfvjhprBJvOFoxf :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Scheduling Framework
调度框架
注册到扩展点
内置插件
(pkg/scheduler/framework/plugins/)
NodeName
节点名匹配
NodeAffinity
节点亲和性
TaintToleration
污点容忍
NodeResources
资源充足性
PodTopologySpread
拓扑分布
InterPodAffinity
Pod 间亲和
VolumeBinding
卷绑定
ImageLocality
镜像本地性
DefaultBinder
默认绑定器
DefaultPreemption
默认抢占
扩展点
抢占后重试
QueueSort
排队排序
PreFilter
预过滤
Filter
过滤
PostFilter
后过滤
(抢占/重试)
PreScore
预评分
Score
评分
NormalizeScore
评分归一化
Reserve
预留资源
Permit
批准/拒绝/等待
PreBind
预绑定
Bind
绑定
PostBind
后绑定
10.2 调度完整流程
Binder 节点缓存 SchedulerCache Scheduling Framework Scheduler Core 调度队列 PriorityQueue API Server Binder 节点缓存 SchedulerCache Scheduling Framework Scheduler Core 调度队列 PriorityQueue API Server #mermaid-svg-4A8EgRHyNFj6GGvp{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-4A8EgRHyNFj6GGvp .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-4A8EgRHyNFj6GGvp .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-4A8EgRHyNFj6GGvp .error-icon{fill:#552222;}#mermaid-svg-4A8EgRHyNFj6GGvp .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-4A8EgRHyNFj6GGvp .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-4A8EgRHyNFj6GGvp .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-4A8EgRHyNFj6GGvp .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-4A8EgRHyNFj6GGvp .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-4A8EgRHyNFj6GGvp .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-4A8EgRHyNFj6GGvp .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-4A8EgRHyNFj6GGvp .marker{fill:#333333;stroke:#333333;}#mermaid-svg-4A8EgRHyNFj6GGvp .marker.cross{stroke:#333333;}#mermaid-svg-4A8EgRHyNFj6GGvp svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-4A8EgRHyNFj6GGvp p{margin:0;}#mermaid-svg-4A8EgRHyNFj6GGvp .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-4A8EgRHyNFj6GGvp text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-4A8EgRHyNFj6GGvp .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-4A8EgRHyNFj6GGvp .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-4A8EgRHyNFj6GGvp .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-4A8EgRHyNFj6GGvp .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-4A8EgRHyNFj6GGvp #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-4A8EgRHyNFj6GGvp .sequenceNumber{fill:white;}#mermaid-svg-4A8EgRHyNFj6GGvp #sequencenumber{fill:#333;}#mermaid-svg-4A8EgRHyNFj6GGvp #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-4A8EgRHyNFj6GGvp .messageText{fill:#333;stroke:none;}#mermaid-svg-4A8EgRHyNFj6GGvp .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-4A8EgRHyNFj6GGvp .labelText,#mermaid-svg-4A8EgRHyNFj6GGvp .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-4A8EgRHyNFj6GGvp .loopText,#mermaid-svg-4A8EgRHyNFj6GGvp .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-4A8EgRHyNFj6GGvp .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-4A8EgRHyNFj6GGvp .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-4A8EgRHyNFj6GGvp .noteText,#mermaid-svg-4A8EgRHyNFj6GGvp .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-4A8EgRHyNFj6GGvp .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-4A8EgRHyNFj6GGvp .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-4A8EgRHyNFj6GGvp .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-4A8EgRHyNFj6GGvp .actorPopupMenu{position:absolute;}#mermaid-svg-4A8EgRHyNFj6GGvp .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-4A8EgRHyNFj6GGvp .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-4A8EgRHyNFj6GGvp .actor-man circle,#mermaid-svg-4A8EgRHyNFj6GGvp line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-4A8EgRHyNFj6GGvp :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} PreFilter 阶段 Filter 阶段 (并发) par 对每个节点并发执行 过滤掉不满足条件的节点 剩余为 Feasible Nodes PostFilter 阶段 (抢占) Score 阶段 (并发) par 对每个可行节点并发评分 选择最高分节点 alt 无可用节点 有可用节点 Reserve → Permit → Bind loop 调度循环 Watch 新 Pod (nodeName="") QueueSort 插件排序 (优先级/Priority 排序) 取出待调度 Pod PreFilter(Pod) 计算 Pod 调度约束 (资源请求、亲和性等) 获取所有候选节点 Filter(Pod, Node_i) NodeName/NodeAffinity TaintToleration/PodFitsResources NodePorts/VolumeConstraints PostFilter(Pod) DefaultPreemption 驱逐低优先级 Pod 腾出资源 抢占成功,重新入队 Score(Pod, Node_i) NodeResources/CPU-Mem 均衡 ImageLocality/InterPodAffinity PodTopologySpread NormalizeScore (归一化到 0-100) Reserve(Pod, Node) (预留资源,防止并发冲突) Permit(Pod, Node) (批准/拒绝/等待) PreBind(Pod, Node) (卷预绑定等) Bind(Pod, Node) POST /api/v1/.../pods/<name>/binding 200 OK PostBind(Pod, Node) (清理缓存/通知)
调度框架源码对应
| 组件 | 源码位置 | 说明 |
|---|---|---|
| 调度器入口 | cmd/kube-scheduler/app/server.go |
Cobra 命令,创建调度器 |
| 调度核心 | pkg/scheduler/scheduler.go |
ScheduleOne 主循环 |
| 调度队列 | pkg/scheduler/internal/queue/ |
PriorityQueue,支持优先级和回退 |
| 调度缓存 | pkg/scheduler/internal/cache/ |
节点信息缓存,避免频繁 List |
| Framework 接口 | pkg/scheduler/framework/interface.go |
Plugin 扩展点定义 |
| Filter 插件 | pkg/scheduler/framework/plugins/noderesources/ |
资源充足性检查 |
| Score 插件 | pkg/scheduler/framework/plugins/noderesources/ |
资源均衡评分 |
| Bind 插件 | pkg/scheduler/framework/plugins/defaultbinder/ |
默认绑定实现 |
| 抢占插件 | pkg/scheduler/framework/plugins/defaultpreemption/ |
默认抢占实现 |
十一、Kubelet 节点架构图
源码位置:pkg/kubelet/ + cmd/kubelet/app/server.go
#mermaid-svg-DQO5cVRwsh4sq15r{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-DQO5cVRwsh4sq15r .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-DQO5cVRwsh4sq15r .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-DQO5cVRwsh4sq15r .error-icon{fill:#552222;}#mermaid-svg-DQO5cVRwsh4sq15r .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-DQO5cVRwsh4sq15r .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-DQO5cVRwsh4sq15r .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-DQO5cVRwsh4sq15r .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-DQO5cVRwsh4sq15r .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-DQO5cVRwsh4sq15r .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-DQO5cVRwsh4sq15r .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-DQO5cVRwsh4sq15r .marker{fill:#333333;stroke:#333333;}#mermaid-svg-DQO5cVRwsh4sq15r .marker.cross{stroke:#333333;}#mermaid-svg-DQO5cVRwsh4sq15r svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-DQO5cVRwsh4sq15r p{margin:0;}#mermaid-svg-DQO5cVRwsh4sq15r .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-DQO5cVRwsh4sq15r .cluster-label text{fill:#333;}#mermaid-svg-DQO5cVRwsh4sq15r .cluster-label span{color:#333;}#mermaid-svg-DQO5cVRwsh4sq15r .cluster-label span p{background-color:transparent;}#mermaid-svg-DQO5cVRwsh4sq15r .label text,#mermaid-svg-DQO5cVRwsh4sq15r span{fill:#333;color:#333;}#mermaid-svg-DQO5cVRwsh4sq15r .node rect,#mermaid-svg-DQO5cVRwsh4sq15r .node circle,#mermaid-svg-DQO5cVRwsh4sq15r .node ellipse,#mermaid-svg-DQO5cVRwsh4sq15r .node polygon,#mermaid-svg-DQO5cVRwsh4sq15r .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-DQO5cVRwsh4sq15r .rough-node .label text,#mermaid-svg-DQO5cVRwsh4sq15r .node .label text,#mermaid-svg-DQO5cVRwsh4sq15r .image-shape .label,#mermaid-svg-DQO5cVRwsh4sq15r .icon-shape .label{text-anchor:middle;}#mermaid-svg-DQO5cVRwsh4sq15r .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-DQO5cVRwsh4sq15r .rough-node .label,#mermaid-svg-DQO5cVRwsh4sq15r .node .label,#mermaid-svg-DQO5cVRwsh4sq15r .image-shape .label,#mermaid-svg-DQO5cVRwsh4sq15r .icon-shape .label{text-align:center;}#mermaid-svg-DQO5cVRwsh4sq15r .node.clickable{cursor:pointer;}#mermaid-svg-DQO5cVRwsh4sq15r .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-DQO5cVRwsh4sq15r .arrowheadPath{fill:#333333;}#mermaid-svg-DQO5cVRwsh4sq15r .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-DQO5cVRwsh4sq15r .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-DQO5cVRwsh4sq15r .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-DQO5cVRwsh4sq15r .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-DQO5cVRwsh4sq15r .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-DQO5cVRwsh4sq15r .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-DQO5cVRwsh4sq15r .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-DQO5cVRwsh4sq15r .cluster text{fill:#333;}#mermaid-svg-DQO5cVRwsh4sq15r .cluster span{color:#333;}#mermaid-svg-DQO5cVRwsh4sq15r div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-DQO5cVRwsh4sq15r .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-DQO5cVRwsh4sq15r rect.text{fill:none;stroke-width:0;}#mermaid-svg-DQO5cVRwsh4sq15r .icon-shape,#mermaid-svg-DQO5cVRwsh4sq15r .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-DQO5cVRwsh4sq15r .icon-shape p,#mermaid-svg-DQO5cVRwsh4sq15r .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-DQO5cVRwsh4sq15r .icon-shape .label rect,#mermaid-svg-DQO5cVRwsh4sq15r .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-DQO5cVRwsh4sq15r .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-DQO5cVRwsh4sq15r .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-DQO5cVRwsh4sq15r :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 外部依赖
Kubelet 节点代理
节点状态管理
健康监控
网络管理
卷管理器
容器运行时层
Pod 生命周期管理
Watch Pod
SyncPod
gRPC CRI
Exec CNI
gRPC CSI
Mount/Unmount
事件驱动
驱逐 Pod
Update Status
Update Node
Update Lease
Pod Configuration
配置源 (File/HTTP/API)
Pod Manager
Pod 存储与管理
Status Manager
Pod 状态上报
Pod Workers
每 Pod 一个 goroutine
同步逻辑
CRI Runtime
kuberuntime_manager.go
Container GC
容器垃圾回收
Image Manager
镜像拉取与 GC
RuntimeClass
运行时类型选择
Desired State
期望卷状态
Actual State
实际卷状态
Volume Reconciler
协调挂载/卸载
CSI Plugin
CSI gRPC 调用
CNI Runner
网络插件调用
DNS Config
Pod DNS 配置
HostPort Manager
端口映射
Prober Manager
Liveness/Readiness/
Startup Probe
PLEG
Pod Lifecycle Event
Generator
CAdvisor
容器资源监控
Eviction Manager
资源驱逐
Node Status
节点心跳上报
Node Lease
租约续期
Certificate Manager
证书轮转
API Server
containerd / CRI-O
Daemon
CNI 插件二进制
CSI Driver Daemon
Kubelet 核心模块说明
| 模块 | 源码位置 | 职责 |
|---|---|---|
| Pod Workers | pkg/kubelet/pod_workers.go |
为每个 Pod 启动独立 goroutine 执行 SyncPod |
| CRI Runtime | pkg/kubelet/kuberuntime/ |
通过 CRI gRPC 接口操作容器运行时 |
| Volume Manager | pkg/kubelet/volumemanager/ |
期望/实际状态协调,驱动卷挂载/卸载 |
| PLEG | pkg/kubelet/pleg/ |
定期查询 CRI 获取容器状态变更,生成事件 |
| Prober | pkg/kubelet/prober/ |
执行 Liveness/Readiness/Startup 探针 |
| Eviction | pkg/kubelet/eviction/ |
节点资源不足时驱逐低优先级 Pod |
| Status Manager | pkg/kubelet/status/ |
聚合 Pod 状态并上报 API Server |
| Certificate Manager | pkg/kubelet/certificate/ |
自动申请和轮转 Kubelet 客户端证书 |
PLEG 机制详解 :
PLEG(Pod Lifecycle Event Generator)是 Kubelet 的核心事件驱动机制。它通过定时(默认 1s)调用 CRI 的 ListPodSandbox 和 ListContainers 获取容器运行时状态,与本地缓存对比生成 Pod 生命周期事件(Started/Died/Changed),驱动 Pod Workers 执行同步操作。这种设计避免了为每个容器设置独立 Watch 的开销。
十二、网络模型与 Service 架构图
12.1 三层网络模型
#mermaid-svg-KKREGDYECefLMz4G{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-KKREGDYECefLMz4G .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-KKREGDYECefLMz4G .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-KKREGDYECefLMz4G .error-icon{fill:#552222;}#mermaid-svg-KKREGDYECefLMz4G .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-KKREGDYECefLMz4G .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-KKREGDYECefLMz4G .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-KKREGDYECefLMz4G .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-KKREGDYECefLMz4G .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-KKREGDYECefLMz4G .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-KKREGDYECefLMz4G .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-KKREGDYECefLMz4G .marker{fill:#333333;stroke:#333333;}#mermaid-svg-KKREGDYECefLMz4G .marker.cross{stroke:#333333;}#mermaid-svg-KKREGDYECefLMz4G svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-KKREGDYECefLMz4G p{margin:0;}#mermaid-svg-KKREGDYECefLMz4G .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-KKREGDYECefLMz4G .cluster-label text{fill:#333;}#mermaid-svg-KKREGDYECefLMz4G .cluster-label span{color:#333;}#mermaid-svg-KKREGDYECefLMz4G .cluster-label span p{background-color:transparent;}#mermaid-svg-KKREGDYECefLMz4G .label text,#mermaid-svg-KKREGDYECefLMz4G span{fill:#333;color:#333;}#mermaid-svg-KKREGDYECefLMz4G .node rect,#mermaid-svg-KKREGDYECefLMz4G .node circle,#mermaid-svg-KKREGDYECefLMz4G .node ellipse,#mermaid-svg-KKREGDYECefLMz4G .node polygon,#mermaid-svg-KKREGDYECefLMz4G .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-KKREGDYECefLMz4G .rough-node .label text,#mermaid-svg-KKREGDYECefLMz4G .node .label text,#mermaid-svg-KKREGDYECefLMz4G .image-shape .label,#mermaid-svg-KKREGDYECefLMz4G .icon-shape .label{text-anchor:middle;}#mermaid-svg-KKREGDYECefLMz4G .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-KKREGDYECefLMz4G .rough-node .label,#mermaid-svg-KKREGDYECefLMz4G .node .label,#mermaid-svg-KKREGDYECefLMz4G .image-shape .label,#mermaid-svg-KKREGDYECefLMz4G .icon-shape .label{text-align:center;}#mermaid-svg-KKREGDYECefLMz4G .node.clickable{cursor:pointer;}#mermaid-svg-KKREGDYECefLMz4G .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-KKREGDYECefLMz4G .arrowheadPath{fill:#333333;}#mermaid-svg-KKREGDYECefLMz4G .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-KKREGDYECefLMz4G .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-KKREGDYECefLMz4G .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-KKREGDYECefLMz4G .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-KKREGDYECefLMz4G .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-KKREGDYECefLMz4G .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-KKREGDYECefLMz4G .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-KKREGDYECefLMz4G .cluster text{fill:#333;}#mermaid-svg-KKREGDYECefLMz4G .cluster span{color:#333;}#mermaid-svg-KKREGDYECefLMz4G div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-KKREGDYECefLMz4G .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-KKREGDYECefLMz4G rect.text{fill:none;stroke-width:0;}#mermaid-svg-KKREGDYECefLMz4G .icon-shape,#mermaid-svg-KKREGDYECefLMz4G .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-KKREGDYECefLMz4G .icon-shape p,#mermaid-svg-KKREGDYECefLMz4G .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-KKREGDYECefLMz4G .icon-shape .label rect,#mermaid-svg-KKREGDYECefLMz4G .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-KKREGDYECefLMz4G .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-KKREGDYECefLMz4G .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-KKREGDYECefLMz4G :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Kubernetes 网络三层模型
L2: Pod 网络
(CNI 插件管理)
节点间通信
Pod ↔ Pod 直通
ClusterIP → Pod
L3: Service 网络
(虚拟 IP,kube-proxy 管理)
ClusterIP
10.96.0.0/12
集群内部可达
NodePort
30000-32767
节点端口映射
LoadBalancer
云负载均衡器
外部流量入口
ExternalIP
外部可达 IP
L1: 节点网络
(物理/虚拟网络)
节点 IP
192.168.1.10/24
192.168.1.11/24
192.168.1.12/24
节点 3: 10.244.3.0/24
Pod E: 10.244.3.11
CNI Bridge / VXLAN / BGP
跨节点 Pod 互通
节点 2: 10.244.2.0/24
Pod C: 10.244.2.7
Pod D: 10.244.2.9
节点 1: 10.244.1.0/24
Pod A: 10.244.1.3
Pod B: 10.244.1.5
Pod CIDR
10.244.0.0/16
每节点分配 /24 子网
12.2 kube-proxy 工作流程
源码位置:pkg/proxy/(iptables/ipvs/userspace 三种模式)
集群内客户端 iptables / IPVS EndpointSlice Controller kube-proxy API Server 集群内客户端 iptables / IPVS EndpointSlice Controller kube-proxy API Server #mermaid-svg-Cj28E8uJOBP7ifWg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Cj28E8uJOBP7ifWg .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Cj28E8uJOBP7ifWg .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Cj28E8uJOBP7ifWg .error-icon{fill:#552222;}#mermaid-svg-Cj28E8uJOBP7ifWg .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Cj28E8uJOBP7ifWg .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Cj28E8uJOBP7ifWg .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Cj28E8uJOBP7ifWg .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Cj28E8uJOBP7ifWg .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Cj28E8uJOBP7ifWg .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Cj28E8uJOBP7ifWg .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Cj28E8uJOBP7ifWg .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Cj28E8uJOBP7ifWg .marker.cross{stroke:#333333;}#mermaid-svg-Cj28E8uJOBP7ifWg svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Cj28E8uJOBP7ifWg p{margin:0;}#mermaid-svg-Cj28E8uJOBP7ifWg .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-Cj28E8uJOBP7ifWg text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-Cj28E8uJOBP7ifWg .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-Cj28E8uJOBP7ifWg .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-Cj28E8uJOBP7ifWg .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-Cj28E8uJOBP7ifWg .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-Cj28E8uJOBP7ifWg #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-Cj28E8uJOBP7ifWg .sequenceNumber{fill:white;}#mermaid-svg-Cj28E8uJOBP7ifWg #sequencenumber{fill:#333;}#mermaid-svg-Cj28E8uJOBP7ifWg #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-Cj28E8uJOBP7ifWg .messageText{fill:#333;stroke:none;}#mermaid-svg-Cj28E8uJOBP7ifWg .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-Cj28E8uJOBP7ifWg .labelText,#mermaid-svg-Cj28E8uJOBP7ifWg .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-Cj28E8uJOBP7ifWg .loopText,#mermaid-svg-Cj28E8uJOBP7ifWg .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-Cj28E8uJOBP7ifWg .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-Cj28E8uJOBP7ifWg .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-Cj28E8uJOBP7ifWg .noteText,#mermaid-svg-Cj28E8uJOBP7ifWg .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-Cj28E8uJOBP7ifWg .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-Cj28E8uJOBP7ifWg .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-Cj28E8uJOBP7ifWg .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-Cj28E8uJOBP7ifWg .actorPopupMenu{position:absolute;}#mermaid-svg-Cj28E8uJOBP7ifWg .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-Cj28E8uJOBP7ifWg .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-Cj28E8uJOBP7ifWg .actor-man circle,#mermaid-svg-Cj28E8uJOBP7ifWg line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-Cj28E8uJOBP7ifWg :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Service 变更事件触发 alt iptables 模式 ipvs 模式 请求处理 Watch Service 变更 Watch EndpointSlice 变更 构建 Service 规则映射 ClusterIP → Endpoints iptables-restore 写入 KUBE-SERVICES 链 写入 KUBE-SVC-XXX 链 写入 KUBE-SEP-XXX 链 ipvsadm 创建 VirtualServer 绑定 RealServer ipvs 内核负载均衡 访问 10.96.100.1:80 (Service ClusterIP) DNAT 转换 10.96.100.1:80 → 10.244.2.7:80 响应数据 (源 IP 还原)
12.3 Service 请求路由详解
#mermaid-svg-qTO0n0TiJmHtHoT0{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-qTO0n0TiJmHtHoT0 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-qTO0n0TiJmHtHoT0 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-qTO0n0TiJmHtHoT0 .error-icon{fill:#552222;}#mermaid-svg-qTO0n0TiJmHtHoT0 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-qTO0n0TiJmHtHoT0 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-qTO0n0TiJmHtHoT0 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-qTO0n0TiJmHtHoT0 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-qTO0n0TiJmHtHoT0 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-qTO0n0TiJmHtHoT0 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-qTO0n0TiJmHtHoT0 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-qTO0n0TiJmHtHoT0 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-qTO0n0TiJmHtHoT0 .marker.cross{stroke:#333333;}#mermaid-svg-qTO0n0TiJmHtHoT0 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-qTO0n0TiJmHtHoT0 p{margin:0;}#mermaid-svg-qTO0n0TiJmHtHoT0 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-qTO0n0TiJmHtHoT0 .cluster-label text{fill:#333;}#mermaid-svg-qTO0n0TiJmHtHoT0 .cluster-label span{color:#333;}#mermaid-svg-qTO0n0TiJmHtHoT0 .cluster-label span p{background-color:transparent;}#mermaid-svg-qTO0n0TiJmHtHoT0 .label text,#mermaid-svg-qTO0n0TiJmHtHoT0 span{fill:#333;color:#333;}#mermaid-svg-qTO0n0TiJmHtHoT0 .node rect,#mermaid-svg-qTO0n0TiJmHtHoT0 .node circle,#mermaid-svg-qTO0n0TiJmHtHoT0 .node ellipse,#mermaid-svg-qTO0n0TiJmHtHoT0 .node polygon,#mermaid-svg-qTO0n0TiJmHtHoT0 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-qTO0n0TiJmHtHoT0 .rough-node .label text,#mermaid-svg-qTO0n0TiJmHtHoT0 .node .label text,#mermaid-svg-qTO0n0TiJmHtHoT0 .image-shape .label,#mermaid-svg-qTO0n0TiJmHtHoT0 .icon-shape .label{text-anchor:middle;}#mermaid-svg-qTO0n0TiJmHtHoT0 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-qTO0n0TiJmHtHoT0 .rough-node .label,#mermaid-svg-qTO0n0TiJmHtHoT0 .node .label,#mermaid-svg-qTO0n0TiJmHtHoT0 .image-shape .label,#mermaid-svg-qTO0n0TiJmHtHoT0 .icon-shape .label{text-align:center;}#mermaid-svg-qTO0n0TiJmHtHoT0 .node.clickable{cursor:pointer;}#mermaid-svg-qTO0n0TiJmHtHoT0 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-qTO0n0TiJmHtHoT0 .arrowheadPath{fill:#333333;}#mermaid-svg-qTO0n0TiJmHtHoT0 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-qTO0n0TiJmHtHoT0 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-qTO0n0TiJmHtHoT0 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-qTO0n0TiJmHtHoT0 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-qTO0n0TiJmHtHoT0 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-qTO0n0TiJmHtHoT0 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-qTO0n0TiJmHtHoT0 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-qTO0n0TiJmHtHoT0 .cluster text{fill:#333;}#mermaid-svg-qTO0n0TiJmHtHoT0 .cluster span{color:#333;}#mermaid-svg-qTO0n0TiJmHtHoT0 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-qTO0n0TiJmHtHoT0 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-qTO0n0TiJmHtHoT0 rect.text{fill:none;stroke-width:0;}#mermaid-svg-qTO0n0TiJmHtHoT0 .icon-shape,#mermaid-svg-qTO0n0TiJmHtHoT0 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-qTO0n0TiJmHtHoT0 .icon-shape p,#mermaid-svg-qTO0n0TiJmHtHoT0 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-qTO0n0TiJmHtHoT0 .icon-shape .label rect,#mermaid-svg-qTO0n0TiJmHtHoT0 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-qTO0n0TiJmHtHoT0 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-qTO0n0TiJmHtHoT0 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-qTO0n0TiJmHtHoT0 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 后端 Pod
Linux Netfilter
(iptables/IPVS)
集群内 Pod (客户端)
TCP 10.96.100.1:80
1/3 概率
1/3 概率
1/3 概率
DNAT
DNAT
DNAT
DNS 查询
返回 ClusterIP
CoreDNS
nginx.default.svc.cluster.local
→ 10.96.100.1
应用容器
curl http://nginx.default.svc
KUBE-SERVICES 链
匹配 ClusterIP
KUBE-SVC-NGINX 链
概率选择后端
KUBE-SEP-POD1
→ 10.244.1.10:80
KUBE-SEP-POD2
→ 10.244.2.20:80
KUBE-SEP-POD3
→ 10.244.3.30:80
Pod 1
10.244.1.10:80
Pod 2
10.244.2.20:80
Pod 3
10.244.3.30:80
kube-proxy 源码结构
| 模式 | 源码位置 | 说明 |
|---|---|---|
| iptables | pkg/proxy/iptables/ |
基于 iptables 规则,默认模式 |
| IPVS | pkg/proxy/ipvs/ |
基于 IPVS 内核负载均衡,高性能 |
| userspace | pkg/proxy/userspace/ |
用户态代理,已废弃 |
| Endpoints 缓存 | pkg/proxy/endpointslicecache.go |
EndpointSlice → 内部 EndpointsMap |
| 规则同步 | pkg/proxy/service.go |
Service/Endpoint 变更触发规则重写 |
十三、Informer/Cache 机制图
Informer 是 Kubernetes 控制器编程的核心模式,所有控制器都基于 Informer 实现状态同步:
#mermaid-svg-yISTZri5COm5Cf8K{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-yISTZri5COm5Cf8K .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-yISTZri5COm5Cf8K .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-yISTZri5COm5Cf8K .error-icon{fill:#552222;}#mermaid-svg-yISTZri5COm5Cf8K .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-yISTZri5COm5Cf8K .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-yISTZri5COm5Cf8K .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-yISTZri5COm5Cf8K .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-yISTZri5COm5Cf8K .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-yISTZri5COm5Cf8K .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-yISTZri5COm5Cf8K .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-yISTZri5COm5Cf8K .marker{fill:#333333;stroke:#333333;}#mermaid-svg-yISTZri5COm5Cf8K .marker.cross{stroke:#333333;}#mermaid-svg-yISTZri5COm5Cf8K svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-yISTZri5COm5Cf8K p{margin:0;}#mermaid-svg-yISTZri5COm5Cf8K .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-yISTZri5COm5Cf8K .cluster-label text{fill:#333;}#mermaid-svg-yISTZri5COm5Cf8K .cluster-label span{color:#333;}#mermaid-svg-yISTZri5COm5Cf8K .cluster-label span p{background-color:transparent;}#mermaid-svg-yISTZri5COm5Cf8K .label text,#mermaid-svg-yISTZri5COm5Cf8K span{fill:#333;color:#333;}#mermaid-svg-yISTZri5COm5Cf8K .node rect,#mermaid-svg-yISTZri5COm5Cf8K .node circle,#mermaid-svg-yISTZri5COm5Cf8K .node ellipse,#mermaid-svg-yISTZri5COm5Cf8K .node polygon,#mermaid-svg-yISTZri5COm5Cf8K .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-yISTZri5COm5Cf8K .rough-node .label text,#mermaid-svg-yISTZri5COm5Cf8K .node .label text,#mermaid-svg-yISTZri5COm5Cf8K .image-shape .label,#mermaid-svg-yISTZri5COm5Cf8K .icon-shape .label{text-anchor:middle;}#mermaid-svg-yISTZri5COm5Cf8K .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-yISTZri5COm5Cf8K .rough-node .label,#mermaid-svg-yISTZri5COm5Cf8K .node .label,#mermaid-svg-yISTZri5COm5Cf8K .image-shape .label,#mermaid-svg-yISTZri5COm5Cf8K .icon-shape .label{text-align:center;}#mermaid-svg-yISTZri5COm5Cf8K .node.clickable{cursor:pointer;}#mermaid-svg-yISTZri5COm5Cf8K .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-yISTZri5COm5Cf8K .arrowheadPath{fill:#333333;}#mermaid-svg-yISTZri5COm5Cf8K .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-yISTZri5COm5Cf8K .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-yISTZri5COm5Cf8K .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-yISTZri5COm5Cf8K .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-yISTZri5COm5Cf8K .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-yISTZri5COm5Cf8K .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-yISTZri5COm5Cf8K .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-yISTZri5COm5Cf8K .cluster text{fill:#333;}#mermaid-svg-yISTZri5COm5Cf8K .cluster span{color:#333;}#mermaid-svg-yISTZri5COm5Cf8K div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-yISTZri5COm5Cf8K .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-yISTZri5COm5Cf8K rect.text{fill:none;stroke-width:0;}#mermaid-svg-yISTZri5COm5Cf8K .icon-shape,#mermaid-svg-yISTZri5COm5Cf8K .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-yISTZri5COm5Cf8K .icon-shape p,#mermaid-svg-yISTZri5COm5Cf8K .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-yISTZri5COm5Cf8K .icon-shape .label rect,#mermaid-svg-yISTZri5COm5Cf8K .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-yISTZri5COm5Cf8K .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-yISTZri5COm5Cf8K .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-yISTZri5COm5Cf8K :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Lister 接口
控制器
SharedInformer
Store 接口
Reflector
(client-go)
Kube-APIServer
触发 OnUpdate
Enqueue Key
List() 查询
List() 查询
Watch Event
Update API Server
Etcd 集群
KV 数据
Revision: 12345
Watch API
/api/v1/.../pods?watch=true&resourceVersion=12345
List API
/api/v1/.../pods
ListAndWatch()
-
List 全量
-
Watch 增量
Watch 结果流
ADDED/MODIFIED/DELETED
Cache
(ThreadSafeStore)
Key → Object Map
索引器 Indexers
KeyFunc
namespace/name → Key
Event Handlers
OnAdd / OnUpdate / OnDelete
Resync Timer
定期全量同步
(默认: 无)
Work Queue
RateLimitingQueue
(去重 + 限流 + 重试)
Worker Loop
ProcessNextWorkItem()
Reconcile 逻辑
期望 vs 实际
PodLister
Pods(namespace)
ServiceLister
NodeLister
Informer 机制详解
源码位置 :staging/src/k8s.io/client-go/informers/ + staging/src/k8s.io/client-go/tools/cache/
核心流程:
- ListAndWatch:Reflector 先 List 全量数据建立初始缓存,然后启动 Watch 流接收增量事件
- ResourceVersion:每次 Watch 携带上次收到的 ResourceVersion,API Server 只推送该版本之后的变更
- 本地缓存:所有通过 Informer 读取的数据来自本地内存,不直接调用 API Server
- 共享机制:SharedInformerFactory 确保同一资源的 Informer 只创建一个,多个控制器共享同一缓存
- Resync:可选的定期全量同步,将缓存中所有对象重新触发 OnUpdate 事件,确保没有遗漏
- WorkQueue :事件处理器将 Key(
namespace/name)入队而非整个对象,保证处理顺序和限流
十四、插件化与扩展架构图
Kubernetes 的核心设计理念之一是插件化,几乎所有功能模块都支持通过接口扩展:
#mermaid-svg-XUL1gy9xAB6RN3w6{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-XUL1gy9xAB6RN3w6 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-XUL1gy9xAB6RN3w6 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-XUL1gy9xAB6RN3w6 .error-icon{fill:#552222;}#mermaid-svg-XUL1gy9xAB6RN3w6 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-XUL1gy9xAB6RN3w6 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-XUL1gy9xAB6RN3w6 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-XUL1gy9xAB6RN3w6 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-XUL1gy9xAB6RN3w6 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-XUL1gy9xAB6RN3w6 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-XUL1gy9xAB6RN3w6 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-XUL1gy9xAB6RN3w6 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-XUL1gy9xAB6RN3w6 .marker.cross{stroke:#333333;}#mermaid-svg-XUL1gy9xAB6RN3w6 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-XUL1gy9xAB6RN3w6 p{margin:0;}#mermaid-svg-XUL1gy9xAB6RN3w6 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-XUL1gy9xAB6RN3w6 .cluster-label text{fill:#333;}#mermaid-svg-XUL1gy9xAB6RN3w6 .cluster-label span{color:#333;}#mermaid-svg-XUL1gy9xAB6RN3w6 .cluster-label span p{background-color:transparent;}#mermaid-svg-XUL1gy9xAB6RN3w6 .label text,#mermaid-svg-XUL1gy9xAB6RN3w6 span{fill:#333;color:#333;}#mermaid-svg-XUL1gy9xAB6RN3w6 .node rect,#mermaid-svg-XUL1gy9xAB6RN3w6 .node circle,#mermaid-svg-XUL1gy9xAB6RN3w6 .node ellipse,#mermaid-svg-XUL1gy9xAB6RN3w6 .node polygon,#mermaid-svg-XUL1gy9xAB6RN3w6 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-XUL1gy9xAB6RN3w6 .rough-node .label text,#mermaid-svg-XUL1gy9xAB6RN3w6 .node .label text,#mermaid-svg-XUL1gy9xAB6RN3w6 .image-shape .label,#mermaid-svg-XUL1gy9xAB6RN3w6 .icon-shape .label{text-anchor:middle;}#mermaid-svg-XUL1gy9xAB6RN3w6 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-XUL1gy9xAB6RN3w6 .rough-node .label,#mermaid-svg-XUL1gy9xAB6RN3w6 .node .label,#mermaid-svg-XUL1gy9xAB6RN3w6 .image-shape .label,#mermaid-svg-XUL1gy9xAB6RN3w6 .icon-shape .label{text-align:center;}#mermaid-svg-XUL1gy9xAB6RN3w6 .node.clickable{cursor:pointer;}#mermaid-svg-XUL1gy9xAB6RN3w6 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-XUL1gy9xAB6RN3w6 .arrowheadPath{fill:#333333;}#mermaid-svg-XUL1gy9xAB6RN3w6 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-XUL1gy9xAB6RN3w6 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-XUL1gy9xAB6RN3w6 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-XUL1gy9xAB6RN3w6 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-XUL1gy9xAB6RN3w6 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-XUL1gy9xAB6RN3w6 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-XUL1gy9xAB6RN3w6 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-XUL1gy9xAB6RN3w6 .cluster text{fill:#333;}#mermaid-svg-XUL1gy9xAB6RN3w6 .cluster span{color:#333;}#mermaid-svg-XUL1gy9xAB6RN3w6 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-XUL1gy9xAB6RN3w6 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-XUL1gy9xAB6RN3w6 rect.text{fill:none;stroke-width:0;}#mermaid-svg-XUL1gy9xAB6RN3w6 .icon-shape,#mermaid-svg-XUL1gy9xAB6RN3w6 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-XUL1gy9xAB6RN3w6 .icon-shape p,#mermaid-svg-XUL1gy9xAB6RN3w6 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-XUL1gy9xAB6RN3w6 .icon-shape .label rect,#mermaid-svg-XUL1gy9xAB6RN3w6 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-XUL1gy9xAB6RN3w6 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-XUL1gy9xAB6RN3w6 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-XUL1gy9xAB6RN3w6 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 扩展层
Kubernetes 核心
(不可变部分)
认证授权扩展
云平台扩展
运行时扩展
调度扩展
存储扩展
网络扩展
API 扩展
API Server
REST + Watch + Etcd
Controller Manager
控制器框架
Scheduler
调度框架
Kubelet
Pod 生命周期
CRD
自定义资源定义
(apiextensions-apiserver)
API Aggregation
聚合 API Server
(kube-aggregator)
Mutating
Admission Webhook
Validating
Admission Webhook
CNI 插件
(Calico/Flannel/
Cilium/Weave)
kube-proxy 模式
iptables / IPVS
Ingress Controller
(Nginx/Traefik/
Envoy Gateway)
Gateway API
(新一代路由)
CSI 插件
(标准化存储接口)
FlexVolume
(旧版存储插件)
Dynamic Provisioner
StorageClass 驱动
Scheduler Plugin
自定义 Filter/Score
Scheduler Extender
HTTP 扩展
Descheduler
重调度优化
CRI Runtime
(containerd/CRI-O/
Kata Containers)
Device Plugin
(GPU/FPGA/RDMA)
Cloud Provider
(AWS/GCP/Azure/
OpenStack/VSphere)
Cloud Controller
Manager
CSI Cloud Driver
云盘供给
Webhook
Authentication
Webhook
Authorization
OIDC
集成
插件接口源码映射
| 扩展点 | 接口定义 | 源码位置 | 扩展方式 |
|---|---|---|---|
| CRI | runtimeapi.RuntimeService |
staging/src/k8s.io/cri-api/ |
gRPC 插件 |
| CNI | CNI Plugin Interface |
外部规范 | 可执行二进制 |
| CSI | csi.*Server |
staging/src/k8s.io/csi-translation-lib/ |
gRPC 插件 |
| Scheduler Plugin | framework.Plugin |
pkg/scheduler/framework/interface.go |
Go 插件 |
| Admission Webhook | admission.Webhook |
staging/src/k8s.io/apiserver/pkg/admission/plugin/webhook/ |
HTTP Webhook |
| CRD | CustomResourceDefinition |
staging/src/k8s.io/apiextensions-apiserver/ |
YAML 声明 |
| Device Plugin | deviceplugin.Plugin |
staging/src/k8s.io/kubelet/pkg/apis/deviceplugin/ |
gRPC 插件 |
| Cloud Provider | cloudprovider.Interface |
pkg/cloudprovider/ + staging/src/k8s.io/cloud-provider/ |
Go 接口 |
十五、声明式 API 与 Reconcile 模式
15.1 声明式 API 核心原理
Kubernetes 最根本的设计是声明式 API:用户声明"我想要什么"(期望状态),系统负责驱动"实际是什么"(实际状态)趋近期望状态。
#mermaid-svg-A0qt7WTmF5lThJXj{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-A0qt7WTmF5lThJXj .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-A0qt7WTmF5lThJXj .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-A0qt7WTmF5lThJXj .error-icon{fill:#552222;}#mermaid-svg-A0qt7WTmF5lThJXj .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-A0qt7WTmF5lThJXj .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-A0qt7WTmF5lThJXj .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-A0qt7WTmF5lThJXj .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-A0qt7WTmF5lThJXj .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-A0qt7WTmF5lThJXj .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-A0qt7WTmF5lThJXj .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-A0qt7WTmF5lThJXj .marker{fill:#333333;stroke:#333333;}#mermaid-svg-A0qt7WTmF5lThJXj .marker.cross{stroke:#333333;}#mermaid-svg-A0qt7WTmF5lThJXj svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-A0qt7WTmF5lThJXj p{margin:0;}#mermaid-svg-A0qt7WTmF5lThJXj .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-A0qt7WTmF5lThJXj .cluster-label text{fill:#333;}#mermaid-svg-A0qt7WTmF5lThJXj .cluster-label span{color:#333;}#mermaid-svg-A0qt7WTmF5lThJXj .cluster-label span p{background-color:transparent;}#mermaid-svg-A0qt7WTmF5lThJXj .label text,#mermaid-svg-A0qt7WTmF5lThJXj span{fill:#333;color:#333;}#mermaid-svg-A0qt7WTmF5lThJXj .node rect,#mermaid-svg-A0qt7WTmF5lThJXj .node circle,#mermaid-svg-A0qt7WTmF5lThJXj .node ellipse,#mermaid-svg-A0qt7WTmF5lThJXj .node polygon,#mermaid-svg-A0qt7WTmF5lThJXj .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-A0qt7WTmF5lThJXj .rough-node .label text,#mermaid-svg-A0qt7WTmF5lThJXj .node .label text,#mermaid-svg-A0qt7WTmF5lThJXj .image-shape .label,#mermaid-svg-A0qt7WTmF5lThJXj .icon-shape .label{text-anchor:middle;}#mermaid-svg-A0qt7WTmF5lThJXj .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-A0qt7WTmF5lThJXj .rough-node .label,#mermaid-svg-A0qt7WTmF5lThJXj .node .label,#mermaid-svg-A0qt7WTmF5lThJXj .image-shape .label,#mermaid-svg-A0qt7WTmF5lThJXj .icon-shape .label{text-align:center;}#mermaid-svg-A0qt7WTmF5lThJXj .node.clickable{cursor:pointer;}#mermaid-svg-A0qt7WTmF5lThJXj .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-A0qt7WTmF5lThJXj .arrowheadPath{fill:#333333;}#mermaid-svg-A0qt7WTmF5lThJXj .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-A0qt7WTmF5lThJXj .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-A0qt7WTmF5lThJXj .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-A0qt7WTmF5lThJXj .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-A0qt7WTmF5lThJXj .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-A0qt7WTmF5lThJXj .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-A0qt7WTmF5lThJXj .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-A0qt7WTmF5lThJXj .cluster text{fill:#333;}#mermaid-svg-A0qt7WTmF5lThJXj .cluster span{color:#333;}#mermaid-svg-A0qt7WTmF5lThJXj div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-A0qt7WTmF5lThJXj .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-A0qt7WTmF5lThJXj rect.text{fill:none;stroke-width:0;}#mermaid-svg-A0qt7WTmF5lThJXj .icon-shape,#mermaid-svg-A0qt7WTmF5lThJXj .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-A0qt7WTmF5lThJXj .icon-shape p,#mermaid-svg-A0qt7WTmF5lThJXj .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-A0qt7WTmF5lThJXj .icon-shape .label rect,#mermaid-svg-A0qt7WTmF5lThJXj .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-A0qt7WTmF5lThJXj .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-A0qt7WTmF5lThJXj .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-A0qt7WTmF5lThJXj :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 声明式模型
比较
比较
驱动
改变
反馈
期望状态
Spec
(用户定义)
差异
Δ = Spec - Status
实际状态
Status
(系统观测)
操作
Create/Update/Delete
15.2 Reconcile 循环详解
#mermaid-svg-o4RkWtvDoHmQ8h9D{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-o4RkWtvDoHmQ8h9D .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-o4RkWtvDoHmQ8h9D .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-o4RkWtvDoHmQ8h9D .error-icon{fill:#552222;}#mermaid-svg-o4RkWtvDoHmQ8h9D .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-o4RkWtvDoHmQ8h9D .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-o4RkWtvDoHmQ8h9D .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-o4RkWtvDoHmQ8h9D .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-o4RkWtvDoHmQ8h9D .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-o4RkWtvDoHmQ8h9D .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-o4RkWtvDoHmQ8h9D .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-o4RkWtvDoHmQ8h9D .marker{fill:#333333;stroke:#333333;}#mermaid-svg-o4RkWtvDoHmQ8h9D .marker.cross{stroke:#333333;}#mermaid-svg-o4RkWtvDoHmQ8h9D svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-o4RkWtvDoHmQ8h9D p{margin:0;}#mermaid-svg-o4RkWtvDoHmQ8h9D .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-o4RkWtvDoHmQ8h9D .cluster-label text{fill:#333;}#mermaid-svg-o4RkWtvDoHmQ8h9D .cluster-label span{color:#333;}#mermaid-svg-o4RkWtvDoHmQ8h9D .cluster-label span p{background-color:transparent;}#mermaid-svg-o4RkWtvDoHmQ8h9D .label text,#mermaid-svg-o4RkWtvDoHmQ8h9D span{fill:#333;color:#333;}#mermaid-svg-o4RkWtvDoHmQ8h9D .node rect,#mermaid-svg-o4RkWtvDoHmQ8h9D .node circle,#mermaid-svg-o4RkWtvDoHmQ8h9D .node ellipse,#mermaid-svg-o4RkWtvDoHmQ8h9D .node polygon,#mermaid-svg-o4RkWtvDoHmQ8h9D .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-o4RkWtvDoHmQ8h9D .rough-node .label text,#mermaid-svg-o4RkWtvDoHmQ8h9D .node .label text,#mermaid-svg-o4RkWtvDoHmQ8h9D .image-shape .label,#mermaid-svg-o4RkWtvDoHmQ8h9D .icon-shape .label{text-anchor:middle;}#mermaid-svg-o4RkWtvDoHmQ8h9D .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-o4RkWtvDoHmQ8h9D .rough-node .label,#mermaid-svg-o4RkWtvDoHmQ8h9D .node .label,#mermaid-svg-o4RkWtvDoHmQ8h9D .image-shape .label,#mermaid-svg-o4RkWtvDoHmQ8h9D .icon-shape .label{text-align:center;}#mermaid-svg-o4RkWtvDoHmQ8h9D .node.clickable{cursor:pointer;}#mermaid-svg-o4RkWtvDoHmQ8h9D .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-o4RkWtvDoHmQ8h9D .arrowheadPath{fill:#333333;}#mermaid-svg-o4RkWtvDoHmQ8h9D .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-o4RkWtvDoHmQ8h9D .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-o4RkWtvDoHmQ8h9D .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-o4RkWtvDoHmQ8h9D .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-o4RkWtvDoHmQ8h9D .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-o4RkWtvDoHmQ8h9D .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-o4RkWtvDoHmQ8h9D .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-o4RkWtvDoHmQ8h9D .cluster text{fill:#333;}#mermaid-svg-o4RkWtvDoHmQ8h9D .cluster span{color:#333;}#mermaid-svg-o4RkWtvDoHmQ8h9D div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-o4RkWtvDoHmQ8h9D .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-o4RkWtvDoHmQ8h9D rect.text{fill:none;stroke-width:0;}#mermaid-svg-o4RkWtvDoHmQ8h9D .icon-shape,#mermaid-svg-o4RkWtvDoHmQ8h9D .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-o4RkWtvDoHmQ8h9D .icon-shape p,#mermaid-svg-o4RkWtvDoHmQ8h9D .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-o4RkWtvDoHmQ8h9D .icon-shape .label rect,#mermaid-svg-o4RkWtvDoHmQ8h9D .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-o4RkWtvDoHmQ8h9D .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-o4RkWtvDoHmQ8h9D .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-o4RkWtvDoHmQ8h9D :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Reconcile 调和循环
成功
失败
- 从 WorkQueue 取出 Key
- 从 Lister 获取当前对象
- 读取 Spec (期望状态)
- 查询关联资源
(Pod/Service/Node 等)
5. 比较期望 vs 实际
6a. 一致 → 无操作
6b. 不一致 → 计算变更
7. 执行变更
(Create/Update/Delete)
8. 处理错误
(Requeue with Backoff)
9. 标记 Done
15.3 以 Deployment 控制器为例
#mermaid-svg-129rl9yoX2phQ9Ro{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-129rl9yoX2phQ9Ro .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-129rl9yoX2phQ9Ro .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-129rl9yoX2phQ9Ro .error-icon{fill:#552222;}#mermaid-svg-129rl9yoX2phQ9Ro .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-129rl9yoX2phQ9Ro .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-129rl9yoX2phQ9Ro .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-129rl9yoX2phQ9Ro .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-129rl9yoX2phQ9Ro .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-129rl9yoX2phQ9Ro .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-129rl9yoX2phQ9Ro .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-129rl9yoX2phQ9Ro .marker{fill:#333333;stroke:#333333;}#mermaid-svg-129rl9yoX2phQ9Ro .marker.cross{stroke:#333333;}#mermaid-svg-129rl9yoX2phQ9Ro svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-129rl9yoX2phQ9Ro p{margin:0;}#mermaid-svg-129rl9yoX2phQ9Ro .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-129rl9yoX2phQ9Ro .cluster-label text{fill:#333;}#mermaid-svg-129rl9yoX2phQ9Ro .cluster-label span{color:#333;}#mermaid-svg-129rl9yoX2phQ9Ro .cluster-label span p{background-color:transparent;}#mermaid-svg-129rl9yoX2phQ9Ro .label text,#mermaid-svg-129rl9yoX2phQ9Ro span{fill:#333;color:#333;}#mermaid-svg-129rl9yoX2phQ9Ro .node rect,#mermaid-svg-129rl9yoX2phQ9Ro .node circle,#mermaid-svg-129rl9yoX2phQ9Ro .node ellipse,#mermaid-svg-129rl9yoX2phQ9Ro .node polygon,#mermaid-svg-129rl9yoX2phQ9Ro .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-129rl9yoX2phQ9Ro .rough-node .label text,#mermaid-svg-129rl9yoX2phQ9Ro .node .label text,#mermaid-svg-129rl9yoX2phQ9Ro .image-shape .label,#mermaid-svg-129rl9yoX2phQ9Ro .icon-shape .label{text-anchor:middle;}#mermaid-svg-129rl9yoX2phQ9Ro .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-129rl9yoX2phQ9Ro .rough-node .label,#mermaid-svg-129rl9yoX2phQ9Ro .node .label,#mermaid-svg-129rl9yoX2phQ9Ro .image-shape .label,#mermaid-svg-129rl9yoX2phQ9Ro .icon-shape .label{text-align:center;}#mermaid-svg-129rl9yoX2phQ9Ro .node.clickable{cursor:pointer;}#mermaid-svg-129rl9yoX2phQ9Ro .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-129rl9yoX2phQ9Ro .arrowheadPath{fill:#333333;}#mermaid-svg-129rl9yoX2phQ9Ro .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-129rl9yoX2phQ9Ro .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-129rl9yoX2phQ9Ro .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-129rl9yoX2phQ9Ro .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-129rl9yoX2phQ9Ro .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-129rl9yoX2phQ9Ro .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-129rl9yoX2phQ9Ro .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-129rl9yoX2phQ9Ro .cluster text{fill:#333;}#mermaid-svg-129rl9yoX2phQ9Ro .cluster span{color:#333;}#mermaid-svg-129rl9yoX2phQ9Ro div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-129rl9yoX2phQ9Ro .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-129rl9yoX2phQ9Ro rect.text{fill:none;stroke-width:0;}#mermaid-svg-129rl9yoX2phQ9Ro .icon-shape,#mermaid-svg-129rl9yoX2phQ9Ro .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-129rl9yoX2phQ9Ro .icon-shape p,#mermaid-svg-129rl9yoX2phQ9Ro .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-129rl9yoX2phQ9Ro .icon-shape .label rect,#mermaid-svg-129rl9yoX2phQ9Ro .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-129rl9yoX2phQ9Ro .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-129rl9yoX2phQ9Ro .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-129rl9yoX2phQ9Ro :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} ReplicaSet Controller
Deployment Controller
输入
Deployment
replicas: 3
template: nginx:1.21
Reconcile Deployment
列出关联 ReplicaSet
(按 revision 排序)
新建/更新 ReplicaSet
replicas: 3
缩容旧 ReplicaSet
replicas: 0
滚动更新控制
maxSurge/maxUnavailable
Reconcile ReplicaSet
计算 Pod 数量
创建 Pod
(不足时)
删除 Pod
(多余时)
源码路径:
- Deployment Controller:
pkg/controller/deployment/deployment_controller.go - ReplicaSet Controller:
pkg/controller/replicaset/replica_set.go - 滚动更新逻辑:
pkg/controller/deployment/rolling.go
十六、Leader Election 高可用模式
Kubernetes 控制平面组件(Controller Manager、Scheduler)支持多副本部署,通过 Leader Election 确保同一时刻只有一个实例运行:
Etcd API Server Controller Manager 实例 2 Controller Manager 实例 1 Etcd API Server Controller Manager 实例 2 Controller Manager 实例 1 #mermaid-svg-12bJtIRS9mDeJTEN{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-12bJtIRS9mDeJTEN .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-12bJtIRS9mDeJTEN .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-12bJtIRS9mDeJTEN .error-icon{fill:#552222;}#mermaid-svg-12bJtIRS9mDeJTEN .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-12bJtIRS9mDeJTEN .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-12bJtIRS9mDeJTEN .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-12bJtIRS9mDeJTEN .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-12bJtIRS9mDeJTEN .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-12bJtIRS9mDeJTEN .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-12bJtIRS9mDeJTEN .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-12bJtIRS9mDeJTEN .marker{fill:#333333;stroke:#333333;}#mermaid-svg-12bJtIRS9mDeJTEN .marker.cross{stroke:#333333;}#mermaid-svg-12bJtIRS9mDeJTEN svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-12bJtIRS9mDeJTEN p{margin:0;}#mermaid-svg-12bJtIRS9mDeJTEN .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-12bJtIRS9mDeJTEN text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-12bJtIRS9mDeJTEN .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-12bJtIRS9mDeJTEN .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-12bJtIRS9mDeJTEN .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-12bJtIRS9mDeJTEN .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-12bJtIRS9mDeJTEN #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-12bJtIRS9mDeJTEN .sequenceNumber{fill:white;}#mermaid-svg-12bJtIRS9mDeJTEN #sequencenumber{fill:#333;}#mermaid-svg-12bJtIRS9mDeJTEN #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-12bJtIRS9mDeJTEN .messageText{fill:#333;stroke:none;}#mermaid-svg-12bJtIRS9mDeJTEN .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-12bJtIRS9mDeJTEN .labelText,#mermaid-svg-12bJtIRS9mDeJTEN .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-12bJtIRS9mDeJTEN .loopText,#mermaid-svg-12bJtIRS9mDeJTEN .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-12bJtIRS9mDeJTEN .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-12bJtIRS9mDeJTEN .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-12bJtIRS9mDeJTEN .noteText,#mermaid-svg-12bJtIRS9mDeJTEN .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-12bJtIRS9mDeJTEN .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-12bJtIRS9mDeJTEN .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-12bJtIRS9mDeJTEN .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-12bJtIRS9mDeJTEN .actorPopupMenu{position:absolute;}#mermaid-svg-12bJtIRS9mDeJTEN .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-12bJtIRS9mDeJTEN .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-12bJtIRS9mDeJTEN .actor-man circle,#mermaid-svg-12bJtIRS9mDeJTEN line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-12bJtIRS9mDeJTEN :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 启动阶段 - 竞选 Leader CM1 成为 Leader 开始运行控制器 Follower - 等待 发现已有 Leader 进入等待模式 loop 定期检查 Leader 故障 CM1 崩溃 停止续约 Leader 已失活 CM2 成为新 Leader 开始运行控制器 Create Lease kube-controller-manager holderIdentity: "cm-1" 存储 Lease Update Lease renewTime: now transitions: 0 更新 Lease Get Lease kube-controller-manager holderIdentity: "cm-1" renewTime: recent Get Lease renewTime: recent (Leader 仍活跃) Get Lease renewTime: expired (超过 leaseDurationSeconds) Update Lease holderIdentity: "cm-2" renewTime: now transitions: 1 更新 Lease
Leader Election 源码
| 组件 | 源码位置 | 机制 |
|---|---|---|
| Controller Manager | cmd/kube-controller-manager/app/controllermanager.go |
Lease-based Election |
| Scheduler | cmd/kube-scheduler/app/server.go |
Lease-based Election |
| 通用实现 | staging/src/k8s.io/client-go/tools/leaderelection/ |
LeaderElector 结构体 |
| Lease CRD | staging/src/k8s.io/api/coordination/v1/ |
Lease API 对象 |
选举参数:
| 参数 | 默认值 | 说明 |
|---|---|---|
| leaseDuration | 15s | Leader 租约有效期 |
| renewDeadline | 10s | Leader 续约超时时间 |
| retryPeriod | 2s | Follower 重试间隔 |
十七、核心设计模式汇总
17.1 设计模式全景图
#mermaid-svg-H65OqmQvBQS0qzjD{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-H65OqmQvBQS0qzjD .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-H65OqmQvBQS0qzjD .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-H65OqmQvBQS0qzjD .error-icon{fill:#552222;}#mermaid-svg-H65OqmQvBQS0qzjD .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-H65OqmQvBQS0qzjD .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-H65OqmQvBQS0qzjD .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-H65OqmQvBQS0qzjD .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-H65OqmQvBQS0qzjD .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-H65OqmQvBQS0qzjD .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-H65OqmQvBQS0qzjD .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-H65OqmQvBQS0qzjD .marker{fill:#333333;stroke:#333333;}#mermaid-svg-H65OqmQvBQS0qzjD .marker.cross{stroke:#333333;}#mermaid-svg-H65OqmQvBQS0qzjD svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-H65OqmQvBQS0qzjD p{margin:0;}#mermaid-svg-H65OqmQvBQS0qzjD .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-H65OqmQvBQS0qzjD .cluster-label text{fill:#333;}#mermaid-svg-H65OqmQvBQS0qzjD .cluster-label span{color:#333;}#mermaid-svg-H65OqmQvBQS0qzjD .cluster-label span p{background-color:transparent;}#mermaid-svg-H65OqmQvBQS0qzjD .label text,#mermaid-svg-H65OqmQvBQS0qzjD span{fill:#333;color:#333;}#mermaid-svg-H65OqmQvBQS0qzjD .node rect,#mermaid-svg-H65OqmQvBQS0qzjD .node circle,#mermaid-svg-H65OqmQvBQS0qzjD .node ellipse,#mermaid-svg-H65OqmQvBQS0qzjD .node polygon,#mermaid-svg-H65OqmQvBQS0qzjD .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-H65OqmQvBQS0qzjD .rough-node .label text,#mermaid-svg-H65OqmQvBQS0qzjD .node .label text,#mermaid-svg-H65OqmQvBQS0qzjD .image-shape .label,#mermaid-svg-H65OqmQvBQS0qzjD .icon-shape .label{text-anchor:middle;}#mermaid-svg-H65OqmQvBQS0qzjD .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-H65OqmQvBQS0qzjD .rough-node .label,#mermaid-svg-H65OqmQvBQS0qzjD .node .label,#mermaid-svg-H65OqmQvBQS0qzjD .image-shape .label,#mermaid-svg-H65OqmQvBQS0qzjD .icon-shape .label{text-align:center;}#mermaid-svg-H65OqmQvBQS0qzjD .node.clickable{cursor:pointer;}#mermaid-svg-H65OqmQvBQS0qzjD .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-H65OqmQvBQS0qzjD .arrowheadPath{fill:#333333;}#mermaid-svg-H65OqmQvBQS0qzjD .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-H65OqmQvBQS0qzjD .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-H65OqmQvBQS0qzjD .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-H65OqmQvBQS0qzjD .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-H65OqmQvBQS0qzjD .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-H65OqmQvBQS0qzjD .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-H65OqmQvBQS0qzjD .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-H65OqmQvBQS0qzjD .cluster text{fill:#333;}#mermaid-svg-H65OqmQvBQS0qzjD .cluster span{color:#333;}#mermaid-svg-H65OqmQvBQS0qzjD div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-H65OqmQvBQS0qzjD .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-H65OqmQvBQS0qzjD rect.text{fill:none;stroke-width:0;}#mermaid-svg-H65OqmQvBQS0qzjD .icon-shape,#mermaid-svg-H65OqmQvBQS0qzjD .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-H65OqmQvBQS0qzjD .icon-shape p,#mermaid-svg-H65OqmQvBQS0qzjD .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-H65OqmQvBQS0qzjD .icon-shape .label rect,#mermaid-svg-H65OqmQvBQS0qzjD .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-H65OqmQvBQS0qzjD .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-H65OqmQvBQS0qzjD .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-H65OqmQvBQS0qzjD :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Kubernetes 核心设计模式
网络模式
CNI Plugin
网络可插拔
Service VIP
ClusterIP 虚拟 IP
EndpointSlice
端点分片
存储模式
Etcd Backend
单一存储后端
Storage Abstraction
REST Storage 接口
Watch Propagation
三级 Watch 链路
扩展性模式
Plugin Interface
接口 + 注册
CRD + Operator
自定义资源 + 控制器
Webhook
HTTP 回调扩展
Adapter Pattern
外部系统适配
控制器模式
Reconcile Loop
期望 vs 实际
Informer/Cache
本地缓存 + Watch
Work Queue
去重 + 限流 + 重试
Leader Election
主备切换
API 层模式
声明式 API
Spec + Status
Level-driven
而非 Edge-driven
API Versioning
Alpha → Beta → GA
17.2 关键模式详解
Level-driven vs Edge-driven
Kubernetes 采用 Level-driven(电平驱动)模式,而非 Edge-driven(边沿驱动):
- Edge-driven:只在状态变化时触发一次操作,如果操作失败,不会自动重试
- Level-driven:持续检查当前状态(Level),只要当前状态与期望不一致,就持续驱动变更
这通过 Informer 的 Resync 机制实现:即使没有新事件,定期 Resync 也会将所有对象重新入队,确保最终一致性。
Work Queue 三层保障
源码:staging/src/k8s.io/client-go/util/workqueue/
- 去重(Deduplication):同一 Key 多次入队只保留一个,避免重复处理
- 限流(RateLimiting):处理失败后指数退避重试,避免错误风暴
- 延迟入队(AddAfter):支持延迟重入队,实现退避策略
Storage 抽象层次
API Layer (REST Handler)
↓
Registry (资源路由 → Storage 映射)
↓
Strategy (创建/更新/删除策略)
↓
Codec (JSON/Protobuf 编解码)
↓
Storage Interface (Create/Get/List/Watch/Update/Delete)
↓
Etcd Store (gRPC 实现)
↓
Etcd Cluster (Raft 共识)
十八、架构优势与设计原则
18.1 架构优势
| 优势 | 实现方式 | 核心收益 |
|---|---|---|
| 声明式 API | Spec/Status 分离 + Reconcile Loop | 用户只需声明期望,系统自动达成 |
| 最终一致性 | Informer + WorkQueue + Resync | 网络分区恢复后自动修复状态 |
| 高度可扩展 | CRD + Webhook + Plugin Interface | 无需修改核心代码即可扩展功能 |
| 松耦合 | API Server 作为唯一通信总线 | 组件可独立升级/替换 |
| 自愈能力 | 控制器持续 Reconcile | Pod 故障自动重建、节点异常自动标记 |
| 高可用 | Leader Election + 多副本 | 控制平面组件故障自动切换 |
| 多租户 | Namespace + RBAC + ResourceQuota | 命名空间级隔离 + 权限控制 + 配额限制 |
18.2 核心设计原则
- Keep the core simple:核心只做编排调度,复杂功能通过扩展实现(CSI/CNI/CRI)
- API Server is the source of truth:所有状态必须通过 API Server,Etcd 是唯一持久化后端
- Controllers are level-driven:持续 Reconcile,不依赖单次事件触发
- No direct component-to-component communication:组件间不直接通信,避免耦合
- Fail-open, not fail-closed:系统优先保证可用性,允许短暂不一致
- Extensibility by default:所有功能模块预留扩展接口
- Immutable infrastructure:Pod 不被修改,只被替换(重建)
18.3 架构演进趋势
| 方向 | 当前状态 | 演进中 |
|---|---|---|
| API Server | 单体 API Server + 聚合层 | API 聚合 + CRD 分片 |
| 调度器 | 单调度器 + Framework 插件 | 多调度器 + Coscheduling |
| 网络 | kube-proxy iptables/IPVS | eBPF 替代 kube-proxy (Cilium) |
| 运行时 | Docker + containerd | containerd-only + Kata (安全容器) |
| 存储 | FlexVolume → CSI | CSI only + 快照/克隆 |
| 安全 | RBAC + PodSecurityPolicy | RBAC + PodSecurity Standards |
| 可观测性 | Metrics Server + cAdvisor | OpenTelemetry 集成 |
附录:源码快速参考
核心入口文件
| 组件 | 入口文件 | 核心实现目录 |
|---|---|---|
| kube-apiserver | cmd/kube-apiserver/app/server.go |
pkg/kubeapiserver/ + pkg/registry/ |
| kube-controller-manager | cmd/kube-controller-manager/app/controllermanager.go |
pkg/controller/ |
| kube-scheduler | cmd/kube-scheduler/app/server.go |
pkg/scheduler/ |
| kubelet | cmd/kubelet/app/server.go |
pkg/kubelet/ |
| kube-proxy | cmd/kube-proxy/app/server.go |
pkg/proxy/ |
| kubectl | cmd/kubectl/kubectl.go |
pkg/kubectl/ |
| cloud-controller-manager | cmd/cloud-controller-manager/main.go |
pkg/cloudprovider/ |
API 类型定义
| 资源组 | 源码位置 |
|---|---|
| Core (Pod/Service/Node) | pkg/apis/core/ |
| Apps (Deployment/StatefulSet/DaemonSet) | pkg/apis/apps/ |
| Batch (Job/CronJob) | pkg/apis/batch/ |
| Networking (Ingress/NetworkPolicy) | pkg/apis/networking/ |
| RBAC (Role/RoleBinding) | pkg/apis/rbac/ |
| Storage (PV/PVC/StorageClass) | pkg/apis/storage/ |
| Admission (Webhook配置) | pkg/apis/admissionregistration/ |
关键接口
| 接口 | 源码位置 | 用途 |
|---|---|---|
runtimeapi.RuntimeService |
staging/src/k8s.io/cri-api/ |
CRI 容器运行时接口 |
framework.Plugin |
pkg/scheduler/framework/interface.go |
调度框架插件接口 |
cloudprovider.Interface |
pkg/cloudprovider/ |
云平台接口 |
volume.VolumePlugin |
pkg/volume/plugins.go |
存储卷插件接口 |
admission.Validation/Mutation |
staging/src/k8s.io/apiserver/pkg/admission/ |
准入控制插件接口 |
store.Interface |
staging/src/k8s.io/apiserver/pkg/storage/ |
存储后端接口 |