Kubernetes 1.30:多重 Webhook 和模組化授權變得更輕鬆
在 Kubernetes 1.30 中,我們 (SIG Auth) 正在將結構化授權配置移至 Beta 版。
今天的文章是關於授權:決定某人可以和不能存取什麼。查看昨天的上一篇文章,了解 Kubernetes v1.30 中關於身份驗證 (找出誰在執行任務,並檢查他們是否是他們所聲稱的身分) 的新功能。
簡介
Kubernetes 持續發展以滿足系統管理員和開發人員的複雜需求。Kubernetes 的一個關鍵面向,可確保叢集的安全性和完整性,是 API 伺服器授權。直到最近,kube-apiserver 中授權鏈的配置在某種程度上仍然僵化,僅限於一組命令列標誌,並且在授權鏈中僅允許單一 Webhook。這種方法雖然功能完善,但限制了叢集管理員定義複雜、細緻的授權策略所需的彈性。最新的結構化授權配置功能 (KEP-3221) 旨在透過引入更結構化和通用的方式來配置授權鏈,從而徹底改變這方面,重點是啟用多個 Webhook 並提供明確的控制機制。
改進的需求
叢集管理員長期以來一直尋求在 API 伺服器處理程序鏈中指定多個授權 Webhook 的能力,並控制每個 Webhook 的詳細行為,例如逾時和失敗策略。這種需求源於建立分層安全策略的願望,在分層安全策略中,可以根據特定順序的多個標準或規則集來驗證請求。先前的限制也使得難以動態配置授權器鏈,從而沒有空間有效管理複雜的授權情境。
結構化授權配置功能 透過引入組態檔格式來配置 Kubernetes API 伺服器授權鏈,從而解決了這些限制。此格式允許在授權鏈中指定多個 Webhook (所有其他授權類型最多指定一次)。每個 Webhook 授權器都具有明確定義的參數,包括逾時設定、失敗策略以及使用 CEL 規則調用的條件,以便在將請求分派到 Webhook 之前預先篩選請求,從而幫助您防止不必要的調用。組態還支援自動重新載入,確保可以動態應用變更,而無需重新啟動 kube-apiserver。此功能解決了當前的限制,並為更有效地保護和管理 Kubernetes 叢集開闢了新的可能性。
範例配置
以下是結構化授權配置範例,以及所有欄位、其預設值和可能值的描述。
apiVersion: apiserver.config.k8s.io/v1beta1
kind: AuthorizationConfiguration
authorizers:
- type: Webhook
# Name used to describe the authorizer
# This is explicitly used in monitoring machinery for metrics
# Note:
# - Validation for this field is similar to how K8s labels are validated today.
# Required, with no default
name: webhook
webhook:
# The duration to cache 'authorized' responses from the webhook
# authorizer.
# Same as setting `--authorization-webhook-cache-authorized-ttl` flag
# Default: 5m0s
authorizedTTL: 30s
# The duration to cache 'unauthorized' responses from the webhook
# authorizer.
# Same as setting `--authorization-webhook-cache-unauthorized-ttl` flag
# Default: 30s
unauthorizedTTL: 30s
# Timeout for the webhook request
# Maximum allowed is 30s.
# Required, with no default.
timeout: 3s
# The API version of the authorization.k8s.io SubjectAccessReview to
# send to and expect from the webhook.
# Same as setting `--authorization-webhook-version` flag
# Required, with no default
# Valid values: v1beta1, v1
subjectAccessReviewVersion: v1
# MatchConditionSubjectAccessReviewVersion specifies the SubjectAccessReview
# version the CEL expressions are evaluated against
# Valid values: v1
# Required, no default value
matchConditionSubjectAccessReviewVersion: v1
# Controls the authorization decision when a webhook request fails to
# complete or returns a malformed response or errors evaluating
# matchConditions.
# Valid values:
# - NoOpinion: continue to subsequent authorizers to see if one of
# them allows the request
# - Deny: reject the request without consulting subsequent authorizers
# Required, with no default.
failurePolicy: Deny
connectionInfo:
# Controls how the webhook should communicate with the server.
# Valid values:
# - KubeConfigFile: use the file specified in kubeConfigFile to locate the
# server.
# - InClusterConfig: use the in-cluster configuration to call the
# SubjectAccessReview API hosted by kube-apiserver. This mode is not
# allowed for kube-apiserver.
type: KubeConfigFile
# Path to KubeConfigFile for connection info
# Required, if connectionInfo.Type is KubeConfigFile
kubeConfigFile: /kube-system-authz-webhook.yaml
# matchConditions is a list of conditions that must be met for a request to be sent to this
# webhook. An empty list of matchConditions matches all requests.
# There are a maximum of 64 match conditions allowed.
#
# The exact matching logic is (in order):
# 1. If at least one matchCondition evaluates to FALSE, then the webhook is skipped.
# 2. If ALL matchConditions evaluate to TRUE, then the webhook is called.
# 3. If at least one matchCondition evaluates to an error (but none are FALSE):
# - If failurePolicy=Deny, then the webhook rejects the request
# - If failurePolicy=NoOpinion, then the error is ignored and the webhook is skipped
matchConditions:
# expression represents the expression which will be evaluated by CEL. Must evaluate to bool.
# CEL expressions have access to the contents of the SubjectAccessReview in v1 version.
# If version specified by subjectAccessReviewVersion in the request variable is v1beta1,
# the contents would be converted to the v1 version before evaluating the CEL expression.
#
# Documentation on CEL: https://kubernetes.dev.org.tw/docs/reference/using-api/cel/
#
# only send resource requests to the webhook
- expression: has(request.resourceAttributes)
# only intercept requests to kube-system
- expression: request.resourceAttributes.namespace == 'kube-system'
# don't intercept requests from kube-system service accounts
- expression: "!('system:serviceaccounts:kube-system' in request.groups)"
- type: Node
name: node
- type: RBAC
name: rbac
- type: Webhook
name: in-cluster-authorizer
webhook:
authorizedTTL: 5m
unauthorizedTTL: 30s
timeout: 3s
subjectAccessReviewVersion: v1
failurePolicy: NoOpinion
connectionInfo:
type: InClusterConfig
以下配置範例說明了真實世界的案例,這些案例需要能夠指定具有不同設定、優先順序和失敗模式的多個 Webhook。
保護已安裝的 CRD
確保叢集啟動時自訂資源定義 (CRD) 的可用性一直是關鍵需求。控制器協調這些 CRD 的阻礙之一是為它們提供保護機制,這可以透過多個授權 Webhook 來實現。這在以前是不可能的,因為在 Kubernetes API 伺服器授權鏈中指定多個授權 Webhook 根本是不可能的。現在,透過結構化授權配置功能,管理員可以指定多個 Webhook,提供 RBAC 無法滿足的解決方案,尤其是在拒絕「非系統」使用者對某些 CRD 的權限時。
假設此情境如下
- 已安裝「受保護的」CRD。
- 它們只能由
admin
群組中的使用者修改。
apiVersion: apiserver.config.k8s.io/v1beta1
kind: AuthorizationConfiguration
authorizers:
- type: Webhook
name: system-crd-protector
webhook:
unauthorizedTTL: 30s
timeout: 3s
subjectAccessReviewVersion: v1
matchConditionSubjectAccessReviewVersion: v1
failurePolicy: Deny
connectionInfo:
type: KubeConfigFile
kubeConfigFile: /files/kube-system-authz-webhook.yaml
matchConditions:
# only send resource requests to the webhook
- expression: has(request.resourceAttributes)
# only intercept requests for CRDs
- expression: request.resourceAttributes.resource.resource = "customresourcedefinitions"
- expression: request.resourceAttributes.resource.group = ""
# only intercept update, patch, delete, or deletecollection requests
- expression: request.resourceAttributes.verb in ['update', 'patch', 'delete','deletecollection']
- type: Node
- type: RBAC
防止不必要的巢狀 Webhook
系統管理員希望在使用 Open Policy Agent 等框架將請求移交給 Webhook 之前,對請求應用特定的驗證。過去,這需要運行巢狀 Webhook (在新增到授權鏈的 Webhook 中) 才能實現所需的結果。結構化授權配置功能簡化了此過程,提供了一個結構化的 API,用於在需要時選擇性地觸發其他 Webhook。它還使管理員能夠為每個 Webhook 設定不同的失敗策略,從而確保更一致和可預測的回應。
apiVersion: apiserver.config.k8s.io/v1beta1
kind: AuthorizationConfiguration
authorizers:
- type: Webhook
name: system-crd-protector
webhook:
unauthorizedTTL: 30s
timeout: 3s
subjectAccessReviewVersion: v1
matchConditionSubjectAccessReviewVersion: v1
failurePolicy: Deny
connectionInfo:
type: KubeConfigFile
kubeConfigFile: /files/kube-system-authz-webhook.yaml
matchConditions:
# only send resource requests to the webhook
- expression: has(request.resourceAttributes)
# only intercept requests for CRDs
- expression: request.resourceAttributes.resource.resource = "customresourcedefinitions"
- expression: request.resourceAttributes.resource.group = ""
# only intercept update, patch, delete, or deletecollection requests
- expression: request.resourceAttributes.verb in ['update', 'patch', 'delete','deletecollection']
- type: Node
- type: RBAC
- name: opa
type: Webhook
webhook:
unauthorizedTTL: 30s
timeout: 3s
subjectAccessReviewVersion: v1
matchConditionSubjectAccessReviewVersion: v1
failurePolicy: Deny
connectionInfo:
type: KubeConfigFile
kubeConfigFile: /files/opa-default-authz-webhook.yaml
matchConditions:
# only send resource requests to the webhook
- expression: has(request.resourceAttributes)
# only intercept requests to default namespace
- expression: request.resourceAttributes.namespace == 'default'
# don't intercept requests from default service accounts
- expression: "!('system:serviceaccounts:default' in request.groups)"
下一步是什麼?
從 Kubernetes 1.30 開始,此功能處於 Beta 版,預設為啟用。對於 Kubernetes v1.31,我們預期該功能將保持在 Beta 版,同時我們將從使用者那裡獲得更多回饋。一旦它準備好 GA,功能標誌將被移除,並且組態檔版本將升級到 v1。
在 結構化授權配置 Kubernetes 文件網站上了解有關此功能的更多資訊。您也可以關注 KEP-3221 以追蹤即將發布的 Kubernetes 版本中的進展。
行動號召
在這篇文章中,我們介紹了 Kubernetes v1.30 中結構化授權配置功能的優點,以及針對真實世界情境的一些範例配置。若要使用此功能,您必須使用 --authorization-config
命令列引數指定授權配置的路徑。從 Kubernetes 1.30 開始,此功能處於 Beta 版,預設為啟用。如果您想繼續使用命令列標誌而不是組態檔,這些標誌將繼續按原樣運作。同時指定 --authorization-config
和 --authorization-modes
/--authorization-webhook-*
將不起作用。您需要從 kube-apiserver 命令中刪除較舊的標誌。
以下 Kind 叢集配置在 APIserver 上設定該命令引數,以從檔案資料夾中的檔案 (authorization_config.yaml
) 載入 AuthorizationConfiguration。任何需要的 kubeconfig 和憑證檔案也可以放在檔案目錄中。
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
featureGates:
StructuredAuthorizationConfiguration: true # enabled by default in v1.30
kubeadmConfigPatches:
- |
kind: ClusterConfiguration
metadata:
name: config
apiServer:
extraArgs:
authorization-config: "/files/authorization_config.yaml"
extraVolumes:
- name: files
hostPath: "/files"
mountPath: "/files"
readOnly: true
nodes:
- role: control-plane
extraMounts:
- hostPath: files
containerPath: /files
我們很樂意聽取您對此功能的意見回饋。特別是,我們希望 Kubernetes 叢集管理員和授權 Webhook 實作人員在建置與此新 API 的整合時提供意見回饋。請透過 Kubernetes Slack 上的 #sig-auth-authorizers-dev 頻道與我們聯絡。
如何參與
如果您有興趣協助開發此功能、分享意見回饋或參與任何其他正在進行的 SIG Auth 專案,請透過 Kubernetes Slack 上的 #sig-auth 頻道與我們聯絡。
也歡迎您參加每隔週三舉行的 SIG Auth 會議。
致謝
此功能由多家不同公司的貢獻者推動。我們要衷心感謝每位貢獻時間和精力使這一切成為可能的人。