APIServer 本质上就是一个特殊的 RESTful HTTPS 服务器 。从协议底层看,它接收的仍然是标准的 HTTP/1.1 或 HTTP/2 请求,但语义、认证方式、状态管理哲学与普通业务 HTTP API 差异极大。
一、APIServer 接收的请求长什么样?
1.1 一个真实的完整请求( kubectl create pod 的底层)
当你在终端执行:
kubectl run nginx --image=nginx
kubectl 实际上向 APIServer 发送了如下 HTTP 请求(简化版):
POST /api/v1/namespaces/default/pods HTTP/2
Host: 10.96.0.1:443
Authorization: Bearer eyJhbGciOiJSUzI1NiIs...
Content-Type: application/json
Accept: application/json
{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {
"name": "nginx",
"namespace": "default",
"labels": {
"run": "nginx"
}
},
"spec": {
"containers": [{
"name": "nginx",
"image": "nginx",
"resources": {}
}]
}
}
APIServer 返回:
HTTP/2 201 Created
Content-Type: application/json
{
"kind": "Pod",
"apiVersion": "v1",
"metadata": {
"name": "nginx",
"uid": "a3f5c8d2-...",
"resourceVersion": "1234567",
"creationTimestamp": "2026-05-12T11:51:00Z"
},
"spec": { ... },
"status": { "phase": "Pending" }
}
1.2 URI 的固定结构(RESTful 资源路径)
K8s API 的 URL 不是随意设计的,而是严格的资源层级:
/api/v1/namespaces/{namespace}/pods/{name}
/api/v1/namespaces/{namespace}/services/{name}
/apis/apps/v1/namespaces/{namespace}/deployments/{name}
/apis/networking.k8s.io/v1/namespaces/{namespace}/ingresses/{name}
|------------------|--------------------------------------------|
| URL 段 | 含义 |
| /api/v1 | 核心 API 组(Pod/Service/Node/Namespace 等) |
| /apis/apps/v1 | 命名 API 组(Deployment/StatefulSet/DaemonSet) |
| /namespaces/{ns} | 命名空间作用域 |
| /{resource} | 资源类型(复数小写) |
| /{name} | 具体资源实例 |
| /{name}/status | 子资源:仅更新状态(权限可独立控制) |
| /{name}/scale | 子资源:扩缩容专用端点 |
| /{name}/log | 子资源:Pod 日志(连接至 kubelet) |
| /{name}/exec | 子资源:远程执行(WebSocket 升级) |
二、与普通 HTTP API 的六大核心差异
差异 1:声明式(Declarative)vs 命令式(Imperative)
|----------|---------------------|------------------------------------------------|
| 维度 | 普通业务 HTTP API | K8s APIServer |
| 哲学 | "去做这件事"(命令) | "我要这个状态"(声明) |
| 请求语义 | POST /orders → 创建订单 | POST /pods → 声明"我想要一个 Pod" |
| 幂等性 | 通常不保证 | 绝对幂等:相同 YAML 重复 apply,结果不变 |
| 状态收敛 | 业务系统自己维护 | APIServer 只负责持久化期望状态,实际状态由 Controller 异步收敛 |
例子:
- 普通 API:POST /send-sms 执行一次就发一条短信,重复调用发多条。
- K8s API:POST /pods 如果 Pod 已存在且 spec 未变,直接返回 200/409,不会创建第二个。
差异 2:内置全局版本控制(ResourceVersion)
每个 K8s 资源都有 resourceVersion,本质是 etcd 的 MVCC 版本号:
"metadata": {
"resourceVersion": "1234567"
}
作用:
- 乐观并发控制 :PUT 请求带 If-Match: "1234567",若服务端版本已变,返回 409 Conflict,防止覆盖。
- Watch 断点续传 :客户端断开重连时携带 resourceVersion,APIServer 从该版本之后推送事件。
普通 HTTP API 通常没有 :需要自己设计 version 字段或 ETag 机制。
差异 3:Watch 机制(长轮询/流式事件)
这是 K8s API 最独特的能力,普通 HTTP API 极少需要:
GET /api/v1/namespaces/default/pods?watch=1&resourceVersion=1234567 HTTP/1.1
Accept: application/json
返回不是一次性 JSON,而是持续的 Chunked Transfer 流:
{"type":"ADDED", "object":{...}}
{"type":"MODIFIED", "object":{...}}
{"type":"DELETED", "object":{...}}
谁在用 Watch?
- kubelet:Watch 本节点 Pod 变化,决定创建/销毁容器
- Controller:Watch Deployment,发现副本数变化后创建 ReplicaSet
- Scheduler:Watch 未绑定节点的 Pod,执行调度
普通 HTTP API:如果需要实时推送,通常用 WebSocket 或 SSE,但语义与 Watch 完全不同。
差异 4:FieldSelector / LabelSelector(服务端过滤)
GET /api/v1/pods?fieldSelector=status.phase=Running,spec.nodeName=node-01
GET /api/v1/pods?labelSelector=app=payment,env=prod
APIServer 在收到请求后,会将过滤条件下推至 etcd,只返回匹配的资源。
普通 HTTP API :通常是 GET /api/items?status=active,由业务服务自己查数据库过滤。K8s 的 Selector 是基础设施级能力 ,且支持集合运算(In、NotIn、Exists)。
差异 5:子资源(Subresource)与权限精细化
普通 API 通常是 /resource/{id} 平铺,K8s 有子资源概念:
|--------|---------------------------|-----------------------------------------|
| 子资源 | URL | 独立权限 |
| Status | /pods/{name}/status | 可单独授权(如 kubelet 只允许更新 status,不允许改 spec) |
| Log | /pods/{name}/log | 实际代理到 kubelet,权限可独立控制 |
| Exec | /pods/{name}/exec | WebSocket 升级,独立 RBAC 规则 |
| Scale | /deployments/{name}/scale | HPA 只需要 scale 权限,不需要 full update 权限 |
| Bind | /pods/{name}/binding | Scheduler 专用,将 Pod 绑定到节点 |
金融级意义:等保要求最小权限,子资源让 RBAC 可以精确到"只能看日志,不能删 Pod"。
差异 6:内置认证授权链(不是"加个 JWT 中间件"那么简单)
APIServer 的请求在到达业务逻辑前,必须经过三道安检:
客户端请求
│
├──► 1. TLS 握手(mTLS 客户端证书验证,或 Token 校验)
│
├──► 2. 认证(Authentication):你是谁?
│ • X509 客户端证书(kubelet/controller-manager)
│ • Bearer Token(ServiceAccount JWT / OIDC / Webhook)
│ • Bootstrap Token(节点加入集群)
│
├──► 3. 授权(Authorization):你能做什么?
│ • RBAC(Role/ClusterRole + RoleBinding)
│ • Node 授权(kubelet 只能操作本节点 Pod)
│ • Webhook(对接银行 AD/LDAP/Keycloak)
│
└──► 4. 准入控制(Admission Control):请求是否合规?
• Mutating(修改请求,如自动注入 Sidecar)
• Validating(校验请求,如 OPA/Kyverno 策略拦截)
普通 HTTP API :通常只有一层 Authorization: Bearer xxx + 业务层鉴权,没有 K8s 这种协议级、标准化的多阶段安检。
三、APIServer 的协议细节(与普通 HTTP 的微妙差异)
3.1 内容协商:JSON vs Protobuf
APIServer 同时支持两种序列化:
默认:JSON(人类可读,kubectl 默认)
Accept: application/json
高性能:Protobuf(内部组件优先使用,带宽和 CPU 节省 3-5 倍)
Accept: application/vnd.kubernetes.protobuf
银行级优化:集群内部组件(kubelet、controller-manager)应强制使用 Protobuf,减少 APIServer 序列化压力。
3.2 动词(Verb)与 HTTP 方法的映射
K8s 在 RBAC 中使用逻辑动词,不完全等于 HTTP 方法:
|---------|---------------------------|------------------------------------------|
| HTTP 方法 | K8s RBAC Verb | 说明 |
| GET | get / list / watch | list 是集合查询,get 是单个资源,watch 是长连接 |
| POST | create | |
| PUT | update | 全量替换 |
| PATCH | patch | 部分更新(JSON Patch / Strategic Merge Patch) |
| DELETE | delete / deletecollection | |
特殊 :kubectl apply 底层是 PATCH(Strategic Merge Patch),不是简单的 PUT。
3.3 Strategic Merge Patch(K8s 独创)
普通 HTTP API 的 PATCH 通常是 JSON Merge Patch 或 JSON Patch(RFC 6902)。K8s 发明了Strategic Merge Patch,解决容器列表的合并语义:
原 Deployment
containers:
- name: nginx
image: nginx:1.19 - name: sidecar
image: busybox
用户 PATCH(只改 nginx 版本)
containers:
- name: nginx
image: nginx:1.20
K8s Strategic Merge 结果:保留 sidecar,只更新 nginx
普通 JSON Merge Patch 结果:可能直接替换整个 containers 数组,sidecar 丢失
关键 :patchStrategy:"merge" patchMergeKey:"name" 注解定义了合并策略,这是普通 HTTP API 没有的。
四、金融级视角:APIServer 调用的安全与审计
4.1 审计日志(等保 3.0 要求)
APIServer 的每个请求都会生成结构化审计事件:
{
"kind": "Event",
"apiVersion": "audit.k8s.io/v1",
"level": "RequestResponse",
"timestamp": "2026-05-12T11:51:00Z",
"verb": "create",
"user": {
"username": "zhangsan@bank.com",
"groups": ["digital-banking", "system:authenticated"]
},
"sourceIPs": ["10.0.1.15"],
"objectRef": {
"resource": "pods",
"namespace": "prod-core",
"name": "payment-api-xxx"
},
"requestObject": { ... }, // 请求体(敏感资源可能省略)
"responseObject": { ... }, // 响应体
"responseStatus": { "code": 201 }
}
银行要求:审计日志必须留存 6 个月,WORM 存储,对接 SIEM。
4.2 API Priority and Fairness(APF):防止请求洪峰
银行大集群中,某个失控的 CI Job 批量 List Pod 可能挤爆 APIServer。APF 将请求分级:
FlowSchema:区分系统组件、人类用户、服务账号
priorityLevelConfiguration:
- name: system-high # kubelet、controller 高优
- name: operator-medium # 运维人员中优
- name: ci-low # CI 流水线低优,限流排队
普通 HTTP API :通常用 Nginx/Envoy 限流,但缺乏 K8s 这种基于身份和动词的内置优先级队列。
五、一句话讲清差异
APIServer 的 API 在协议层面就是 HTTP/JSON(或 Protobuf),但在语义层面是"面向终态的、版本化的、事件驱动的、带内置安检链的分布式资源控制系统"。
它与普通 HTTP API 的关系,类似于**"SQL 与 Excel 都是表格"**------表面都是行列数据,但底层哲学和适用域完全不同。