【解構雲原生】K8s 的 RBAC - 基於角色的訪問控制
本文由作者授權釋出,未經許可,請勿轉載。
作者:李嵐清,網易數帆輕舟事業部資深工程師
基於角色的訪問控制(Role-Based Access Control, 即“RBAC”)使用 “rbac.authorization.k8s.io” API Group 實現授權控制,使用者可以通過 Kubernetes API 動態配置策略。
API 物件
RBAC 共包含4個型別的資源物件:Role、ClusterRole、RoleBinding、ClusterRoleBinding
。使用者可以通過增刪改查上述四個API物件來實現訪問許可權的動態控制。
假如沒有建立任何ClusterRole和Role,則所有使用者是無許可權訪問任何K8S的API的,K8S的許可權控制是類似於白名單的,通過建立 Role&RoleBinding 和 ClusterRole&ClusterRoleBinding 將使用者許可權新增到“白名單”中,以此來實現授權。
Role 和 ClusterRole
在 RBAC API 中,Role 和 Cluster 都表示一組許可權的集合,Role 是 namespace-scoped的,定義的是某一個namespace中的資源許可權;而如果想要實現叢集級別的或者跨namespace的許可權控制,則需要建立 ClusterRole。
Role example
如上文所說,Role 是 namespace-scoped的,定義的是某一個namespace中的資源許可權。
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"]
上述 pod-reader
role,表示可以get/list/watch default namespce下面的pods資源。
Role 中可以定義多條rules,每條rule表示一個許可權,rule型別定義如下:
type Rule struct {
// Verbs is a list of Verbs that apply to ALL the ResourceKinds and AttributeRestrictions contained in this rule. VerbAll represents all kinds.
Verbs []string
// APIGroups is the name of the APIGroup that contains the resources.
// If multiple API groups are specified, any action requested against one of the enumerated resources in any API group will be allowed.
APIGroups []string
// Resources is a list of resources this rule applies to. '*' represents all resources in the specified apiGroups.
// '*/foo' represents the subresource 'foo' for all resources in the specified apiGroups.
Resources []string
// ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed.
ResourceNames []string
// NonResourceURLs is a set of partial urls that a user should have access to. *s are allowed, but only as the full, final step in the path
// If an action is not a resource API request, then the URL is split on '/' and is checked against the NonResourceURLs to look for a match.
// Since non-resource URLs are not namespaced, this field is only applicable for ClusterRoles referenced from a ClusterRoleBinding.
// Rules can either apply to API resources (such as "pods" or "secrets") or non-resource URL paths (such as "/api"), but not both.
NonResourceURLs []string
}
ClusterRole example
ClusterRole 是用來實現叢集級別的或者跨namespace的許可權控制:
- cluster-scoped 型別的資源,比如
nodes
- non-resource 型別的api,比如/healthz`
- namespace-scoped 型別的資源,實現跨namespace的許可權控制
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"]
secret-reader
表示 get/list/watch 所有namespaces下面的secrets資源的許可權。
RoleBinding 和 ClusterRoleBinding
Role 和 ClusterRole 都表示了許可權的集合,許可權只有授予某個user或者group才有實際意義。許可權和使用者之間的關聯關係 是通過 RoleBinding 和 ClusterRoleBinding 兩個API資源來實現的。RoleBinding 是 namespace-scoped的,而 ClusterRoleBinding是 cluster-scoped的。
RoleBinding example
RoleBinding 可以引用在同一名稱空間內定義的 Role 物件。 下面示例中定義的 RoleBinding 物件在“default” 名稱空間中將“pod-reader” 角色授予使用者“jane”。 這一授權將允許使用者“jane” 從“default” 名稱空間中讀取 pod。
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: read-pods
namespace: default
subjects:
- kind: User
name: jane
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
RoleBinding 物件也可以引用一個 ClusterRole 物件用於在 RoleBinding 所在的名稱空間內授予使用者對所引用的 ClusterRole 中 定義的名稱空間資源的訪問許可權。這一點允許管理員在整個叢集範圍內首先定義一組通用的角色,然後再在不同的名稱空間中複用這些角色。
例如,儘管下面示例中的 RoleBinding 引用的是一個 ClusterRole 物件,但是使用者”dave”(即角色繫結主體)還是隻能讀取”development” 名稱空間中的 secret(即 RoleBinding 所在的名稱空間)。
# 以下角色繫結允許使用者 "dave" 讀取 "development" 名稱空間中的 secret。
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: read-secrets
namespace: development # 這裡表明僅授權讀取 "development" 名稱空間中的資源。
subjects:
- kind: User
name: dave
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
ClusterRoleBinding example
可以使用ClusterRoleBinding在叢集級別和所有名稱空間中授予許可權。下面示例中所定義的ClusterRoleBinding允許在使用者組”manager” 中的任何使用者都可以讀取叢集中任何名稱空間中的 secret。
以下 ClusterRoleBinding 物件允許在使用者組 "manager" 中的任何使用者都可以讀取叢集中任何名稱空間中的 secret。
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: read-secrets-global
subjects:
- kind: Group
name: manager
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io
更多型別的資源引用
大多數資源由代表其名字的字串表示,例如”pods”,就像它們出現在相關 API endpoint 的 URL 中一樣。然而,有一些 Kubernetes API 還 包含了” 子資源”,比如 pod 的 logs。在 Kubernetes 中,pod logs endpoint 的 URL 格式為:
GET /api/v1/namespaces/{namespace}/pods/{name}/log
在這種情況下,“pods” 是名稱空間資源,而“log” 是 pods 的子資源。為了在 RBAC 角色中表示出這一點,我們需要使用斜線來劃分資源 與子資源。如果需要角色繫結主體讀取 pods 以及 pod log,您需要定義以下角色:
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
namespace: default
name: pod-and-pod-logs-reader
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list"]
通過resourceNames
列表,角色可以針對不同種類的請求根據資源名引用資源例項。當指定了resourceNames列表時,不同動作 種類的請求的許可權,如使用get、delete、update、patch
等動詞的請求,將被限定到資源列表中所包含的資源例項上。 例如,如果需要限定一個角色繫結主體只能“get” 或者“update” 一個 configmap 時,您可以定義以下角色:
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
namespace: default
name: configmap-updater
rules:
- apiGroups: [""]
resources: ["configmap"]
resourceNames: ["my-configmap"]
verbs: ["update", "get"]
值得注意的是,如果設定了resourceNames
,則請求所使用的動詞不能是 list、watch、create 或者 deletecollection
。 由於資源名不會出現在 create、list、watch 和 deletecollection
等 API 請求的 URL 中,所以這些請求動詞不會被設定了resourceNames的規則所允許,因為規則中的resourceNames 部分不會匹配這些請求。
更多示例
角色定義示例
- 允許讀取 core API Group 中定義的資源 pods:
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
- 允許讀寫在 extensions 和 apps API Group 中定義的 deployments :
rules:
- apiGroups: ["extensions", "apps"]
resources: ["deployments"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- 允許讀取 pods 以及讀寫 jobs :
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
- apiGroups: ["batch", "extensions"]
resources: ["jobs"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- 允許讀取一個名為 my-config 的ConfigMap例項(需要將其通過RoleBinding繫結從而限制針對某一個名稱空間中定義的一個ConfigMap例項的訪問):
rules:
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["my-config"]
verbs: ["get"]
- 允許讀取 core API Group 中的 nodes 資源(由於Node是叢集級別資源,所以此ClusterRole定義需要與一個ClusterRoleBinding繫結才能有效):
rules:
- apiGroups: [""]
resources: ["nodes"]
verbs: ["get", "list", "watch"]
- 允許對非資源 endpoint
/healthz
及其所有子路徑的 GET 和 POST 請求(此ClusterRole定義需要與一個ClusterRoleBinding繫結才能有效):
rules:
- nonResourceURLs: ["/healthz", "/healthz/*"] # 在非資源 URL 中,'*' 代表字尾萬用字元
verbs: ["get", "post"]
- 所有api 訪問許可權
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["*"]
角色繫結示例
- 一個名為 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
作者簡介
李嵐清,網易數帆輕舟事業部資深系統開發工程師,具有多年 Kubernetes 開發運維經驗,負責在 / 離線業務混部、容器網路編排等多個專案,推動和協助網易內部多個業務實現容器化。目前專注於雲原生、分散式系統架構等技術領域。
相關文章
- RBAC-基於角色的訪問控制
- 基於角色的訪問控制RBAC是什麼? - TailscaleAI
- [Django REST framework - RBAC-基於角色的訪問控制、base64編碼 、xadmin的使用]DjangoRESTFramework
- kubernetes實踐之十六:RBAC 角色訪問控制
- 資料安全合規需要從基於角色的訪問控制邁向基於屬性的訪問控制
- idou老師教你學istio :基於角色的訪問控制
- Quarkus中基於角色的許可權訪問控制教程
- Spring Security 實戰乾貨:基於註解的介面角色訪問控制Spring
- .Net Core實戰之基於角色的訪問控制的設計
- Spring Security 實戰乾貨:基於配置的介面角色訪問控制Spring
- Spring Security實現基於RBAC的許可權表示式動態訪問控制Spring
- React基於RBAC的許可權控制React
- 容器編排系統K8s之訪問控制--RBAC授權K8S
- 基於角色的訪問控制並根據不同的場景顯示不同的反饋資訊
- 基於linux下的selinux強制訪問控制Linux
- Java JDK11基於巢狀的訪問控制JavaJDK巢狀
- 服務端指南 | 基於資料的訪問控制服務端
- Ant Design Pro v4 基於角色的許可權訪問控制實戰教程 #1 介紹
- Swift的訪問控制講解Swift
- 005.OpenShift訪問控制-許可權-角色
- jCasbin: 強大的訪問控制、許可權管理框架,支援 ACL, RBAC, ABAC框架
- 學習阿里雲的訪問控制策略阿里
- 基於RBAC的許可權控制淺析(結合Spring Security)Spring
- 銀行基於雲原生架構下的 DevOps 建設架構dev
- Ant Design Pro v4 基於角色的許可權訪問控制實戰教程 #2 初始化專案
- B站基於K8S的雲原生混部技術實踐K8S
- k8s結合jumpserver做kubectl許可權控制 使用者在多個namespaces的訪問許可權 rbac許可權控制K8SServernamespace訪問許可權
- K8s准入控制與RBAC比較K8S
- k8s 基於RBAC的認證、授權介紹和實踐K8S
- 基於shiro RBAC的表設計
- 類的訪問控制
- AWS身份和訪問管理模組新增標籤和基於屬性的訪問控制能力
- PHP 中基於 Casbin 做 RBAC + RESTful 許可權控制PHPREST
- ASP.NET Core 基於宣告的訪問控制到底是什麼鬼?ASP.NET
- Swift 中的訪問控制Swift
- 【Gator Cloud】架構篇 - 提供基於雲原生的資料安全保護Cloud架構
- 銀行基於雲原生架構的 DevOps 建設實踐經驗架構dev
- 雲原生系列6 基於springcloud架構風格的本地debug實現SpringGCCloud架構