Kubernetes admission webhook 自签名证书认证
k8s 在 apiserver 中提供 准入控制 扩展,用于在资源创建、更新、删除操作时进行拦截和处理。
自定义的准入控制器通过提供一个 webhook 服务,再创建对应的资源对象注册到 apiserver 中,这就是 Dynamic Admission Control 动态准入控制。比如你作为某个 k8s 的平台管理员,希望使用方在创建 pod 的时候必须带上特定的业务标签,就可以通过自定义准入控制器来实现。
API Server 通过 TLS 连接 webhook,并用 caBundle 校验 webhook 服务端证书。
证书架构
graph TB
subgraph "Certificate Authority (CA)"
CAKey[CA 私钥]
CACert[CA 证书]
end
subgraph "Serving Certificate"
ServingKey[服务私钥]
ServingCert[服务证书]
end
CAKey -->|签发| ServingCert
CACert -->|配置到 caBundle| APIServer[API Server]
ServingKey --> WebhookServer[Webhook Server]
ServingCert --> WebhookServer
APIServer -->|TLS 请求| WebhookServer
APIServer -->|用 caBundle 验证| ServingCert
认证流程
webhook 提供服务证书和私钥;WebhookConfiguration 中的 caBundle 提供信任的 CA 证书。轮换 CA 时可以同时配置新旧 CA 证书,让新旧服务证书在过渡期都能通过校验。
当用户执行 kubectl create pod 触发 Webhook 调用时:
sequenceDiagram
participant API as API Server
participant Webhook as Webhook Server
API->>Webhook: 1. 发起 TLS 连接
Webhook->>API: 2. 返回服务证书
Note over API: 3. 用 caBundle 验证证书:<br/>- CA 是否可信?<br/>- DNS 名称是否匹配?<br/>- 证书是否过期?
alt 验证通过
API->>Webhook: 4. 发送 AdmissionReview
Webhook->>API: 5. 返回 AdmissionResponse
else 验证失败
API--xWebhook: 拒绝连接
end
核心验证点:
- CA 可信:服务证书必须由
caBundle中的 CA 签发 - DNS 匹配:证书的 SAN 必须包含 Webhook Service 的 DNS 名称
- 未过期:证书在有效期内