解剖K8s控制平面(上):API Server与etcd如何成为集群的“大脑“与“记忆“?

大家好,我是刘叨叨,一个致力于让碎片化技术系统性的运维人。

在Kubernetes的分布式架构中,控制平面的核心可归结为两个关键组件:API Server 作为系统的唯一交互端点与网关etcd 作为集群的一致性状态存储引擎。它们是所有集群操作与状态管理的源头与终点。

掌握这两者,就掌握了理解K8s如何协调工作的钥匙。

组件定位:集群的"外交官"与"数据库"

API Server:集群的唯一入口

就像公司的前台,所有访客必须先经过这里

核心特点

复制代码
📍 唯一入口:所有请求(人/机器)都必须通过它
📍 无状态设计:可以水平扩展,部署多个副本
📍 RESTful接口:使用标准的HTTP方法(GET/POST/PUT/DELETE)

etcd:集群的状态存储器

就像公司的档案库,所有重要文件都存放在这里

核心特点

复制代码
📍 分布式键值存储:数据分散在多个节点
📍 强一致性:所有节点看到的数据完全一致
📍 高可用性:部分节点挂掉,服务依然正常

API Server:不只是个"传话筒"

三大核心功能

1. 认证(Authentication)------ "你是谁?"

复制代码
支持的认证方式:
┌─────────┬─────────────────────────────┐
│ 方式     │ 适用场景                    │
├─────────┼─────────────────────────────┤
│ X509证书 │ kubectl、kubelet等长期连接  │
│ 令牌     │ ServiceAccount、Dashboard   │
│ 基础认证 │ 简单测试环境(不推荐生产)   │
└─────────┴─────────────────────────────┘

2. 授权(Authorization)------ "你能做什么?"

复制代码
# RBAC配置示例:允许开发组查看Pod
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-viewer
rules:
- apiGroups: [""]
  resources: ["pods"]      # 资源类型:Pod
  verbs: ["get", "list"]   # 允许的操作:查看

3. 准入控制(Admission Control)------ "我帮你检查/修改一下"

复制代码
准入控制链示例:
请求 → 验证 → 修改 → 审计 → 持久化
常见准入控制器:
✅ ValidatingWebhook:验证资源是否合法
✅ MutatingWebhook:修改资源内容(如添加sidecar)
✅ ResourceQuota:检查是否超出配额

实际工作流程

复制代码
# 当你执行这个命令时:
kubectl get pods
# API Server内部处理:
1. 接收HTTP GET请求 → /api/v1/namespaces/default/pods
2. 验证证书(你是谁?)
3. 检查RBAC权限(允许查看Pod吗?)
4. 从etcd读取Pod数据
5. 返回JSON/YAML格式的响应

etcd:不只是个"记事本"

数据结构:如何组织海量数据?

键的设计模式

复制代码
# etcd的键路径就像文件系统
/registry/pods/default/myapp-pod     # Pod信息
/registry/services/default/myapp-svc  # Service信息  
/registry/nodes/node-01               # 节点信息
/registry/configmaps/default/config   # 配置信息
# 通用格式:
/registry/{资源类型}/{命名空间}/{资源名称}

值的内容示例(Pod的JSON表示):

复制代码
{
  "apiVersion": "v1",
  "kind": "Pod",
  "metadata": {
    "name": "myapp-pod",
    "namespace": "default",
    "uid": "123e4567-e89b-12d3-a456-426614174000"
  },
  "spec": {
    "containers": [{
      "name": "nginx",
      "image": "nginx:1.20"
    }]
  },
  "status": {
    "phase": "Running",
    "podIP": "10.244.1.3"
  }
}

为什么etcd如此重要?

1. 集群的"唯一真相源"

复制代码
所有组件都相信etcd中的数据
├── API Server从etcd读写
├── Controller比较etcd中的期望状态
├── Scheduler查看etcd中的节点信息
└── kubelet上报状态到etcd

2. Watch机制:实时通知

复制代码
// 伪代码:Controller如何监听资源变化
client.Watch("/registry/pods/default", func(event) {
    switch event.Type {
    case "PUT":    // 创建/更新
        reconcile(event.Key, event.Value)
    case "DELETE": // 删除
        cleanup(event.Key)
    }
})

3. 租约(Lease)机制

复制代码
# 节点健康检查示例
1. kubelet每10秒:续租一次("我还活着!")
2. 如果etcd 40秒没收到续租 → 认为节点失联
3. 标记节点为NotReady,重新调度其上的Pod

API Server + etcd:黄金搭档如何工作?

场景:创建一个简单的Pod

复制代码
# 用户提交的YAML
apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  containers:
  - name: busybox
    image: busybox
    command: ["sleep", "3600"]

协作流程

复制代码
👤 用户执行 kubectl apply -f pod.yaml
    ↓
🚪 API Server接收请求
    ├── 认证:验证客户端证书
    ├── 授权:检查create pod权限  
    └── 准入:运行准入控制器链
    ↓
💾 写入etcd(此时Pod的nodeName为空)
    ├── 键:/registry/pods/default/test-pod
    └── 值:完整的Pod定义JSON
    ↓
📡 通知所有监听者
    ├── Scheduler:"有新Pod需要调度!"
    ├── Controller Manager:"有个Pod创建了"
    └── kubelet(暂无,因为未指定节点)
    ↓
✅ 返回给用户:pod/test-pod created

关键特性:版本控制与乐观锁

每个资源都有版本号

复制代码
# 获取资源时包含resourceVersion
kubectl get pod test-pod -o yaml
# metadata.resourceVersion: "123456"
# 更新时携带这个版本号
# 如果期间有人修改了资源,更新会失败
# 避免"丢失更新"问题

生产环境实战要点

高可用部署模式

API Server

复制代码
# 部署多个副本,前面加负载均衡器
┌─────────────────┐
│   Load Balancer  │
├─────┬─────┬─────┤
│ API │ API │ API │ ← 3个无状态副本
└─────┴─────┴─────┘
# 任何副本都能处理请求

etcd集群

复制代码
# 典型3节点集群(容忍1个节点故障)
节点1: etcd --name=etcd1 --initial-cluster-state=new
节点2: etcd --name=etcd2 --initial-cluster-state=new  
节点3: etcd --name=etcd3 --initial-cluster-state=new
# 数据复制机制:
写入 → 主节点 → 同步到从节点 → 多数确认 → 提交

互动讨论

在实际工作中,你遇到过API Server或etcd的什么问题?

  1. 证书问题:证书过期导致集群不可用?
  2. 性能问题:etcd磁盘IO瓶颈?
  3. 配置问题:RBAC权限配置错误?

欢迎留言分享你的"踩坑"经历,一起避坑!


下一篇预告:控制平面还有两位重要成员------Scheduler(调度器)Controller Manager(控制器管理器)。它们是集群的"调度中心"和"纠错系统",下一篇我们将深入探讨它们如何让Pod去该去的地方,并确保一切按计划运行。

关注【刘叨叨趣味运维】,用有趣的方式,啃下最硬核的技术。咱们下期见!

相关推荐
-dcr9 小时前
56.kubernetes弹性伸缩
云原生·容器·kubernetes
Hui Baby9 小时前
K8S联邦负载
java·容器·kubernetes
qq_312920119 小时前
K8s Ingress实战:七层负载均衡流量治理
容器·kubernetes·负载均衡
海鸥819 小时前
k8s中Jenkins 配置文件「 更新不了 」
java·kubernetes·jenkins
Cyber4K9 小时前
【Kubernetes专项】K8s 常见持久化存储方案及存储类动态 PV
云原生·容器·kubernetes
噎住佩奇21 小时前
k8s-配置管理
云原生·容器·kubernetes
程序媛Dev1 天前
K8s 太重、虚拟机太旧,Sealos 找到了基础架构的最优解
云原生·容器·kubernetes
索荣荣1 天前
Java定时任务与Kubernetes CronJob、AWS EventBridge的集成方案指南
java·开发语言·kubernetes·aws
回忆是昨天里的海1 天前
k8s-部署spring cloud微服务
spring cloud·微服务·kubernetes