
k8s 在 apiserver 中提供 [准入控制](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/) 扩展，用于在资源创建、更新、删除操作时进行拦截和处理。

自定义的准入控制器通过提供一个 webhook 服务，再创建对应的资源对象注册到 apiserver 中，这就是 [Dynamic Admission Control 动态准入控制](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/)。比如你作为某个 k8s 的平台管理员，希望使用方在创建 pod 的时候必须带上特定的业务标签，就可以通过自定义准入控制器来实现。

为了保证 webhook 服务的安全性，API Server 与 Webhook 之间需要使用 TLS 证书进行认证。

## 证书架构

```mermaid
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
```

## 认证流程

用"银行验证 ATM 机身份"来类比：

- API Server = 银行总部，需要验证对方身份
- Webhook = ATM 机，需要证明自己是合法的
- CA = 认证机构，负责颁发"身份证"（证书）
- caBundle = 银行总部持有的认证机构列表，注意是多个，主要是为了应对证书轮换。

当用户执行 `kubectl create pod` 触发 Webhook 调用时：

```mermaid
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
```

核心验证点：

1. CA 可信：服务证书必须由 `caBundle` 中的 CA 签发
2. DNS 匹配：证书的 SAN 必须包含 Webhook Service 的 DNS 名称
3. 未过期：证书在有效期内

