授權
Kubernetes 授權發生在 身份驗證 之後。通常,提出請求的用戶端必須先通過身份驗證(登入),其請求才能被允許;但是,Kubernetes 在某些情況下也允許匿名請求。
若要概觀授權如何融入更廣泛的 API 存取控制範圍,請閱讀 控制對 Kubernetes API 的存取。
授權裁決
Kubernetes API 請求的授權發生在 API 伺服器內部。API 伺服器根據所有策略評估所有請求屬性,也可能諮詢外部服務,然後允許或拒絕請求。
API 請求的所有部分都必須通過某種授權機制的允許才能繼續。換句話說:預設情況下存取被拒絕。
當配置多個 授權模組 時,將依序檢查每個模組。如果任何授權者核准或拒絕請求,則會立即返回該決定,並且不會諮詢其他授權者。如果所有模組對請求都沒有意見,則請求將被拒絕。整體拒絕裁決表示 API 伺服器拒絕該請求並以 HTTP 403 (Forbidden) 狀態回應。
授權中使用的請求屬性
Kubernetes 僅審查以下 API 請求屬性
- 使用者 - 身份驗證期間提供的
user
字串。 - 群組 - 經過身份驗證的使用者所屬的群組名稱列表。
- 額外資訊 - 由身份驗證層提供的任意字串鍵到字串值的映射。
- API - 指示請求是否用於 API 資源。
- 請求路徑 - 雜項非資源端點的路徑,例如
/api
或/healthz
。 - API 請求動詞 - API 動詞(例如
get
、list
、create
、update
、patch
、watch
、delete
和deletecollection
)用於資源請求。若要判斷資源 API 端點的請求動詞,請參閱 請求動詞和授權。 - HTTP 請求動詞 - 小寫的 HTTP 方法(例如
get
、post
、put
和delete
)用於非資源請求。 - 資源 - 正在存取的資源的 ID 或名稱(僅適用於資源請求)-- 對於使用
get
、update
、patch
和delete
動詞的資源請求,您必須提供資源名稱。 - 子資源 - 正在存取的子資源(僅適用於資源請求)。
- 命名空間 - 正在存取的物件的命名空間(僅適用於命名空間資源請求)。
- API 群組 - 正在存取的 API 群組(僅適用於資源請求)。空字串表示核心 API 群組。
請求動詞和授權
非資源請求
對 /api/v1/...
或 /apis/<group>/<version>/...
以外的端點的請求被視為非資源請求,並使用請求的小寫 HTTP 方法作為動詞。例如,使用 HTTP 對 /api
或 /healthz
等端點發出 GET
請求將使用 get 作為動詞。
資源請求
若要判斷資源 API 端點的請求動詞,Kubernetes 會對應使用的 HTTP 動詞,並考量請求是作用於個別資源還是資源集合
HTTP 動詞 | 請求動詞 |
---|---|
POST | create |
GET , HEAD | get(針對個別資源)、list(針對集合,包括完整物件內容)、watch(用於監看個別資源或資源集合) |
PUT | update |
PATCH | patch |
DELETE | delete(針對個別資源)、deletecollection(針對集合) |
注意
+get、list 和 watch 動詞都可以傳回資源的完整詳細資訊。就存取傳回的資料而言,它們是等效的。例如,對secrets
執行 list 將會揭露任何傳回資源的 data 屬性。Kubernetes 有時會使用特殊動詞檢查授權以取得額外權限。例如
- 身份驗證 的特殊情況
- impersonate 動詞作用於核心 API 群組中的
users
、groups
和serviceaccounts
,以及authentication.k8s.io
API 群組中的userextras
。
- impersonate 動詞作用於核心 API 群組中的
- CertificateSigningRequests 的授權
- CertificateSigningRequests 的 approve 動詞,以及對現有核准進行修訂的 update 動詞
- RBAC (基於角色的存取控制)
- 作用於
rbac.authorization.k8s.io
API 群組中roles
和clusterroles
資源的 bind 和 escalate 動詞。
- 作用於
授權上下文
Kubernetes 預期屬性是 REST API 請求共有的。這表示 Kubernetes 授權可以與現有的組織範圍或雲端供應商範圍的存取控制系統協同運作,這些系統可能處理 Kubernetes API 以外的其他 API。
授權模式
Kubernetes API 伺服器可以使用多種授權模式之一來授權請求
AlwaysAllow (總是允許)
- 此模式允許所有請求,這會帶來安全風險。僅當您的 API 請求不需要授權時(例如,用於測試),才使用此授權模式。
AlwaysDeny (總是拒絕)
- 此模式會封鎖所有請求。僅將此授權模式用於測試。
ABAC
(基於屬性的存取控制)- Kubernetes ABAC 模式定義了一種存取控制範例,其中透過使用組合屬性的策略來授予使用者存取權限。策略可以使用任何類型的屬性(使用者屬性、資源屬性、物件、環境屬性等)。
RBAC
(基於角色的存取控制)- Kubernetes RBAC 是一種基於企業內個別使用者的角色來管理對電腦或網路資源存取的方法。在此上下文中,「存取」是指個別使用者執行特定任務的能力,例如檢視、建立或修改檔案。
在此模式下,Kubernetes 使用rbac.authorization.k8s.io
API 群組來驅動授權決策,讓您可以透過 Kubernetes API 動態設定權限策略。 節點
- 一種特殊用途的授權模式,根據 kubelet 排程執行的 Pod 來授予權限。若要進一步瞭解節點授權模式,請參閱節點授權。
Webhook
- Kubernetes 用於授權的 Webhook 模式會進行同步 HTTP 呼叫,封鎖請求直到遠端 HTTP 服務回應查詢。您可以編寫自己的軟體來處理呼叫,或使用生態系統中的解決方案。
警告
啟用 AlwaysAllow
模式會繞過授權;請勿在您不信任所有潛在 API 用戶端的叢集上使用此模式,包括您執行的工作負載。
授權機制通常會傳回拒絕或無意見結果;有關此的更多資訊,請參閱授權裁決。啟用 AlwaysAllow
表示如果所有其他授權者都傳回「無意見」,則允許該請求。例如,--authorization-mode=AlwaysAllow,RBAC
與 --authorization-mode=AlwaysAllow
具有相同的效果,因為 Kubernetes RBAC 不提供負面(拒絕)存取規則。
您不應在可從公共網際網路連線的 Kubernetes 叢集上使用 AlwaysAllow
模式。
system:masters 群組
system:masters
群組是一個內建的 Kubernetes 群組,它授予對 API 伺服器的無限制存取權。任何分配到此群組的使用者都具有完整的叢集管理員權限,繞過 RBAC 或 Webhook 機制施加的任何授權限制。避免將使用者新增到此群組。如果您確實需要授予使用者叢集管理員權限,您可以建立一個 ClusterRoleBinding 到內建的 cluster-admin
ClusterRole。
授權模式配置
您可以使用僅限組態檔或命令列引數來配置 Kubernetes API 伺服器的授權器鏈。
您必須選擇兩種配置方法之一;不允許同時設定 --authorization-config
路徑,並使用 --authorization-mode
和 --authorization-webhook-*
命令列引數配置授權 Webhook。如果您嘗試這樣做,API 伺服器會在啟動期間報告錯誤訊息,然後立即退出。
使用授權組態檔配置 API 伺服器
Kubernetes v1.32 [stable]
(預設啟用:true)Kubernetes 讓您配置可以包含多個 Webhook 的授權鏈。該鏈中的授權項目可以具有明確定義的參數,這些參數以特定順序驗證請求,為您提供精細的控制,例如在失敗時明確拒絕。
組態檔方法甚至允許您指定CEL 規則,以便在將請求分派到 Webhook 之前預先篩選請求,幫助您防止不必要的調用。當組態檔被修改時,API 伺服器也會自動重新載入授權器鏈。
您可以使用 --authorization-config
命令列引數指定授權組態的路徑。
如果您想使用命令列引數而不是組態檔,這也是一種有效且支援的方法。某些授權功能(例如:多個 Webhook、Webhook 失敗策略和預先篩選規則)僅在使用授權組態檔時可用。
組態範例
---
#
# DO NOT USE THE CONFIG AS IS. THIS IS AN EXAMPLE.
#
apiVersion: apiserver.config.k8s.io/v1
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
當使用組態檔配置授權器鏈時,請確保所有控制平面節點都具有相同的檔案內容。在升級/降級叢集時,請注意 API 伺服器配置。例如,如果從 Kubernetes 1.31 升級到 Kubernetes 1.32,您需要確保組態檔的格式是 Kubernetes 1.32 可以理解的,然後再升級叢集。如果您降級到 1.31,則需要適當地設定配置。
授權配置和重新載入
當 API 伺服器觀察到檔案變更時,以及在未觀察到變更事件的情況下,每隔 60 秒排程,Kubernetes 會重新載入授權配置檔案。
注意
您必須確保在重新載入時,檔案中所有非 Webhook 授權器類型保持不變。
重新載入不得新增或移除節點或 RBAC 授權器(它們可以重新排序,但不能新增或移除)。
命令列授權模式配置
您可以使用以下模式
--authorization-mode=ABAC
(基於屬性的存取控制模式)--authorization-mode=RBAC
(基於角色的存取控制模式)--authorization-mode=Node
(節點授權器)--authorization-mode=Webhook
(Webhook 授權模式)--authorization-mode=AlwaysAllow
(總是允許請求;帶有安全風險)--authorization-mode=AlwaysDeny
(總是拒絕請求)
您可以選擇多種授權模式;例如:--authorization-mode=Node,RBAC,Webhook
Kubernetes 根據您在 API 伺服器的命令列上指定的順序檢查授權模組,因此較早的模組具有較高的優先權來允許或拒絕請求。
您不能將 --authorization-mode
命令列引數與用於使用本機檔案配置授權的 --authorization-config
命令列引數結合使用。
有關 API 伺服器的命令列引數的更多資訊,請閱讀 kube-apiserver
參考文件。
透過工作負載建立或編輯進行權限提升
可以建立/編輯命名空間中 Pod 的使用者,無論是直接或透過啟用間接工作負載管理的物件,都可能能夠提升他們在該命名空間中的權限。權限提升的潛在途徑包括 Kubernetes API 擴充及其關聯的控制器。
注意
作為叢集管理員,在授予建立或編輯工作負載的存取權時請謹慎。關於這些權限可能被濫用的某些細節記錄在權限提升路徑中。權限提升路徑
如果您允許攻擊者或不可信任的使用者在命名空間中執行任意 Pod,他們可以透過不同的方式在命名空間內獲得額外的權限
- 在該命名空間中掛載任意密鑰
- 可用於存取其他工作負載的機密資訊
- 可用於取得更高權限的 ServiceAccount 的服務帳戶權杖
- 在該命名空間中使用任意 ServiceAccount
- 可以以另一個工作負載的身分執行 Kubernetes API 動作(身分模擬)
- 可以執行 ServiceAccount 擁有的任何特權動作
- 在該命名空間中掛載或使用其他工作負載的 ConfigMap
- 可用於取得其他工作負載的資訊,例如資料庫主機名稱。
- 在該命名空間中掛載其他工作負載的磁碟區
- 可用於取得其他工作負載的資訊並變更它。
注意
作為系統管理員,在部署允許使用者變更上述區域的 CustomResourceDefinition 時,您應謹慎。這些可能會開啟權限提升路徑。在決定您的授權控制時,請考慮此類變更的後果。檢查 API 存取權
kubectl
提供了 auth can-i
子命令,用於快速查詢 API 授權層。該命令使用 SelfSubjectAccessReview
API 來判斷目前使用者是否可以執行給定的動作,並且無論使用哪種授權模式都有效。
kubectl auth can-i create deployments --namespace dev
輸出類似於這樣
yes
kubectl auth can-i create deployments --namespace prod
輸出類似於這樣
no
管理員可以將此與使用者身分模擬結合使用,以判斷其他使用者可以執行哪些動作。
kubectl auth can-i list secrets --namespace dev --as dave
輸出類似於這樣
no
同樣地,若要檢查命名空間 dev
中名為 dev-sa
的 ServiceAccount 是否可以列出命名空間 target
中的 Pod
kubectl auth can-i list pods \
--namespace target \
--as system:serviceaccount:dev:dev-sa
輸出類似於這樣
yes
SelfSubjectAccessReview 是 authorization.k8s.io
API 群組的一部分,該群組將 API 伺服器授權公開給外部服務。此群組中的其他資源包括
- SubjectAccessReview
- 適用於任何使用者(不僅是目前使用者)的存取權檢閱。適用於將授權決策委派給 API 伺服器。例如,kubelet 和擴充 API 伺服器使用它來判斷使用者對其自身 API 的存取權。
- LocalSubjectAccessReview
- 類似於 SubjectAccessReview,但僅限於特定命名空間。
- SelfSubjectRulesReview
- 檢閱會傳回使用者可以在命名空間內執行的動作集。適用於使用者快速總結自己的存取權,或用於 UI 隱藏/顯示動作。
可以透過建立正常的 Kubernetes 資源來查詢這些 API,其中傳回物件的 response status
欄位是查詢的結果。例如
kubectl create -f - -o yaml << EOF
apiVersion: authorization.k8s.io/v1
kind: SelfSubjectAccessReview
spec:
resourceAttributes:
group: apps
resource: deployments
verb: create
namespace: dev
EOF
產生的 SelfSubjectAccessReview 類似於
apiVersion: authorization.k8s.io/v1
kind: SelfSubjectAccessReview
metadata:
creationTimestamp: null
spec:
resourceAttributes:
group: apps
resource: deployments
namespace: dev
verb: create
status:
allowed: true
denied: false
下一步
- 若要進一步瞭解身份驗證,請參閱身份驗證。
- 如需概觀,請閱讀控制對 Kubernetes API 的存取。
- 若要進一步瞭解准入控制,請參閱使用准入控制器。
- 閱讀更多關於 Kubernetes 中的通用表達式語言。