大家好,我是刘叨叨,一个致力于让碎片化技术系统性的运维人。
在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的什么问题?
- 证书问题:证书过期导致集群不可用?
- 性能问题:etcd磁盘IO瓶颈?
- 配置问题:RBAC权限配置错误?
欢迎留言分享你的"踩坑"经历,一起避坑!
下一篇预告:控制平面还有两位重要成员------Scheduler(调度器)和Controller Manager(控制器管理器)。它们是集群的"调度中心"和"纠错系统",下一篇我们将深入探讨它们如何让Pod去该去的地方,并确保一切按计划运行。
关注【刘叨叨趣味运维】,用有趣的方式,啃下最硬核的技术。咱们下期见!