Webhook 模式

WebHook 是一种 HTTP 回调:在某些事件发生时发生的 HTTP POST 请求;通过 HTTP POST 进行的简单事件通知。实现 WebHook 的 Web 应用程序在特定事件发生时会向一个 URL 发送 POST 消息。

当指定 Webhook 模式时,Kubernetes 会在确定用户权限时查询外部 REST 服务。

配置文件格式

Webhook 模式需要一个用于 HTTP 配置的文件,通过 --authorization-webhook-config-file=SOME_FILENAME 标志指定。

配置文件使用 kubeconfig 文件格式。在文件中,“users”指代 API Server webhook,“clusters”指代远程服务。

使用 HTTPS 客户端认证的配置示例

# Kubernetes API version
apiVersion: v1
# kind of the API object
kind: Config
# clusters refers to the remote service.
clusters:
  - name: name-of-remote-authz-service
    cluster:
      # CA for verifying the remote service.
      certificate-authority: /path/to/ca.pem
      # URL of remote service to query. Must use 'https'. May not include parameters.
      server: https://authz.example.com/authorize

# users refers to the API Server's webhook configuration.
users:
  - name: name-of-api-server
    user:
      client-certificate: /path/to/cert.pem # cert for the webhook plugin to use
      client-key: /path/to/key.pem          # key matching the cert

# kubeconfig files require a context. Provide one for the API Server.
current-context: webhook
contexts:
- context:
    cluster: name-of-remote-authz-service
    user: name-of-api-server
  name: webhook

请求负载

当需要进行授权决策时,API Server 会 POST 一个 JSON 序列化的 authorization.k8s.io/v1beta1 SubjectAccessReview 对象,描述该操作。该对象包含描述尝试发起请求的用户以及有关正在访问的资源或请求属性的详细信息的字段。

请注意,Webhook API 对象遵循与其他 Kubernetes API 对象相同的版本兼容性规则。实现者应该注意 Beta 对象较宽松的兼容性承诺,并检查请求的“apiVersion”字段以确保正确的反序列化。此外,API Server 必须启用 authorization.k8s.io/v1beta1 API 扩展组(--runtime-config=authorization.k8s.io/v1beta1=true)。

请求正文示例

{
  "apiVersion": "authorization.k8s.io/v1beta1",
  "kind": "SubjectAccessReview",
  "spec": {
    "resourceAttributes": {
      "namespace": "kittensandponies",
      "verb": "get",
      "group": "unicorn.example.org",
      "resource": "pods"
    },
    "user": "jane",
    "group": [
      "group1",
      "group2"
    ]
  }
}

远程服务应填写请求的 status 字段并响应以允许或拒绝访问。响应正文的 spec 字段将被忽略并可以省略。允许访问的响应将返回

{
  "apiVersion": "authorization.k8s.io/v1beta1",
  "kind": "SubjectAccessReview",
  "status": {
    "allowed": true
  }
}

有两种方法可以拒绝访问。

第一种方法在大多数情况下是首选,它表示授权 Webhook 不允许或对请求“没有意见”,但如果配置了其他授权器,它们有机会允许请求。如果没有其他授权器,或者它们都不允许请求,则该请求将被禁止。Webhook 将返回

{
  "apiVersion": "authorization.k8s.io/v1beta1",
  "kind": "SubjectAccessReview",
  "status": {
    "allowed": false,
    "reason": "user does not have read access to the namespace"
  }
}

第二种方法立即拒绝,从而短路其他已配置授权器的评估。这应仅由对集群完整授权器配置有详细了解的 Webhook 使用。Webhook 将返回

{
  "apiVersion": "authorization.k8s.io/v1beta1",
  "kind": "SubjectAccessReview",
  "status": {
    "allowed": false,
    "denied": true,
    "reason": "user does not have read access to the namespace"
  }
}

非资源路径的访问请求发送如下:

{
  "apiVersion": "authorization.k8s.io/v1beta1",
  "kind": "SubjectAccessReview",
  "spec": {
    "nonResourceAttributes": {
      "path": "/debug",
      "verb": "get"
    },
    "user": "jane",
    "group": [
      "group1",
      "group2"
    ]
  }
}
特性状态: Kubernetes v1.34 [稳定] (默认启用:true)

当调用授权 Webhook 时,Kubernetes 会在请求中将标签和字段选择器传递给授权 Webhook。授权 Webhook 可以根据范围内的字段和标签选择器做出授权决策,如果它愿意的话。

SubjectAccessReview API 文档提供了关于授权 Webhook 如何解释和处理这些字段的指导,特别是使用已解析的需求而不是原始选择器字符串,以及如何安全地处理无法识别的操作符。

{
  "apiVersion": "authorization.k8s.io/v1beta1",
  "kind": "SubjectAccessReview",
  "spec": {
    "resourceAttributes": {
      "verb": "list",
      "group": "",
      "resource": "pods",
      "fieldSelector": {
        "requirements": [
          {"key":"spec.nodeName", "operator":"In", "values":["mynode"]}
        ]
      },
      "labelSelector": {
        "requirements": [
          {"key":"example.com/mykey", "operator":"In", "values":["myvalue"]}
        ]
      }
    },
    "user": "jane",
    "group": [
      "group1",
      "group2"
    ]
  }
}

非资源路径包括:/api/apis/metrics/logs/debug/healthz/livez/openapi/v2/readyz/version。客户端需要访问 /api/api/*/apis/apis/*/version 才能发现服务器上存在哪些资源和版本。对其他非资源路径的访问可以被禁止,而不会限制对 REST API 的访问。

有关更多信息,请参阅 SubjectAccessReview API 文档webhook.go 实现

上次修改时间:2025 年 7 月 1 日下午 12:20 PST:KEP-4601:升级到稳定版 (31f23f14a7)