主题
05 — 集群架构与控制平面深度教材
控制平面是 K8s 的大脑。深入理解 apiserver 请求流、调度器框架、控制器模式是高级运维面试的核心考点。
1. kube-apiserver 请求处理流程
请求进入 apiserver 后的完整链路:
HTTP Request
│
▼
┌──────────────────┐
│ Authentication │ 认证:谁在请求?
│ (X509/Bearer/ │ - 客户端证书
│ OIDC/Webhook) │ - Bearer Token
└────────┬─────────┘ - OIDC
▼
┌──────────────────┐
│ Authorization │ 授权:能做什么?
│ (RBAC/ABAC/ │ - RBAC(最常用)
│ Node/Webhook) │ - Node 授权器
└────────┬─────────┘
▼
┌──────────────────┐
│ Mutating Admission│ 准入:修改请求
│ (Webhook Chain) │ - 注入 sidecar
└────────┬─────────┘ - 添加默认值
▼
┌──────────────────┐
│ Schema Validation │ 格式校验
│ (OpenAPI Schema) │ - 字段类型/必填项
└────────┬─────────┘
▼
┌──────────────────┐
│ Validating Admission│ 准入:业务校验
│ (Webhook Chain) │ - 自定义规则
└────────┬────────────┘
▼
┌──────────────────┐
│ etcd Write │ 持久化
└────────┬─────────┘
▼
┌──────────────────┐
│ Watch Event │ 通知 Informer
│ (Notify Controllers)│
└──────────────────┘1.1 apiserver 高可用
bash
# HA 架构要点:
# 1. 至少 3 个 apiserver 实例
# 2. 前置负载均衡器(keepalived/HAProxy/云 LB)
# 3. 所有 apiserver 连接同一个 etcd 集群
# 4. kubelet 通过 LB VIP 访问 apiserver
# 查看 apiserver 状态
kubectl get --raw /healthz
kubectl get --raw /livez
kubectl get --raw /readyz
# 查看 apiserver 审计日志
journalctl -u kube-apiserver --since "1 hour ago" | grep -i audit2. kube-scheduler 调度框架
2.1 调度流程
调度器核心流程:
Pending Pod
│
▼
┌──────────────────┐
│ PreFilter │ 预过滤(检查 Pod 是否可调度)
└────────┬─────────┘
▼
┌──────────────────┐
│ Filter │ 过滤(排除不满足条件的 Node)
│ - NodeResources │ - 资源是否足够
│ - NodeSelector │ - nodeSelector 匹配
│ - Taint/Toleration│ - 污点容忍
│ - NodeAffinity │ - 节点亲和性
│ - PodTopologySpread│ - 拓扑分布
└────────┬─────────┘
▼
┌──────────────────┐
│ Score │ 打分(对满足条件的 Node 排序)
│ - LeastRequested │ - 资源使用率最低
│ - BalancedResource│ - 资源均衡
│ - InterPodAffinity│ - Pod 亲和性
└────────┬─────────┘
▼
┌──────────────────┐
│ Reserve/Bind │ 预留资源 + 绑定到 Node
└──────────────────┘2.2 调度器扩展
bash
# 自定义调度器(Scheduler Extender)
# 通过 HTTP webhook 扩展 Filter/Score 阶段
# 调度器配置文件(KubeSchedulerConfiguration)
apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
- schedulerName: default-scheduler
plugins:
score:
enabled:
- name: NodeResourcesFit
weight: 1
- name: InterPodAffinity
weight: 2
# 查看调度决策
kubectl get events --field-selector reason=Scheduled
kubectl describe pod <name> | grep -A5 Events3. Controller Manager 控制器模式
3.1 核心控制器
| 控制器 | 职责 | 触发条件 |
|---|---|---|
| Deployment Controller | 管理 ReplicaSet 滚动更新 | Deployment spec 变更 |
| ReplicaSet Controller | 维持 Pod 副本数 | Pod 创建/删除 |
| Node Controller | 监控节点状态 | 节点心跳超时 |
| Endpoint Controller | 维护 Service Endpoints | Pod Ready 状态变化 |
| ServiceAccount Controller | 为 Namespace 创建默认 SA | Namespace 创建 |
| Namespace Controller | 处理 Namespace 删除 | Namespace terminating |
3.2 Reconciliation Loop(调谐循环)
所有 K8s 控制器的核心模式:
Watch(监听 etcd 变更)
│
▼
Diff(比较期望状态与实际状态)
│
▼
Act(执行动作使实际状态趋近期望状态)
│
▼
Update Status(更新资源状态)
│
▼
回到 Watch(Level-triggered,不关心事件序列)
关键特性:
- Level-triggered:即使错过某些事件,下次调谐仍能自愈
- 幂等性:多次执行结果一致
- 最终一致性:不保证实时,但保证最终一致3.3 Leader Election(领导者选举)
bash
# 控制面组件使用 Lease 对象进行 leader election
kubectl get lease -n kube-system
# NAME HOLDER AGE
# kube-controller-manager node1_xxx 30d
# kube-scheduler node2_xxx 30d
# 查看当前 leader
kubectl get lease kube-controller-manager -n kube-system -o yaml | grep holderIdentity
# Leader 故障切换时间
# 默认 leaseDuration=15s, renewDeadline=10s, retryPeriod=2s
# 故障检测时间 ≈ leaseDuration = 15 秒4. 控制面高可用架构
推荐 HA 架构:
┌─────────────────────────────────────────────────┐
│ Load Balancer (VIP) │
│ keepalived / HAProxy / 云 LB │
└──────┬──────────────┬──────────────┬────────────┘
│ │ │
┌────▼────┐ ┌────▼────┐ ┌────▼────┐
│apiserver│ │apiserver│ │apiserver│
│ (etcd) │ │ (etcd) │ │ (etcd) │
└─────────┘ └─────────┘ └─────────┘
│ │ │
┌────▼────┐ ┌────▼────┐ ┌────▼────┐
│ etcd │ │ etcd │ │ etcd │
│ (Raft) │ │ (Raft) │ │ (Raft) │
└─────────┘ └─────────┘ └─────────┘
关键配置:
- apiserver --etcd-servers 指向所有 etcd 节点
- kubelet --kubeconfig 指向 LB VIP
- etcd 集群至少 3 节点(容忍 1 节点故障)5. 面试高频问题
Q: kubectl apply 到 Pod Running 的完整流程?
1. kubectl 将 YAML 序列化为 JSON,发送 HTTPS 请求到 apiserver
2. apiserver:认证 → 授权 → Mutating Admission → 校验 → Validating Admission
3. apiserver 将资源写入 etcd
4. Deployment Controller Watch 到变更,创建 ReplicaSet
5. ReplicaSet Controller 创建 Pod 对象写入 etcd
6. Scheduler Watch 到 Pending Pod,执行调度算法选择 Node
7. kubelet Watch 到有 nodeName 的 Pod,通过 CRI 创建容器
8. kubelet 上报 Pod 状态,状态变为 Running
9. Endpoint Controller 将 Pod 加入 Service EndpointsQ: apiserver 挂了会怎样?
影响:
- 无法创建/修改/删除任何资源
- 已运行的 Pod 不受影响(继续运行)
- kubelet 无法上报状态(节点可能标记 NotReady)
- 新的调度无法进行
恢复:
- HA 架构:其他 apiserver 自动接管
- 单点:重启 apiserver,检查 etcd 连接