kube-apiserver 深度解析:集群的统一入口

kube-apiserver 深度解析:集群的统一入口

1. 核心定位

kube-apiserver 是 Kubernetes 控制平面的唯一入口,所有组件(kubelet、controller-manager、scheduler、kubectl)都通过 apiserver 与集群交互,没有任何组件直接访问 etcd。

1
2
3
4
5
6
7
kubectl / 外部客户端


kube-apiserver ←→ etcd


kubelet / scheduler / controller-manager / 自定义控制器

2. 核心职责

职责 说明
REST API 网关 提供标准 RESTful API,管理所有资源对象
认证(Authentication) 验证请求者身份
授权(Authorization) 验证请求者权限
准入控制(Admission) 对象创建/修改前的校验与变更
数据持久化 序列化对象并存储到 etcd
Watch 代理 缓存 etcd Watch 事件,分发给各控制器
API 聚合 支持扩展 API(Aggregation Layer)

3. 请求处理完整链路

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
HTTP Request


┌─────────────────────────────────────────────────────┐
1. TLS 终止(HTTPS) │
├─────────────────────────────────────────────────────┤
2. 认证(Authentication) │
│ X.509 证书 / Bearer Token / OIDC / Webhook │
├─────────────────────────────────────────────────────┤
3. 授权(Authorization) │
│ RBAC / ABAC / Node / Webhook │
├─────────────────────────────────────────────────────┤
4. 准入控制(Admission Control) │
│ MutatingWebhook → ValidatingWebhook │
├─────────────────────────────────────────────────────┤
5. 对象校验(Validation) │
│ Schema 校验 / 字段验证 │
├─────────────────────────────────────────────────────┤
6. 序列化 & 持久化到 etcd │
├─────────────────────────────────────────────────────┤
7. 返回响应 │
└─────────────────────────────────────────────────────┘

4. 认证机制(Authentication)

apiserver 支持多种认证方式,任意一种通过即认证成功

4.1 X.509 客户端证书

最常用的认证方式,kubectl 默认使用:

1
2
3
4
5
6
# ~/.kube/config
users:
- name: admin
user:
client-certificate: /etc/kubernetes/pki/admin.crt
client-key: /etc/kubernetes/pki/admin.key

证书中的 CN 字段作为用户名,O 字段作为用户组:

1
2
3
# 查看证书信息
openssl x509 -in admin.crt -noout -subject
# subject=CN=kubernetes-admin, O=system:masters

4.2 ServiceAccount Token

Pod 内部访问 apiserver 使用 ServiceAccount Token(JWT):

1
2
3
4
5
6
7
8
9
10
# Pod 内自动挂载的 token
cat /var/run/secrets/kubernetes.io/serviceaccount/token

# token 结构(JWT)
Header.Payload.Signature
# Payload 包含:
# - iss: kubernetes/serviceaccount
# - sub: system:serviceaccount:default:my-sa
# - namespace: default
# - name: my-sa

4.3 OIDC(OpenID Connect)

对接外部身份提供商(Dex、Keycloak、AWS Cognito 等):

1
2
3
4
5
# apiserver 启动参数
--oidc-issuer-url=https://accounts.google.com
--oidc-client-id=kubernetes
--oidc-username-claim=email
--oidc-groups-claim=groups

4.4 Webhook Token 认证

1
--authentication-token-webhook-config-file=/etc/kubernetes/webhook-authn.yaml

5. 授权机制(Authorization)

5.1 RBAC(Role-Based Access Control)

Kubernetes 最主流的授权方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# Role:命名空间级别权限
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]

---
# RoleBinding:将 Role 绑定到用户
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: default
subjects:
- kind: User
name: jane
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
1
2
3
4
5
6
7
8
9
# ClusterRole:集群级别权限
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: node-reader
rules:
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "list", "watch"]

5.2 Node 授权

专门为 kubelet 设计,限制 kubelet 只能访问其所在节点的资源:

1
system:node:<nodeName>  →  只能读写本节点的 Pod、Secret、ConfigMap

5.3 授权决策流程

1
2
3
4
5
6
请求 → 遍历所有授权器

├── RBAC 允许? → 允许
├── Node 允许? → 允许
├── Webhook 允许? → 允许
└── 全部拒绝 → 403 Forbidden

6. 准入控制(Admission Control)

准入控制器在对象持久化前对其进行拦截、修改或拒绝

6.1 两个阶段

1
2
3
4
5
6
7
8
9
10
请求


MutatingAdmissionWebhook(变更)
│ 可以修改对象(注入 sidecar、设置默认值等)

ValidatingAdmissionWebhook(验证)
│ 只能允许或拒绝,不能修改

持久化到 etcd

6.2 内置准入控制器

1
2
3
4
5
6
7
8
9
10
11
# 查看启用的准入控制器
kube-apiserver --enable-admission-plugins=\
NamespaceLifecycle,\
LimitRanger,\
ServiceAccount,\
DefaultStorageClass,\
DefaultTolerationSeconds,\
MutatingAdmissionWebhook,\
ValidatingAdmissionWebhook,\
ResourceQuota,\
NodeRestriction
控制器 作用
NamespaceLifecycle 防止在终止中的 Namespace 创建资源
LimitRanger 为 Pod 设置默认资源限制
ServiceAccount 自动挂载 ServiceAccount Token
ResourceQuota 强制执行资源配额
NodeRestriction 限制 kubelet 只能修改自身节点
PodSecurity 强制执行 Pod 安全标准

6.3 自定义 Webhook 示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
apiVersion: admissionregistration.k8s.io/v1
kind: MutatingWebhookConfiguration
metadata:
name: sidecar-injector
webhooks:
- name: sidecar.example.com
clientConfig:
service:
name: sidecar-injector
namespace: default
path: "/inject"
rules:
- operations: ["CREATE"]
apiGroups: [""]
apiVersions: ["v1"]
resources: ["pods"]
admissionReviewVersions: ["v1"]
sideEffects: None

7. API 资源模型

7.1 API 分组

1
2
3
4
5
6
7
8
核心 API(/api/v1):Pod, Service, ConfigMap, Secret, Node...
扩展 API(/apis):
apps/v1:Deployment, StatefulSet, DaemonSet...
batch/v1:Job, CronJob
networking.k8s.io/v1:Ingress, NetworkPolicy
rbac.authorization.k8s.io/v1:Role, ClusterRole...
storage.k8s.io/v1:StorageClass, PV, PVC
自定义(CRD):任意扩展资源

7.2 API 版本演进

1
Alpha(v1alpha1)→ Beta(v1beta1)→ Stable(v1)

7.3 资源操作动词

1
2
3
4
5
6
7
GET    /api/v1/namespaces/default/pods          → list
GET /api/v1/namespaces/default/pods/nginx → get
POST /api/v1/namespaces/default/pods → create
PUT /api/v1/namespaces/default/pods/nginx → update
PATCH /api/v1/namespaces/default/pods/nginx → patch
DELETE /api/v1/namespaces/default/pods/nginx → delete
GET /api/v1/namespaces/default/pods?watch=1 → watch

8. Watch Cache(List-Watch 缓存)

apiserver 在内存中维护一个 Watch Cache,避免所有控制器直接 Watch etcd:

1
2
3
4
5
6
etcd ──Watch──▶ apiserver Watch Cache(内存环形缓冲区)

├──▶ controller-manager
├──▶ scheduler
├──▶ kubelet
└──▶ 自定义控制器
1
2
# 调整 Watch Cache 大小
--watch-cache-sizes=pods#1000,nodes#100

9. API 聚合层(Aggregation Layer)

允许将自定义 API Server 注册到 kube-apiserver:

1
2
3
4
5
6
7
8
9
10
11
12
13
apiVersion: apiregistration.k8s.io/v1
kind: APIService
metadata:
name: v1beta1.metrics.k8s.io
spec:
service:
name: metrics-server
namespace: kube-system
group: metrics.k8s.io
version: v1beta1
insecureSkipTLSVerify: true
groupPriorityMinimum: 100
versionPriority: 100

10. 高可用部署

10.1 多实例部署

1
2
3
4
5
6
7
8
9
10
11
            ┌─────────────────┐
│ Load Balancer │
└────────┬────────┘

┌──────────────┼──────────────┐
▼ ▼ ▼
apiserver-1 apiserver-2 apiserver-3
│ │ │
└──────────────┼──────────────┘

etcd

apiserver 是无状态的,可以水平扩展,多个实例同时工作。

10.2 关键启动参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
kube-apiserver \
--advertise-address=10.0.0.1 \
--etcd-servers=https://10.0.0.1:2379,https://10.0.0.2:2379 \
--service-cluster-ip-range=10.96.0.0/12 \
--service-account-issuer=https://kubernetes.default.svc \
--service-account-key-file=/etc/kubernetes/pki/sa.pub \
--service-account-signing-key-file=/etc/kubernetes/pki/sa.key \
--tls-cert-file=/etc/kubernetes/pki/apiserver.crt \
--tls-private-key-file=/etc/kubernetes/pki/apiserver.key \
--client-ca-file=/etc/kubernetes/pki/ca.crt \
--authorization-mode=Node,RBAC \
--enable-admission-plugins=NodeRestriction \
--max-requests-inflight=400 \
--max-mutating-requests-inflight=200

11. 性能优化与监控

11.1 关键监控指标

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# API 请求延迟(P99)
histogram_quantile(0.99,
rate(apiserver_request_duration_seconds_bucket[5m]))

# 请求错误率
rate(apiserver_request_total{code=~"5.."}[5m])

# etcd 请求延迟
histogram_quantile(0.99,
rate(etcd_request_duration_seconds_bucket[5m]))

# Watch 事件数
rate(apiserver_watch_events_total[5m])

# 当前 inflight 请求数
apiserver_current_inflight_requests

11.2 常见性能问题

1
2
3
4
5
6
7
# 问题:List 请求过多导致 apiserver 压力大
# 解决:使用 ResourceVersion 增量 List,避免全量 List
kubectl get pods --watch # 正确:增量 Watch
# 而不是轮询 kubectl get pods

# 问题:大量 CRD 导致 apiserver 内存增长
# 解决:合理设计 CRD,避免存储大量数据在 etcd

12. 总结

kube-apiserver 是 Kubernetes 的神经中枢:

  1. 统一入口:所有组件通过 apiserver 交互,etcd 不对外暴露
  2. 三层安全:认证 → 授权 → 准入,层层把关
  3. Watch 代理:缓存 etcd 事件,支撑大规模控制器
  4. 无状态设计:可水平扩展,天然高可用
  5. 可扩展性:CRD + Aggregation Layer 支持无限扩展

kube-apiserver 深度解析:集群的统一入口
https://k8s.chucz.asia/kube-apiserver深度解析/
作者
K8s Engineer
发布于
2026年1月5日
许可协议