ᕕ( ᐛ )ᕗ Jimyag's Blog

Kubernetes admission webhook 自签名证书认证

k8s 在 apiserver 中提供 准入控制 扩展,用于在资源创建、更新、删除操作时进行拦截和处理。

自定义的准入控制器通过提供一个 webhook 服务,再创建对应的资源对象注册到 apiserver 中,这就是 Dynamic Admission Control 动态准入控制。比如你作为某个 k8s 的平台管理员,希望使用方在创建 pod 的时候必须带上特定的业务标签,就可以通过自定义准入控制器来实现。

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

证书架构

  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 调用时:

  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. 未过期:证书在有效期内

#Kubernetes