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)