Kubernetes K8S之鑑權RBAC詳解

 

Kubernetes K8S之鑑權概述與RBAC詳解node

 

K8S認證與受權

 

認證「Authentication」

認證有以下幾種方式:算法

一、HTTP Token認證:經過一個Token來識別合法用戶。api

HTTP Token的認證是用一個很長的特殊編碼方式的而且難以被模仿的字符串來表達客戶的一種方式。每個Token對應一個用戶名,存儲在API Server能訪問的文件中。當客戶端發起API調用請求時,須要在HTTP Header裏放入Token。frontend

二、HTTP Base認證:經過用戶名+密碼的方式認證測試

用戶名:密碼 用base64算法進行編碼後的字符串放在HTTP Request中的Heather Authorization 域裏發送給服務端,服務端收到後進行解碼,獲取用戶名和密碼。this

三、最嚴格的HTTPS證書認證:基於CA根證書籤名的客戶端身份認證方式編碼

 

受權「Authorization」

認證只是確認通訊的雙方都是可信的,能夠相互通訊。而受權是肯定請求方有哪些資源的權限。API Server目前支持以下幾種受權策略(經過API Server的啓動參數 --authorization-mode 設置)spa

  • AlwaysDeny:表示拒絕全部請求。僅用於測試
  • AlwaysAllow:表示容許全部請求。若是有集羣不須要受權流程,則能夠採用該策略
  • Node:節點受權是一種特殊用途的受權模式,專門受權由 kubelet 發出的 API 請求
  • Webhook:是一種 HTTP 回調模式,容許使用遠程 REST 端點管理受權
  • ABAC:基於屬性的訪問控制,表示使用用戶配置的受權規則對用戶請求進行匹配和控制
  • RBAC:基於角色的訪問控制,默認使用該規則

 

RBAC受權模式

RBAC(Role-Based Access Control)基於角色的訪問控制,在Kubernetes 1.5 中引入,現爲默認標準。相對其餘訪問控制方式,擁有以下優點:插件

一、對集羣中的資源和非資源均擁有完整的覆蓋code

二、整個RBAC徹底由幾個API對象完成,同其餘API對象同樣,能夠用kubectl或API進行操做

三、能夠在運行時進行操做,無需重啓API Server

 

RBAC API類型

RBAC API 所聲明的四種頂級類型【Role、ClusterRole、RoleBinding 和 ClusterRoleBinding】。用戶能夠像與其餘 API 資源交互同樣,(經過 kubectl API 調用等方式)與這些資源交互。

 

Role 和 ClusterRole

在 RBAC API 中,一個角色包含一組相關權限的規則。權限是純粹累加的(不存在拒絕某操做的規則),即只能給權限累加,不存在給了XX權限,而後去掉XX01權限的狀況。角色能夠用 Role 來定義到某個命名空間(namespace)上, 或者用 ClusterRole 來定義到整個集羣做用域(全部namespace)

一個 Role 只能夠用來對某一命名空間中的資源賦予訪問權限。

 

Role示例:

定義到名稱爲 「default」 的命名空間,能夠用來授予對該命名空間中的 Pods 的讀取權限:

1 apiVersion: rbac.authorization.k8s.io/v1
2 kind: Role
3 metadata:
4   name: pod-reader
5   namespace: default
6 rules:
7 - apiGroups: [""] # "" 指定核心 API 組
8   resources: ["pods"]
9   verbs: ["get", "watch", "list"]

ClusterRole 能夠授予的權限和 Role 相同,可是由於 ClusterRole 屬於集羣範圍,因此它也能夠授予如下訪問權限:

  • 集羣範圍資源 (好比 nodes訪問)
  • 非資源端點(好比 「/healthz」 訪問)
  • 跨命名空間訪問的有名稱空間做用域的資源(如 Pods),好比運行命令kubectl get pods --all-namespaces 時須要此能力

 

ClusterRole示例

可用來對某特定命名空間下的 Secrets 的讀取操做受權,或者跨全部名稱空間執行受權(取決於它是如何綁定的):

1 apiVersion: rbac.authorization.k8s.io/v1
2 kind: ClusterRole
3 metadata:
4   name: secret-reader
5   # 此處的 "namespace" 被省略掉是由於 ClusterRoles 是沒有命名空間的。
6 rules:
7 - apiGroups: [""]
8   resources: ["secrets"]
9   verbs: ["get", "watch", "list"]

 

RoleBinding 和 ClusterRoleBinding

角色綁定(RoleBinding)是將角色中定義的權限賦予一個用戶或者一組用戶。 它包含若干主體【subjects】(users、groups或 service accounts)的列表和對這些主體所得到的角色引用。

可使用 RoleBinding 在指定的命名空間中執行受權,或者在集羣範圍的命名空間使用 ClusterRoleBinding 來執行受權。

一個 RoleBinding 能夠引用同一的命名空間中的 Role。

RoleBinding示例

將 「pod-reader」 角色授予在 「default」 命名空間中的用戶 「jane」; 這樣,用戶 「jane」 就具備了讀取 「default」 命名空間中 pods 的權限。

在下面的例子中,角色綁定使用 roleRef 將用戶 「jane」 綁定到前文建立的角色 Role,其名稱是 pod-reader

 1 apiVersion: rbac.authorization.k8s.io/v1
 2 # 此角色綁定,使得用戶 "jane" 可以讀取 "default" 命名空間中的 Pods
 3 kind: RoleBinding
 4 metadata:
 5   name: read-pods
 6   namespace: default
 7 subjects:
 8 - kind: User
 9   name: jane # 名稱大小寫敏感
10   apiGroup: rbac.authorization.k8s.io
11 roleRef:
12   kind: Role #this must be Role or ClusterRole
13   name: pod-reader # 這裏的名稱必須與你想要綁定的 Role 或 ClusterRole 名稱一致
14   apiGroup: rbac.authorization.k8s.io

roleRef 裏的內容決定了實際建立綁定的方法。kind 能夠是 Role 或 ClusterRole,name 是你要引用的 Role 或 ClusterRole 的名稱。

RoleBinding 也能夠引用 ClusterRole,這能夠容許管理者在 整個集羣中定義一組通用的角色,而後在多個命名空間中重用它們。

 

RoleBinding示例2

下面的例子,RoleBinding 引用的是 ClusterRole, 「dave」 (subjects區分大小寫)將只能夠讀取在」development」 名稱空間( RoleBinding 的命名空間)中的」secrets」 。

 1 apiVersion: rbac.authorization.k8s.io/v1
 2 # 這個角色綁定容許 "dave" 用戶在 "development" 命名空間中有讀取 secrets 的權限。 
 3 kind: RoleBinding
 4 metadata:
 5   name: read-secrets
 6   namespace: development # 這裏只授予 "development" 命名空間的權限。
 7 subjects:
 8 - kind: User
 9   name: dave # 名稱區分大小寫
10   apiGroup: rbac.authorization.k8s.io
11 roleRef:
12   kind: ClusterRole
13   name: secret-reader
14   apiGroup: rbac.authorization.k8s.io

最後,ClusterRoleBinding 可用來在集羣級別並對全部命名空間執行受權。

 

ClusterRoleBinding示例
 1 apiVersion: rbac.authorization.k8s.io/v1
 2 # 這個集羣角色綁定容許 "manager" 組中的任何用戶讀取任意命名空間中 "secrets" 3 kind: ClusterRoleBinding
 4 metadata:
 5   name: read-secrets-global
 6 subjects:
 7 - kind: Group
 8   name: manager # 名稱區分大小寫
 9   apiGroup: rbac.authorization.k8s.io
10 roleRef:
11   kind: ClusterRole
12   name: secret-reader
13   apiGroup: rbac.authorization.k8s.io

當咱們建立binding後,則不能修改binding所引用的Role或ClusterRole。嘗試修改會致使驗證錯誤;若是要改變binding的roleRef,那麼應該刪除該binding對象而且建立一個新的用來替換原來的。

 

Referring to resources【資源引用】

Kubernetes集羣內一些資源通常以其名稱字符串來表示,這些字符串通常會在API的URL地址中出現;同時某些資源也會包含子資源,例如pod的logs資源就屬於pods的子資源,API中URL樣例以下:

GET /api/v1/namespaces/{namespace}/pods/{name}/log

在這種狀況下,」pods」 是有名稱空間的資源,而 「log」 是 pods 的子資源。在 RBAC 角色中,使用」/「分隔資源和子資源

容許一個主體(subject)要同時讀取 pods 和 pod logs,你能夠這麼寫:

1 apiVersion: rbac.authorization.k8s.io/v1
2 kind: Role
3 metadata:
4   namespace: default
5   name: pod-and-pod-logs-reader
6 rules:
7 - apiGroups: [""]
8   resources: ["pods", "pods/log"]
9   verbs: ["get", "list"]

對於某些請求,也能夠經過 resourceNames 列表按名稱引用資源。

例如:在指定時,能夠將請求類型限制到資源的單個實例。限制只能夠 「get」 和 「update」 到單個configmap,則能夠這麼寫:

 1 apiVersion: rbac.authorization.k8s.io/v1
 2 kind: Role
 3 metadata:
 4   namespace: default
 5   name: configmap-updater
 6 rules:
 7 - apiGroups: [""]
 8   resources: ["configmaps"]
 9   resourceNames: ["my-configmap"]
10   verbs: ["update", "get"]

須要注意的是,create 請求不能被 resourceName 限制,由於在鑑權時還不知道對象名稱。 另外一個例外是 deletecollection。

 

Referring to subjects【主體引用】

RoleBinding或ClusterRoleBinding綁定一個role到主體(subjects)。主體(subjects)能夠是groups,users或ServiceAccounts。

Kubernetes將用戶名錶示爲字符串。這些能夠是:普通名稱,好比「alice」 ;郵件風格的名字,好比「bob@example.com」 ;或表示爲字符串的數字用戶id。

注意:前綴 system: 是保留給Kubernetes系統使用的,所以應該確保不會出現名稱以system: 開頭的用戶或組。除了這個特殊的前綴,RBAC受權系統不要求用戶名使用任何格式。

ServiceAccounts具備前綴爲system:serviceaccount: 的名稱,屬於具備前綴爲system:serviceaccounts:的名稱的組。

RoleBinding的示例

下面的示例只是展現 RoleBinding 中 subjects 的部分。

用戶的名稱爲 「alice@example.com」 :

1 subjects:
2 - kind: User
3   name: "alice@example.com"
4   apiGroup: rbac.authorization.k8s.io

 

組的名稱爲 「frontend-admins」 :

1 subjects:
2 - kind: Group
3   name: "frontend-admins"
4   apiGroup: rbac.authorization.k8s.io

 

默認service account在 kube-system 命名空間中:

1 subjects:
2 - kind: ServiceAccount
3   name: default
4   namespace: kube-system

 

在名稱爲 「qa」 命名空間中全部的服務帳號:

1 subjects:
2 - kind: Group
3   name: system:serviceaccounts:qa
4   apiGroup: rbac.authorization.k8s.io

 

在任意名稱空間的全部service accounts:

1 subjects:
2 - kind: Group
3   name: system:serviceaccounts
4   apiGroup: rbac.authorization.k8s.io

 

全部認證過的用戶(版本 1.5+):

1 subjects:
2 - kind: Group
3   name: system:authenticated
4   apiGroup: rbac.authorization.k8s.io

 

全部未認證的用戶(版本 1.5+):

1 subjects:
2 - kind: Group
3   name: system:unauthenticated
4   apiGroup: rbac.authorization.k8s.io

 

全部用戶 (版本 1.5+):

1 subjects:
2 - kind: Group
3   name: system:authenticated
4   apiGroup: rbac.authorization.k8s.io
5 - kind: Group
6   name: system:unauthenticated
7   apiGroup: rbac.authorization.k8s.io

 

准入控制

准入控制是API Server的插件集合,經過添加不一樣的插件,實現額外的准入控制規則。甚至於API Server的一些主要的功能都須要經過Admission Controllers實現,好比:ServiceAccount。

查看哪些插件是默認啓用的:

kube-apiserver -h | grep enable-admission-plugins

 

在 1.17 中,它們是:

1 NamespaceLifecycle, LimitRanger, ServiceAccount, 
2 TaintNodesByCondition, Priority, DefaultTolerationSeconds, 
3 DefaultStorageClass, StorageObjectInUseProtection, PersistentVolumeClaimResize, 
4 MutatingAdmissionWebhook, ValidatingAdmissionWebhook, RuntimeClass, ResourceQuota

 

部分插件功能:

NamespaceLifecycle

該准入控制器禁止在一個正在被終止的 Namespace 中建立新對象,並確保使用不存在的 Namespace 的請求被拒絕。該准入控制器還會禁止刪除三個系統保留的命名空間,即 default、kube-system 和 kube-public。

刪除 Namespace 會觸發刪除該命名空間中全部對象(pod、services 等)的一系列操做。爲了確保這個過程的完整性,咱們強烈建議啓用這個准入控制器。

LimitRanger

該准入控制器會觀察傳入的請求,並確保它不會違反 Namespace 中 LimitRange 對象枚舉的任何約束。

ServiceAccount

該准入控制器實現了 serviceAccounts 的自動化。 若是打算使用 Kubernetes 的 ServiceAccount 對象,強烈建議您使用這個准入控制器。

ResourceQuota

該准入控制器會監測傳入的請求,並確保它不違反任何一個 Namespace 中的 ResourceQuota 對象中枚舉出來的約束。

相關閱讀

一、官網:使用 RBAC 鑑權

相關文章
相關標籤/搜索