授權
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/
資源請求
為了確定資源 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 有時會使用專用動詞檢查額外許可權的授權。例如:
- 身份認證的特殊情況
- 核心 API 組中 `users`、`groups` 和 `serviceaccounts` 上的 **impersonate** 動詞,以及 `authentication.k8s.io` API 組中的 `userextras`。
- CertificateSigningRequest 的授權
- 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 動態配置許可權策略。 Node
- 一種特殊用途的授權模式,根據 kubelet 計劃執行的 Pods 授予 kubelet 許可權。要了解有關節點授權模式的更多資訊,請參閱節點授權。
Webhook
- Kubernetes Webhook 模式用於授權,它會進行同步 HTTP 回撥,阻塞請求直到遠端 HTTP 服務響應查詢。你可以編寫自己的軟體來處理回撥,也可以使用生態系統中的解決方案。
警告
啟用 `AlwaysAllow` 模式會繞過授權;如果群集中**所有**潛在的 API 客戶端(包括你執行的工作負載)都不可信,請勿使用此模式。
授權機制通常返回**拒絕**或**無意見**結果;有關此內容的更多資訊,請參閱授權裁決。啟用 `AlwaysAllow` 意味著如果所有其他授權器都返回“無意見”,則允許請求。例如,`--authorization-mode=AlwaysAllow,RBAC` 與 `--authorization-mode=AlwaysAllow` 具有相同的效果,因為 Kubernetes RBAC 不提供負面(拒絕)訪問規則。
你不應在 API 伺服器可以透過公共網際網路訪問的 Kubernetes 叢集上使用 `AlwaysAllow` 模式。
`system:masters` 組
`system:masters` 組是 Kubernetes 內建組,它授予對 API 伺服器的無限制訪問許可權。分配給此組的任何使用者都擁有完整的叢集管理員許可權,繞過 RBAC 或 Webhook 機制施加的任何授權限制。避免將使用者新增到此組。如果你確實需要授予使用者叢集管理員許可權,可以建立指向內建 `cluster-admin` ClusterRole 的ClusterRoleBinding。
授權模式配置
你可以使用配置檔案或命令列引數來配置 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
# If set to false, 'authorized' responses from the webhook are not cached
# and the specified authorizedTTL is ignored/has no effect.
# Same as setting `--authorization-webhook-cache-authorized-ttl` flag to `0`.
# Note: Setting authorizedTTL to `0` results in its default value being used.
# Default: true
cacheAuthorizedRequests: true
# The duration to cache 'unauthorized' responses from the webhook
# authorizer.
# Same as setting `--authorization-webhook-cache-unauthorized-ttl` flag
# Default: 30s
unauthorizedTTL: 30s
# If set to false, 'unauthorized' responses from the webhook are not cached
# and the specified unauthorizedTTL is ignored/has no effect.
# Same as setting `--authorization-webhook-cache-unauthorized-ttl` flag to `0`.
# Note: Setting unauthorizedTTL to `0` results in its default value being used.
# Default: true
cacheUnauthorizedRequests: true
# 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.club.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.33 升級到 Kubernetes 1.34,你需要確保配置檔案採用 Kubernetes 1.34 可以理解的格式,然後才能升級叢集。如果降級到 1.33,你需要適當地設定配置。
授權配置和重新載入
當 API 伺服器觀察到檔案更改時,Kubernetes 會重新載入授權配置檔案;如果在 60 秒內沒有觀察到更改事件,也會按 60 秒的計劃重新載入。
注意
你必須確保所有非 Webhook 授權器型別在重新載入時在檔案中保持不變。
重新載入**不能**新增或刪除 Node 或 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` 參考。
透過建立或編輯工作負載進行特權升級
允許在名稱空間中建立/編輯 Pods 的使用者(無論是直接還是透過啟用間接工作負載管理的物件)可能能夠升級他們在該名稱空間中的特權。潛在的特權升級途徑包括 Kubernetes API 擴充套件及其關聯的控制器。
注意
作為叢集管理員,在授予建立或編輯工作負載的許可權時要小心。有關如何濫用這些許可權的一些詳細資訊記錄在升級路徑中。升級路徑
如果你允許攻擊者或不可信使用者在該名稱空間中執行任意 Pods,那麼他們可以透過以下不同方式在該名稱空間中獲得額外特權:
- 在該名稱空間中掛載任意 Secret
- 可用於訪問為其他工作負載準備的機密資訊
- 可用於獲取許可權更高的 ServiceAccount 的服務賬戶令牌
- 在該名稱空間中使用任意 ServiceAccounts
- 可以作為其他工作負載執行 Kubernetes API 操作(模擬)
- 可以執行該 ServiceAccount 擁有的任何特權操作
- 掛載或使用為該名稱空間中其他工作負載準備的 ConfigMaps
- 可用於獲取為其他工作負載準備的資訊,例如資料庫主機名。
- 在該名稱空間中掛載為其他工作負載準備的卷
- 可用於獲取為其他工作負載準備的資訊,並對其進行更改。
注意
作為系統管理員,在部署允許使用者更改上述區域的 CustomResourceDefinitions 時,應該謹慎。這些可能會開啟特權升級路徑。在決定授權控制時,請考慮此類更改的後果。檢查 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` 中列出 Pods:
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 隱藏/顯示操作很有用。
這些 API 可以透過建立正常的 Kubernetes 資源進行查詢,其中返回物件的響應 `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 中的通用表示式語言的更多資訊。