Kubernetes Admission Webhook

FreeGuideOnline 最新 2026-07-11

go func serve(w http.ResponseWriter, r *http.Request) { var admissionReview admissionv1.AdmissionReview json.NewDecoder(r.Body).Decode(&admissionReview)

// 执行自定义逻辑
allowed := true
var patch []byte

// ... 检查请求

admissionResponse := admissionv1.AdmissionResponse{
    UID:     admissionReview.Request.UID,
    Allowed: allowed,
}
if patch != nil {
    admissionResponse.Patch = patch
}

response := admissionv1.AdmissionReview{
    TypeMeta: metav1.TypeMeta{
        APIVersion: "admission.k8s.io/v1",
        Kind:       "AdmissionReview",
    },
    Response: &admissionResponse,
}

json.NewEncoder(w).Encode(response)

}


将其打包成容器镜像并部署为一个 Deployment,暴露 ClusterIP Service。

### 2. 创建 TLS 证书 Secret

假设你已有证书文件 `tls.crt` 和 `tls.key`,创建 Secret:

```bash
kubectl create secret tls webhook-server-tls \
  --cert=path/to/tls.crt \
  --key=path/to/tls.key \
  -n <namespace>

3. 配置 Webhook 资源

创建一个 MutatingWebhookConfigurationValidatingWebhookConfiguration。以下是一个验证 webhook 配置示例,拦截所有 Pod 创建请求:

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
  name: pod-policy.example.com
webhooks:
  - name: pod-policy.example.com
    clientConfig:
      service:
        name: webhook-service
        namespace: webhook
        path: "/validate"
      caBundle: <base64-encoded-ca-cert>
    rules:
      - operations: ["CREATE", "UPDATE"]
        apiGroups: [""]
        apiVersions: ["v1"]
        resources: ["pods"]
    admissionReviewVersions: ["v1"]
    sideEffects: None
    failurePolicy: Fail

说明:

  • clientConfig.service 指向 webhook 服务,caBundle 是用于验证服务端证书的 CA 证书(base64 编码)。
  • rules 定义 webhook 监听的资源类型和操作。
  • failurePolicy 决定 API server 无法连接 webhook 时的行为:Fail 表示拒绝请求,Ignore 表示忽略错误并继续处理。
  • sideEffects 声明 webhook 是否会产生副作用(如外部系统调用),影响 Dry-Run 和请求超时行为。

关键技术细节

AdmissionReview 版本

从 Kubernetes 1.16 起支持 admission.k8s.io/v1,之前是 admission.k8s.io/v1beta1。在配置中必须通过 admissionReviewVersions 字段指定支持的版本,API server 会发送该版本。你的 webhook 服务必须能识别并正确处理对应版本的结构。建议同时支持 v1v1beta1 以兼容旧集群,但新集群标配 v1

对象修改与 RFC 6902 JSON Patch

Mutating Webhook 返回的是 JSON Patch 操作的数组,例子:

{
  "response": {
    "uid": "12345",
    "allowed": true,
    "patchType": "JSONPatch",
    "patch": "W3sib3AiOiAiYWRkIiwgInBhdGgiOiAiL3NwZWMvY29udGFpbmVycy8tIiwgInZhbHVlIjogeyJuYW1lIjogInNpZGVjYXIiLCAiaW1hZ2UiOiAic2lkZWNhcjpsYXRlc3QifX1d"
  }
}