使用 RBAC 授權
基於角色的存取控制 (RBAC) 是一種根據組織內個別使用者的角色來規範對電腦或網路資源存取的方法。
RBAC 授權使用 rbac.authorization.k8s.io
API 群組 來驅動授權決策,讓您透過 Kubernetes API 動態設定策略。
若要啟用 RBAC,請啟動 API 伺服器,並將 --authorization-config
旗標設定為包含 RBAC
授權器的檔案;例如
apiVersion: apiserver.config.k8s.io/v1
kind: AuthorizationConfiguration
authorizers:
...
- type: RBAC
...
或者,啟動 API 伺服器,並將 --authorization-mode
旗標設定為包含 RBAC
的逗號分隔清單;例如
kube-apiserver --authorization-mode=...,RBAC --other-options --more-options
API 物件
RBAC API 宣告四種類型的 Kubernetes 物件:Role、ClusterRole、RoleBinding 和 ClusterRoleBinding。您可以像其他任何 Kubernetes 物件一樣,使用 kubectl
等工具來描述或修改 RBAC 物件。
注意
這些物件在設計上會施加存取限制。如果您在學習時對叢集進行變更,請參閱權限提升預防與引導,以了解這些限制如何阻止您進行某些變更。Role 與 ClusterRole
RBAC Role 或 ClusterRole 包含代表一組權限的規則。權限是純粹累加的(沒有「拒絕」規則)。
Role 始終在特定的命名空間內設定權限;當您建立 Role 時,必須指定它所屬的命名空間。
ClusterRole 相反,是一種非命名空間資源。資源具有不同的名稱(Role 和 ClusterRole),因為 Kubernetes 物件始終必須是命名空間或非命名空間;它不能兩者兼具。
ClusterRole 有幾種用途。您可以使用 ClusterRole 來
- 定義命名空間資源的權限,並在個別命名空間中授予存取權
- 定義命名空間資源的權限,並在所有命名空間中授予存取權
- 定義叢集範圍資源的權限
如果您想在命名空間內定義角色,請使用 Role;如果您想定義叢集範圍的角色,請使用 ClusterRole。
Role 範例
以下是「預設」命名空間中的 Role 範例,可用於授予對 pod 的讀取權限
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
resources: ["pods"]
verbs: ["get", "watch", "list"]
ClusterRole 範例
ClusterRole 可用於授予與 Role 相同的權限。由於 ClusterRole 是叢集範圍的,因此您也可以使用它們來授予對以下項目的存取權
叢集範圍資源(例如 節點)
非資源端點(例如
/healthz
)跨所有命名空間的命名空間資源(例如 Pod)
例如:您可以使用 ClusterRole 允許特定使用者執行
kubectl get pods --all-namespaces
以下是 ClusterRole 的範例,可用於授予對任何特定命名空間或跨所有命名空間中的 secret 的讀取權限(取決於它的繫結方式)
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
# "namespace" omitted since ClusterRoles are not namespaced
name: secret-reader
rules:
- apiGroups: [""]
#
# at the HTTP level, the name of the resource for accessing Secret
# objects is "secrets"
resources: ["secrets"]
verbs: ["get", "watch", "list"]
Role 或 ClusterRole 物件的名稱必須是有效的路徑區段名稱。
RoleBinding 與 ClusterRoleBinding
角色繫結會將角色中定義的權限授予使用者或一組使用者。它包含 subjects(使用者、群組或服務帳戶)的清單,以及對正在授予的角色的參考。RoleBinding 在特定命名空間內授予權限,而 ClusterRoleBinding 則在叢集範圍內授予該存取權。
RoleBinding 可能會參照相同命名空間中的任何 Role。或者,RoleBinding 可以參照 ClusterRole,並將該 ClusterRole 繫結至 RoleBinding 的命名空間。如果您想要將 ClusterRole 繫結至叢集中的所有命名空間,您可以使用 ClusterRoleBinding。
RoleBinding 或 ClusterRoleBinding 物件的名稱必須是有效的路徑區段名稱。
RoleBinding 範例
以下是一個 RoleBinding 的範例,它將 "pod-reader" Role 授與給 "default" 命名空間中的使用者 "jane"。這允許 "jane" 讀取 "default" 命名空間中的 Pod。
apiVersion: rbac.authorization.k8s.io/v1
# This role binding allows "jane" to read pods in the "default" namespace.
# You need to already have a Role named "pod-reader" in that namespace.
kind: RoleBinding
metadata:
name: read-pods
namespace: default
subjects:
# You can specify more than one "subject"
- kind: User
name: jane # "name" is case sensitive
apiGroup: rbac.authorization.k8s.io
roleRef:
# "roleRef" specifies the binding to a Role / ClusterRole
kind: Role #this must be Role or ClusterRole
name: pod-reader # this must match the name of the Role or ClusterRole you wish to bind to
apiGroup: rbac.authorization.k8s.io
RoleBinding 也可以參照 ClusterRole,以將該 ClusterRole 中定義的權限授與給 RoleBinding 命名空間內的資源。這種參照方式讓您可以在叢集中定義一組通用的角色,然後在多個命名空間中重複使用它們。
例如,即使以下 RoleBinding 參照了 ClusterRole,"dave" (主體,區分大小寫) 也只能讀取 "development" 命名空間中的 Secrets,因為 RoleBinding 的命名空間 (在其 metadata 中) 是 "development"。
apiVersion: rbac.authorization.k8s.io/v1
# This role binding allows "dave" to read secrets in the "development" namespace.
# You need to already have a ClusterRole named "secret-reader".
kind: RoleBinding
metadata:
name: read-secrets
#
# The namespace of the RoleBinding determines where the permissions are granted.
# This only grants permissions within the "development" namespace.
namespace: development
subjects:
- kind: User
name: dave # Name is case sensitive
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
ClusterRoleBinding 範例
若要跨整個叢集授與權限,您可以使用 ClusterRoleBinding。以下 ClusterRoleBinding 允許 "manager" 群組中的任何使用者讀取任何命名空間中的 Secrets。
apiVersion: rbac.authorization.k8s.io/v1
# This cluster role binding allows anyone in the "manager" group to read secrets in any namespace.
kind: ClusterRoleBinding
metadata:
name: read-secrets-global
subjects:
- kind: Group
name: manager # Name is case sensitive
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
建立繫結後,您就無法變更其參照的 Role 或 ClusterRole。如果您嘗試變更繫結的 roleRef
,您會收到驗證錯誤。如果您確實想要變更繫結的 roleRef
,您需要移除該繫結物件並建立一個替代物件。
此限制有兩個原因
- 使
roleRef
不可變更,允許授與某人現有繫結物件的update
權限,以便他們可以管理主體清單,而無需變更授與給這些主體的角色。 - 繫結至不同的角色在本質上是不同的繫結。要求為了變更
roleRef
而刪除/重新建立繫結,可確保繫結中的完整主體清單旨在被授與新的角色 (而不是僅啟用或意外修改 roleRef 而未驗證是否應將新角色的權限授與給所有現有的主體)。
kubectl auth reconcile
命令列工具會建立或更新包含 RBAC 物件的清單檔案,並在需要變更其參照的角色時處理刪除和重新建立繫結物件。請參閱命令用法和範例以取得更多資訊。
參照資源
在 Kubernetes API 中,大多數資源都使用其物件名稱的字串表示形式來表示和存取,例如 Pod 的 pods
。RBAC 使用與相關 API 端點 URL 中顯示的完全相同的名稱來參照資源。某些 Kubernetes API 涉及子資源,例如 Pod 的日誌。對 Pod 日誌的請求看起來像這樣
GET /api/v1/namespaces/{namespace}/pods/{name}/log
在這種情況下,pods
是 Pod 資源的命名空間資源,而 log
是 pods
的子資源。若要在 RBAC 角色中表示這一點,請使用斜線 (/
) 來分隔資源和子資源。若要允許主體讀取 pods
並存取每個 Pod 的 log
子資源,您可以撰寫
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-and-pod-logs-reader
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list"]
您也可以透過 resourceNames
清單,依名稱參照特定請求的資源。指定後,請求可以限制為資源的個別實例。以下範例限制其主體只能 get
或 update
名為 my-configmap
的 ConfigMap
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: configmap-updater
rules:
- apiGroups: [""]
#
# at the HTTP level, the name of the resource for accessing ConfigMap
# objects is "configmaps"
resources: ["configmaps"]
resourceNames: ["my-configmap"]
verbs: ["update", "get"]
注意
您無法依資源名稱限制create
或 deletecollection
請求。對於 create
,此限制是因為在授權時可能不知道新物件的名稱。如果您依 resourceName 限制 list
或 watch
,用戶端必須在其 list
或 watch
請求中包含符合指定 resourceName 的 metadata.name
欄位選取器,才能獲得授權。例如,kubectl get configmaps --field-selector=metadata.name=my-configmap
您可以不用參照個別的 resources
、apiGroups
和 verbs
,而是使用萬用字元 *
符號來參照所有此類物件。對於 nonResourceURLs
,您可以使用萬用字元 *
作為後綴全域比對。對於 resourceNames
,空集合表示允許所有項目。以下範例允許對 example.com
API 群組中所有目前和未來的資源執行任何目前和未來的動作。這與內建的 cluster-admin
角色類似。
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: example.com-superuser # DO NOT USE THIS ROLE, IT IS JUST AN EXAMPLE
rules:
- apiGroups: ["example.com"]
resources: ["*"]
verbs: ["*"]
注意
在資源和動詞條目中使用萬用字元可能會導致對敏感資源授與過於寬鬆的存取權限。例如,如果新增了新的資源類型,或新增了新的子資源,或檢查了新的自訂動詞,則萬用字元條目會自動授與存取權限,這可能是不希望發生的。最小權限原則應被採用,使用特定的資源和動詞,以確保僅套用工作負載正確運作所需的權限。彙總的 ClusterRole
您可以將多個 ClusterRole 彙總為一個組合的 ClusterRole。作為叢集控制平面一部分執行的控制器,會監看設定了 aggregationRule
的 ClusterRole 物件。aggregationRule
定義了一個標籤選取器,控制器使用它來比對其他應組合到此物件 rules
欄位中的 ClusterRole 物件。
注意
控制平面會覆寫您在彙總 ClusterRole 的rules
欄位中手動指定的任何值。如果您想要變更或新增規則,請在 aggregationRule
選取的 ClusterRole
物件中執行此操作。以下是彙總的 ClusterRole 範例
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: monitoring
aggregationRule:
clusterRoleSelectors:
- matchLabels:
rbac.example.com/aggregate-to-monitoring: "true"
rules: [] # The control plane automatically fills in the rules
如果您建立一個新的 ClusterRole,它符合現有彙總 ClusterRole 的標籤選取器,則該變更會觸發將新規則新增到彙總 ClusterRole 中。以下範例透過建立另一個標籤為 rbac.example.com/aggregate-to-monitoring: true
的 ClusterRole,將規則新增到 "monitoring" ClusterRole。
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: monitoring-endpoints
labels:
rbac.example.com/aggregate-to-monitoring: "true"
# When you create the "monitoring-endpoints" ClusterRole,
# the rules below will be added to the "monitoring" ClusterRole.
rules:
- apiGroups: [""]
resources: ["services", "endpointslices", "pods"]
verbs: ["get", "list", "watch"]
預設的使用者導向角色使用 ClusterRole 彙總。這讓您作為叢集管理員,可以包含自訂資源的規則,例如由 CustomResourceDefinitions 或彙總的 API 伺服器提供的資源,以擴充預設角色。
例如:以下 ClusterRole 允許 "admin" 和 "edit" 預設角色管理名為 CronTab 的自訂資源,而 "view" 角色只能對 CronTab 資源執行讀取動作。您可以假設 CronTab 物件在 API 伺服器看到的 URL 中名為 "crontabs"
。
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: aggregate-cron-tabs-edit
labels:
# Add these permissions to the "admin" and "edit" default roles.
rbac.authorization.k8s.io/aggregate-to-admin: "true"
rbac.authorization.k8s.io/aggregate-to-edit: "true"
rules:
- apiGroups: ["stable.example.com"]
resources: ["crontabs"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: aggregate-cron-tabs-view
labels:
# Add these permissions to the "view" default role.
rbac.authorization.k8s.io/aggregate-to-view: "true"
rules:
- apiGroups: ["stable.example.com"]
resources: ["crontabs"]
verbs: ["get", "list", "watch"]
角色範例
以下範例是 Role 或 ClusterRole 物件的摘錄,僅顯示 rules
區段。
允許讀取核心 API 群組中的 "pods"
資源
rules:
- apiGroups: [""]
#
# at the HTTP level, the name of the resource for accessing Pod
# objects is "pods"
resources: ["pods"]
verbs: ["get", "list", "watch"]
允許在 "apps"
API 群組中讀取/寫入 Deployments (在 HTTP 層級:URL 的資源部分中具有 "deployments"
的物件)
rules:
- apiGroups: ["apps"]
#
# at the HTTP level, the name of the resource for accessing Deployment
# objects is "deployments"
resources: ["deployments"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
允許讀取核心 API 群組中的 Pod,以及讀取或寫入 "batch"
API 群組中的 Job 資源
rules:
- apiGroups: [""]
#
# at the HTTP level, the name of the resource for accessing Pod
# objects is "pods"
resources: ["pods"]
verbs: ["get", "list", "watch"]
- apiGroups: ["batch"]
#
# at the HTTP level, the name of the resource for accessing Job
# objects is "jobs"
resources: ["jobs"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
允許讀取名為 "my-config" 的 ConfigMap (必須與 RoleBinding 繫結,以限制為單一命名空間中的單一 ConfigMap)
rules:
- apiGroups: [""]
#
# at the HTTP level, the name of the resource for accessing ConfigMap
# objects is "configmaps"
resources: ["configmaps"]
resourceNames: ["my-config"]
verbs: ["get"]
允許讀取核心群組中的資源 "nodes"
(由於 Node 是叢集範圍的,因此必須在與 ClusterRoleBinding 繫結的 ClusterRole 中才能生效)
rules:
- apiGroups: [""]
#
# at the HTTP level, the name of the resource for accessing Node
# objects is "nodes"
resources: ["nodes"]
verbs: ["get", "list", "watch"]
允許對非資源端點 /healthz
和所有子路徑發出 GET 和 POST 請求 (必須在與 ClusterRoleBinding 繫結的 ClusterRole 中才能生效)
rules:
- nonResourceURLs: ["/healthz", "/healthz/*"] # '*' in a nonResourceURL is a suffix glob match
verbs: ["get", "post"]
參照主體
RoleBinding 或 ClusterRoleBinding 將角色繫結至主體。主體可以是群組、使用者或 ServiceAccount。
Kubernetes 將使用者名稱表示為字串。這些可以是:純名稱,例如 "alice";電子郵件樣式名稱,如 "bob@example.com";或表示為字串的數字使用者 ID。作為叢集管理員,您有責任組態身分驗證模組,以便身分驗證產生您想要的格式的使用者名稱。
注意
前綴system:
保留供 Kubernetes 系統使用,因此您應確保您沒有以 system:
開頭的名稱的使用者或群組,以避免意外。除了這個特殊的前綴之外,RBAC 授權系統不要求使用者名稱的任何格式。在 Kubernetes 中,Authenticator 模組提供群組資訊。群組與使用者一樣,表示為字串,並且該字串沒有格式要求,除了前綴 system:
是保留的。
ServiceAccount 的名稱以 system:serviceaccount:
為前綴,並屬於名稱以 system:serviceaccounts:
為前綴的群組。
注意
system:serviceaccount:
(單數) 是服務帳戶使用者名稱的前綴。system:serviceaccounts:
(複數) 是服務帳戶群組的前綴。
RoleBinding 範例
以下範例是 RoleBinding
摘錄,僅顯示 subjects
區段。
對於名為 alice@example.com
的使用者
subjects:
- kind: User
name: "alice@example.com"
apiGroup: rbac.authorization.k8s.io
對於名為 frontend-admins
的群組
subjects:
- kind: Group
name: "frontend-admins"
apiGroup: rbac.authorization.k8s.io
對於 "kube-system" 命名空間中的預設服務帳戶
subjects:
- kind: ServiceAccount
name: default
namespace: kube-system
對於 "qa" 命名空間中的所有服務帳戶
subjects:
- kind: Group
name: system:serviceaccounts:qa
apiGroup: rbac.authorization.k8s.io
對於任何命名空間中的所有服務帳戶
subjects:
- kind: Group
name: system:serviceaccounts
apiGroup: rbac.authorization.k8s.io
對於所有已驗證的使用者
subjects:
- kind: Group
name: system:authenticated
apiGroup: rbac.authorization.k8s.io
對於所有未經驗證的使用者
subjects:
- kind: Group
name: system:unauthenticated
apiGroup: rbac.authorization.k8s.io
對於所有使用者
subjects:
- kind: Group
name: system:authenticated
apiGroup: rbac.authorization.k8s.io
- kind: Group
name: system:unauthenticated
apiGroup: rbac.authorization.k8s.io
預設角色和角色繫結
API 伺服器會建立一組預設的 ClusterRole 和 ClusterRoleBinding 物件。其中許多都帶有 system:
前綴,表示該資源由叢集控制平面直接管理。所有預設的 ClusterRole 和 ClusterRoleBinding 都標有 kubernetes.io/bootstrapping=rbac-defaults
標籤。
注意
修改名稱帶有system:
前綴的 ClusterRole 和 ClusterRoleBinding 時,請務必小心。對這些資源的修改可能會導致叢集無法運作。自動協調
在每次啟動時,API 伺服器都會使用任何遺失的權限來更新預設叢集角色,並使用任何遺失的主體來更新預設叢集角色繫結。這允許叢集修復意外的修改,並有助於在新的 Kubernetes 版本中權限和主體變更時,保持角色和角色繫結為最新狀態。
若要選擇退出此協調,請將預設叢集角色或預設叢集 RoleBinding 上的 rbac.authorization.kubernetes.io/autoupdate
註解設定為 false
。請注意,遺失預設權限和主體可能會導致叢集無法運作。
如果 RBAC 授權器處於活動狀態,則預設會啟用自動協調。
API 探索角色
預設叢集角色繫結授權未經驗證和已驗證的使用者讀取被視為可公開存取的 API 資訊 (包括 CustomResourceDefinitions)。若要停用匿名未經驗證的存取,請將 --anonymous-auth=false
標誌新增至 API 伺服器組態。
若要透過 kubectl
檢視這些角色的組態,請執行
kubectl get clusterroles system:discovery -o yaml
注意
如果您編輯該 ClusterRole,您的變更將在 API 伺服器重新啟動時透過自動協調覆寫。若要避免該覆寫,請勿手動編輯角色,或停用自動協調。預設 ClusterRole | 預設 ClusterRoleBinding | 描述 |
---|---|---|
system:basic-user | system:authenticated 群組 | 允許使用者對自己的基本資訊進行唯讀存取。在 v1.14 之前,此角色也預設繫結至system:unauthenticated。 |
system:discovery | system:authenticated 群組 | 允許對 API 探索端點進行唯讀存取,這些端點是探索和協商 API 層級所需的。在 v1.14 之前,此角色也繫結至system:unauthenticated。 |
system:public-info-viewer | system:authenticated 和 system:unauthenticated 群組 | 允許對叢集的非敏感資訊進行唯讀存取。在 Kubernetes v1.14 中導入。 |
使用者導向角色
某些預設 ClusterRole 沒有 system:
前綴。這些是旨在成為使用者導向的角色。它們包括超級使用者角色 (cluster-admin
)、旨在透過 ClusterRoleBinding 在叢集範圍內授與的角色,以及旨在透過 RoleBinding 在特定命名空間內授與的角色 (admin
、edit
、view
)。
使用者導向的 ClusterRole 使用ClusterRole 彙總,以允許管理員在這些 ClusterRole 上包含自訂資源的規則。若要將規則新增至 admin
、edit
或 view
角色,請建立具有以下一個或多個標籤的 ClusterRole
metadata:
labels:
rbac.authorization.k8s.io/aggregate-to-admin: "true"
rbac.authorization.k8s.io/aggregate-to-edit: "true"
rbac.authorization.k8s.io/aggregate-to-view: "true"
預設 ClusterRole | 預設 ClusterRoleBinding | 描述 |
---|---|---|
cluster-admin | system:masters 群組 | 允許超級使用者存取權限,以對任何資源執行任何動作。在 ClusterRoleBinding 中使用時,它會授予對叢集中和所有命名空間中每個資源的完全控制權。在 RoleBinding 中使用時,它會授予對角色繫結命名空間中每個資源 (包括命名空間本身) 的完全控制權。 |
admin | 無 | 允許管理員存取權限,旨在透過 RoleBinding 在命名空間內授與。 如果在 RoleBinding 中使用,則允許對命名空間中大多數資源進行讀寫存取,包括在命名空間內建立角色和角色繫結的能力。此角色不允許寫入資源配額或命名空間本身。此角色也不允許寫入 Kubernetes v1.22+ 建立的叢集中的 EndpointSlices (或 Endpoints)。更多資訊請參閱「EndpointSlices 和 Endpoints 的寫入存取權限」區段。 |
edit | 無 | 允許對命名空間中的大多數物件進行讀寫存取。 此角色不允許檢視或修改角色或角色繫結。但是,此角色允許以命名空間中任何 ServiceAccount 的身分存取 Secrets 和執行 Pod,因此可用於取得命名空間中任何 ServiceAccount 的 API 存取層級。此角色也不允許寫入 Kubernetes v1.22+ 建立的叢集中的 EndpointSlices (或 Endpoints)。更多資訊請參閱「EndpointSlices 和 Endpoints 的寫入存取權限」區段。 |
view | 無 | 允許唯讀存取權限,以檢視命名空間中的大多數物件。它不允許檢視角色或角色繫結。 此角色不允許檢視 Secrets,因為讀取 Secrets 的內容會啟用對命名空間中 ServiceAccount 憑證的存取,這將允許以命名空間中任何 ServiceAccount 的身分進行 API 存取 (一種權限提升形式)。 |
核心組件角色
預設 ClusterRole | 預設 ClusterRoleBinding | 描述 |
---|---|---|
system:kube-scheduler | system:kube-scheduler 使用者 | 允許存取 排程器組件所需的資源。 |
system:volume-scheduler | system:kube-scheduler 使用者 | 允許存取 kube-scheduler 組件所需的磁碟區資源。 |
system:kube-controller-manager | system:kube-controller-manager 使用者 | 允許存取 控制器管理器組件所需的資源。個別控制器所需的權限在控制器角色中詳細說明。 |
system:node | 無 | 允許存取 kubelet 所需的資源,包括對所有 Secrets 的讀取存取權限,以及對所有 pod 狀態物件的寫入存取權限。 您應該使用Node 授權器和 NodeRestriction 許可控制器外掛程式,而不是system:node角色,並允許根據排程在其上執行的 Pod,授與 kubelet API 存取權限。 此system:node角色僅為了與從 v1.8 之前的版本升級的 Kubernetes 叢集相容而存在。 |
system:node-proxier | system:kube-proxy 使用者 | 允許存取 kube-proxy 組件所需的資源。 |
其他組件角色
預設 ClusterRole | 預設 ClusterRoleBinding | 描述 |
---|---|---|
system:auth-delegator | 無 | 允許委派的身分驗證和授權檢查。這通常由附加元件 API 伺服器用於統一的身分驗證和授權。 |
system:heapster | 無 | 用於 Heapster 組件的角色 (已棄用)。 |
system:kube-aggregator | 無 | 用於 kube-aggregator 組件的角色。 |
system:kube-dns | kube-dns 服務帳戶在 kube-system 命名空間中 | 用於 kube-dns 組件的角色。 |
system:kubelet-api-admin | 無 | 允許完全存取 kubelet API。 |
system:node-bootstrapper | 無 | 允許存取執行 kubelet TLS 啟動引導所需的資源。 |
system:node-problem-detector | 無 | 用於 node-problem-detector 組件的角色。 |
system:persistent-volume-provisioner | 無 | 允許存取大多數動態磁碟區佈建器所需的資源。 |
system:monitoring | system:monitoring 群組 | 允許讀取存取控制平面監控端點 (即kube-apiserver 活性和就緒端點 (/healthz, /livez, /readyz)、個別的健康檢查端點 (/healthz/*, /livez/*, /readyz/*) 和/metrics)。請注意,個別的健康檢查端點和指標端點可能會公開敏感資訊。 |
內建控制器的角色
Kubernetes 控制器管理器執行控制器,這些控制器是內建於 Kubernetes 控制平面中的。當使用 --use-service-account-credentials
叫用時,kube-controller-manager 會使用個別的服務帳戶啟動每個控制器。每個內建控制器都存在對應的角色,前綴為 system:controller:
。如果控制器管理器未使用 --use-service-account-credentials
啟動,它會使用自己的憑證執行所有控制迴圈,必須將所有相關角色授與給該憑證。這些角色包括
system:controller:attachdetach-controller
system:controller:certificate-controller
system:controller:clusterrole-aggregation-controller
system:controller:cronjob-controller
system:controller:daemon-set-controller
system:controller:deployment-controller
system:controller:disruption-controller
system:controller:endpoint-controller
system:controller:expand-controller
system:controller:generic-garbage-collector
system:controller:horizontal-pod-autoscaler
system:controller:job-controller
system:controller:namespace-controller
system:controller:node-controller
system:controller:persistent-volume-binder
system:controller:pod-garbage-collector
system:controller:pv-protection-controller
system:controller:pvc-protection-controller
system:controller:replicaset-controller
system:controller:replication-controller
system:controller:resourcequota-controller
system:controller:root-ca-cert-publisher
system:controller:route-controller
system:controller:service-account-controller
system:controller:service-controller
system:controller:statefulset-controller
system:controller:ttl-controller
權限提升預防和啟動引導
RBAC API 防止使用者透過編輯角色或角色繫結來提升權限。由於這是於 API 層級強制執行的,因此即使未使用 RBAC 授權器,它仍然適用。
角色建立或更新的限制
只有在以下至少一項為真的情況下,您才能建立/更新角色
- 您已經擁有角色中包含的所有權限,並且範圍與正在修改的物件相同 (對於 ClusterRole 為叢集範圍,對於 Role 為相同命名空間或叢集範圍)。
- 您被明確授予對
rbac.authorization.k8s.io
API 群組中的roles
或clusterroles
資源執行escalate
動詞的權限。
例如,如果 user-1
沒有叢集範圍內列出 Secrets 的能力,他們就無法建立包含該權限的 ClusterRole。若要允許使用者建立/更新角色
- 授與他們一個允許他們建立/更新 Role 或 ClusterRole 物件的角色 (依所需)。
- 授與他們在他們建立/更新的角色中包含特定權限的權限
- 隱含地,透過給予他們這些權限 (如果他們嘗試建立或修改 Role 或 ClusterRole,但其中包含他們自己未被授與的權限,則 API 請求將被禁止)
- 或明確地允許在
Role
或ClusterRole
中指定任何權限,方法是給予他們在rbac.authorization.k8s.io
API 群組中的roles
或clusterroles
資源上執行escalate
動詞的權限
角色繫結建立或更新的限制
只有在您已經擁有參照角色中包含的所有權限 (範圍與角色繫結相同) 或 您已被授權對參照角色執行 bind
動詞的情況下,您才能建立/更新角色繫結。例如,如果 user-1
沒有叢集範圍內列出 Secrets 的能力,他們就無法建立 ClusterRoleBinding 以繫結至授與該權限的角色。若要允許使用者建立/更新角色繫結
- 授與他們一個允許他們建立/更新 RoleBinding 或 ClusterRoleBinding 物件的角色 (依所需)。
- 授與他們繫結特定角色所需的權限
- 隱含地,透過給予他們角色中包含的權限。
- 明確地,透過給予他們對特定 Role (或 ClusterRole) 執行
bind
動詞的權限。
例如,此 ClusterRole 和 RoleBinding 將允許 user-1
在命名空間 user-1-namespace
中授與其他使用者 admin
、edit
和 view
角色
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: role-grantor
rules:
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["rolebindings"]
verbs: ["create"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["clusterroles"]
verbs: ["bind"]
# omit resourceNames to allow binding any ClusterRole
resourceNames: ["admin","edit","view"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: role-grantor-binding
namespace: user-1-namespace
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: role-grantor
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: user-1
在啟動引導第一個角色和角色繫結時,初始使用者必須授與他們尚未擁有的權限。若要啟動引導初始角色和角色繫結
- 使用具有 "system:masters" 群組的憑證,該憑證預設繫結至 "cluster-admin" 超級使用者角色。
命令列工具
kubectl create role
建立 Role 物件,定義單一命名空間內的權限。範例
建立名為 "pod-reader" 的 Role,允許使用者對 Pod 執行
get
、watch
和list
kubectl create role pod-reader --verb=get --verb=list --verb=watch --resource=pods
建立名為 "pod-reader" 的 Role,並指定 resourceNames
kubectl create role pod-reader --verb=get --resource=pods --resource-name=readablepod --resource-name=anotherpod
建立名為 "foo" 的 Role,並指定 apiGroups
kubectl create role foo --verb=get,list,watch --resource=replicasets.apps
建立名為 "foo" 的 Role,並指定子資源權限
kubectl create role foo --verb=get,list,watch --resource=pods,pods/status
建立名為 "my-component-lease-holder" 的 Role,並具有取得/更新具有特定名稱的資源的權限
kubectl create role my-component-lease-holder --verb=get,list,watch,update --resource=lease --resource-name=my-component
kubectl create clusterrole
建立 ClusterRole。範例
建立名為 "pod-reader" 的 ClusterRole,允許使用者對 Pod 執行
get
、watch
和list
kubectl create clusterrole pod-reader --verb=get,list,watch --resource=pods
建立名為 "pod-reader" 的 ClusterRole,並指定 resourceNames
kubectl create clusterrole pod-reader --verb=get --resource=pods --resource-name=readablepod --resource-name=anotherpod
建立名為 "foo" 的 ClusterRole,並指定 apiGroups
kubectl create clusterrole foo --verb=get,list,watch --resource=replicasets.apps
建立名為 "foo" 的 ClusterRole,並指定子資源權限
kubectl create clusterrole foo --verb=get,list,watch --resource=pods,pods/status
建立名為 "foo" 的 ClusterRole,並指定 nonResourceURL
kubectl create clusterrole "foo" --verb=get --non-resource-url=/logs/*
建立名為 "monitoring" 的 ClusterRole,並指定 aggregationRule
kubectl create clusterrole monitoring --aggregation-rule="rbac.example.com/aggregate-to-monitoring=true"
kubectl create rolebinding
在特定命名空間內授與 Role 或 ClusterRole。範例
在 "acme" 命名空間內,將 "admin" ClusterRole 中的權限授與給名為 "bob" 的使用者
kubectl create rolebinding bob-admin-binding --clusterrole=admin --user=bob --namespace=acme
在 "acme" 命名空間內,將 "view" ClusterRole 中的權限授與給 "acme" 命名空間中名為 "myapp" 的服務帳戶
kubectl create rolebinding myapp-view-binding --clusterrole=view --serviceaccount=acme:myapp --namespace=acme
在 "acme" 命名空間內,將 "view" ClusterRole 中的權限授與給 "myappnamespace" 命名空間中名為 "myapp" 的服務帳戶
kubectl create rolebinding myappnamespace-myapp-view-binding --clusterrole=view --serviceaccount=myappnamespace:myapp --namespace=acme
kubectl create clusterrolebinding
跨整個叢集 (所有命名空間) 授與 ClusterRole。範例
跨整個叢集,將 "cluster-admin" ClusterRole 中的權限授與給名為 "root" 的使用者
kubectl create clusterrolebinding root-cluster-admin-binding --clusterrole=cluster-admin --user=root
跨整個叢集,將 "system:node-proxier" ClusterRole 中的權限授與給名為 "system:kube-proxy" 的使用者
kubectl create clusterrolebinding kube-proxy-binding --clusterrole=system:node-proxier --user=system:kube-proxy
跨整個叢集,將 "view" ClusterRole 中的權限授與給 "acme" 命名空間中名為 "myapp" 的服務帳戶
kubectl create clusterrolebinding myapp-view-binding --clusterrole=view --serviceaccount=acme:myapp
kubectl auth reconcile
從清單檔案建立或更新 rbac.authorization.k8s.io/v1
API 物件。
如果遺失物件,則會建立這些物件,並且如果需要,則會為命名空間物件建立包含命名空間。
現有的角色會更新為包含輸入物件中的權限,如果指定了 --remove-extra-permissions
,則會移除額外的權限。
現有的繫結會更新為包含輸入物件中的主體,如果指定了 --remove-extra-subjects
,則會移除額外的主體。
範例
測試套用 RBAC 物件的清單檔案,顯示將進行的變更
kubectl auth reconcile -f my-rbac-rules.yaml --dry-run=client
套用 RBAC 物件的清單檔案,保留任何額外的權限 (在角色中) 和任何額外的主體 (在繫結中)
kubectl auth reconcile -f my-rbac-rules.yaml
套用 RBAC 物件的清單檔案,移除任何額外的權限 (在角色中) 和任何額外的主體 (在繫結中)
kubectl auth reconcile -f my-rbac-rules.yaml --remove-extra-subjects --remove-extra-permissions
ServiceAccount 權限
預設 RBAC 原則將範圍權限授與給控制平面組件、節點和控制器,但未將權限授與給 kube-system
命名空間之外的服務帳戶 (超出 API 探索角色授予的權限)。
這允許您根據需要將特定角色授與給特定的 ServiceAccount。細緻的角色繫結提供更高的安全性,但需要更多的管理工作。更廣泛的授與可能會為 ServiceAccount 提供不必要 (且可能升級) 的 API 存取權限,但更易於管理。
從最安全到最不安全的順序,方法如下
將角色授與給應用程式特定的服務帳戶 (最佳實務)
這需要應用程式在其 Pod 規格中指定
serviceAccountName
,並建立服務帳戶 (透過 API、應用程式清單檔案、kubectl create serviceaccount
等)。例如,在 "my-namespace" 內將唯讀權限授與給 "my-sa" 服務帳戶
kubectl create rolebinding my-sa-view \ --clusterrole=view \ --serviceaccount=my-namespace:my-sa \ --namespace=my-namespace
將角色授與給命名空間中的 "default" 服務帳戶
如果應用程式未指定
serviceAccountName
,則會使用 "default" 服務帳戶。注意
授與給 "default" 服務帳戶的權限適用於命名空間中任何未指定serviceAccountName
的 Pod。例如,在 "my-namespace" 內將唯讀權限授與給 "default" 服務帳戶
kubectl create rolebinding default-view \ --clusterrole=view \ --serviceaccount=my-namespace:default \ --namespace=my-namespace
許多附加元件以
kube-system
命名空間中的 "default" 服務帳戶身分執行。若要允許這些附加元件以超級使用者存取權限執行,請將叢集管理員權限授與給kube-system
命名空間中的 "default" 服務帳戶。注意
啟用此功能表示kube-system
命名空間包含授予對叢集 API 超級使用者存取權限的 Secrets。kubectl create clusterrolebinding add-on-cluster-admin \ --clusterrole=cluster-admin \ --serviceaccount=kube-system:default
將角色授與給命名空間中的所有服務帳戶
如果您希望命名空間中的所有應用程式都具有角色,無論它們使用哪個服務帳戶,您都可以將角色授與給該命名空間的服務帳戶群組。
例如,在 "my-namespace" 內將唯讀權限授與給該命名空間中的所有服務帳戶
kubectl create rolebinding serviceaccounts-view \ --clusterrole=view \ --group=system:serviceaccounts:my-namespace \ --namespace=my-namespace
將有限的角色授與給叢集範圍內的所有服務帳戶 (不建議)
如果您不想管理每個命名空間的權限,您可以將叢集範圍的角色授與給所有服務帳戶。
例如,跨所有命名空間將唯讀權限授與給叢集中所有服務帳戶
kubectl create clusterrolebinding serviceaccounts-view \ --clusterrole=view \ --group=system:serviceaccounts
將超級使用者存取權限授與給叢集範圍內的所有服務帳戶 (強烈不建議)
如果您完全不在意分割權限,您可以將超級使用者存取權限授與給所有服務帳戶。
警告
這允許任何應用程式完全存取您的叢集,並且還授予任何具有 Secrets 讀取權限 (或建立任何 Pod 能力) 的使用者完全存取您的叢集的權限。kubectl create clusterrolebinding serviceaccounts-cluster-admin \ --clusterrole=cluster-admin \ --group=system:serviceaccounts
EndpointSlices 和 Endpoints 的寫入存取權限
在 Kubernetes v1.22 之前建立的 Kubernetes 叢集在彙總的 "edit" 和 "admin" 角色中包含對 EndpointSlices (和 Endpoints) 的寫入存取權限。作為 CVE-2021-25740 的緩解措施,此存取權限不屬於您使用 Kubernetes v1.22 或更高版本建立的叢集中的彙總角色。
已升級至 Kubernetes v1.22 的現有叢集將不受此變更影響。CVE 公告包含限制現有叢集中此存取權的指南。
如果您希望新的叢集在聚合角色中保留此存取權層級,您可以建立以下 ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
annotations:
kubernetes.io/description: |-
Add endpoints write permissions to the edit and admin roles. This was
removed by default in 1.22 because of CVE-2021-25740. See
https://issue.k8s.io/103675. This can allow writers to direct LoadBalancer
or Ingress implementations to expose backend IPs that would not otherwise
be accessible, and can circumvent network policies or security controls
intended to prevent/isolate access to those backends.
EndpointSlices were never included in the edit or admin roles, so there
is nothing to restore for the EndpointSlice API.
labels:
rbac.authorization.k8s.io/aggregate-to-edit: "true"
name: custom:aggregate-to-edit:endpoints # you can change this if you wish
rules:
- apiGroups: [""]
resources: ["endpoints"]
verbs: ["create", "delete", "deletecollection", "patch", "update"]
從 ABAC 升級
最初執行舊版 Kubernetes 的叢集通常使用寬鬆的 ABAC 策略,包括授予所有服務帳戶完整的 API 存取權。
預設 RBAC 原則將範圍權限授與給控制平面組件、節點和控制器,但未將權限授與給 kube-system
命名空間之外的服務帳戶 (超出 API 探索角色授予的權限)。
雖然安全性更高,但這可能會對期望自動接收 API 權限的現有工作負載造成干擾。以下是管理此轉換的兩種方法
並行授權器
同時執行 RBAC 和 ABAC 授權器,並指定包含舊版 ABAC 策略的策略檔案
--authorization-mode=...,RBAC,ABAC --authorization-policy-file=mypolicy.json
詳細說明第一個命令列選項:如果先前的授權器(例如 Node)拒絕請求,則 RBAC 授權器會嘗試授權 API 請求。如果 RBAC 也拒絕該 API 請求,則會接著執行 ABAC 授權器。這表示任何請求只要符合 RBAC 或 ABAC 策略其中之一,就會被允許。
當 kube-apiserver 在 RBAC 組件的日誌層級為 5 或更高時執行 (--vmodule=rbac*=5
或 --v=5
),您可以在 API 伺服器日誌中看到 RBAC 拒絕訊息(前綴為 RBAC
)。您可以使用該資訊來判斷哪些角色需要授予哪些使用者、群組或服務帳戶。
一旦您將角色授予服務帳戶,且工作負載在伺服器日誌中沒有 RBAC 拒絕訊息的情況下執行,您就可以移除 ABAC 授權器。
寬鬆的 RBAC 權限
您可以使用 RBAC 角色綁定來複製寬鬆的 ABAC 策略。
警告
以下策略允許所有服務帳戶充當叢集管理員。任何在容器中執行的應用程式都會自動接收服務帳戶憑證,並且可以對 API 執行任何操作,包括檢視密鑰和修改權限。這不是建議的策略。
kubectl create clusterrolebinding permissive-binding \
--clusterrole=cluster-admin \
--user=admin \
--user=kubelet \
--group=system:serviceaccounts
在您轉換為使用 RBAC 之後,您應該調整叢集的存取控制,以確保這些控制符合您的資訊安全需求。