Kubernetes(k8s)許可權管理RBAC詳解

来源:https://www.cnblogs.com/liugp/archive/2022/07/02/16438284.html
-Advertisement-
Play Games

一、簡介 kubernetes 集群相關所有的交互都通過apiserver來完成,對於這樣集中式管理的系統來說,許可權管理尤其重要,在1.5版的時候引入了RBAC(Role Base Access Control)的許可權控制機制。 啟用RBAC,需要在 apiserver 中添加參數--authori ...


目錄

一、簡介

kubernetes 集群相關所有的交互都通過apiserver來完成,對於這樣集中式管理的系統來說,許可權管理尤其重要,在1.5版的時候引入了RBAC(Role Base Access Control)的許可權控制機制

啟用RBAC,需要在 apiserver 中添加參數--authorization-mode=RBAC,如果使用的kubeadm安裝的集群,1.6+版本都預設開啟了RBAC。

$ grep -C3 'authorization-mode' /etc/kubernetes/manifests/kube-apiserver.yaml

API Server目前支持以下幾種授權策略:

  • AlwaysDeny:表示拒絕所有請求,一般用於測試。
  • AlwaysAllow:允許接收所有請求。
    如果集群不需要授權流程,則可以採用該策略,這也是Kubernetes的預設配置。
  • ABAC(Attribute-Based Access Control):基於屬性的訪問控制。
    表示使用用戶配置的授權規則對用戶請求進行匹配和控制。
  • Webhook:通過調用外部REST服務對用戶進行授權。
  • RBAC:Role-Based Access Control,基於角色的訪問控制(本章講解)。
  • Node:是一種專用模式,用於對kubelet發出的請求進行訪問控制。

更多許可權管理,可參考:http://docs.kubernetes.org.cn/51.html#Kubernetes

二、用戶分類

K8s的用戶分兩種,一種是普通用戶一種是ServiceAccount(服務賬戶)。

1、普通用戶

  • 普通用戶是假定被外部或獨立服務管理的。管理員分配私鑰。平時常用的kubectl命令都是普通用戶執行的。
  • 如果是用戶需求許可權,則將Role與User(或Group)綁定(這需要創建User/Group),是給用戶使用的。

2、ServiceAccount(服務賬戶)**

  • ServiceAccount(服務帳戶)是由Kubernetes API管理的用戶。它們綁定到特定的命名空間,並由API伺服器自動創建或通過API調用手動創建。服務帳戶與存儲為Secrets的一組證書相關聯,這些憑據被掛載到pod中,以便集群進程與Kubernetes API通信。(登錄dashboard時我們使用的就是ServiceAccount)
  • 如果是程式需求許可權,將Role與ServiceAccount指定(這需要創建ServiceAccount並且在deployment中指定ServiceAccount),是給程式使用的。

相當於Role是一個類,用作許可權申明,User/Group/ServiceAccount將成為類的實例。

工作流程圖

三、K8s角色&角色綁定(以ServiceAccount展開講解)

1)授權介紹

在RABC API中,通過如下的步驟進行授權:

  1. 定義角色:在定義角色時會指定此角色對於資源的訪問控制的規則。
  2. 綁定角色:將主體與角色進行綁定,對用戶進行訪問授權。

角色

  • Role:授權特定命名空間的訪問許可權
  • ClusterRole:授權所有命名空間的訪問許可權

角色綁定

  • RoleBinding:將角色綁定到主體(即subject)
  • ClusterRoleBinding:將集群角色綁定到主體

主體(subject)

  • User:用戶
  • Group:用戶組
  • ServiceAccount:服務賬號

​圖解如下:

2)角色(Role和ClusterRole)

Role是許可權的定義,在kubernetes中角色分為兩種一種是Role針對特定的命名空間,一種是ClusterRole在整個集群範圍內都生效。

Role示例如下:

cat >Role-001.yaml<<EOF
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: default
  name: pod-role
rules:
- apiGroups: [""] # "" indicates the core API group
  resources: ["pods"]
  verbs: ["get", "watch", "list"]
EOF
$ kubectl apply -f Role-001.yaml
$ kubectl get role -n default
$ kubectl describe role pod-role -n default

ClusterRole示例如下:

cat >ClusterRole-001.yaml<<EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: pod-clusterrole
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "watch", "list"]
EOF
$ kubectl apply -f ClusterRole-001.yaml
$ kubectl get clusterrole pod-clusterrole
$ kubectl describe clusterrole pod-clusterrole

相關參數
1、Role、ClsuterRole Verbs可配置參數

"get", "list", "watch", "create", "update", "patch", "delete", "exec"

2、Role、ClsuterRole Resource可配置參數

"services", "endpoints", "pods","secrets","configmaps","crontabs","deployments","jobs","nodes","rolebindings","clusterroles","daemonsets","replicasets","statefulsets","horizontalpodautoscalers","replicationcontrollers","cronjobs"

3、Role、ClsuterRole APIGroup可配置參數

"","apps", "autoscaling", "batch"

3)角色綁定(RoleBinding和ClusterRoleBinding)

定義好了角色也就是一個許可權的集合,然後創建了一個ServiceAccount也就是一個服務賬號,然後將這兩個東西綁定起來,就是授權的過程了。

1、Role角色綁定ServiceAccount

$ cat >RoleBinding-001.yaml<<EOF
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: rb
  namespace: default
subjects:
- kind: ServiceAccount
  name: zhangsan
  namespace: default
roleRef:
  kind: Role
  name: pod-role
  apiGroup: rbac.authorization.k8s.io
EOF
$ kubectl apply -f RoleBinding-001.yaml
$ kubectl get RoleBinding
$ kubectl describe RoleBinding rb

2、ClusterRole角色綁定ServiceAccount

$ cat >ClusterRoleBinding-001.yaml<<EOF
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: crb
subjects:
- kind: ServiceAccount
  name: mark
  namespace: default
roleRef:
  kind: ClusterRole
  name: pod-clusterrole
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: mark
  namespace: default
EOF
$ kubectl apply -f ClusterRoleBinding-001.yaml
$ kubectl get ClusterRoleBinding crb
$ kubectl describe ClusterRoleBinding crb

上面只是說到了綁定ServiceAccount,其實還有兩種類型:User,Group,綁定類似,把subjects.kind。

四、實戰

儘管無法通過 API 調用來添加給kubernetes增加普通用戶,Kubernetes 仍然認為能夠提供由集群的證書 機構簽名的合法證書的用戶是通過身份認證的用戶。基於這樣的配置,Kubernetes 使用證書中的 'subject' 的通用名稱(Common Name)欄位(例如,"/CN=devuser")來 確定用戶名, Kubernetes使用證書中的 'subject' 的單位名稱 (Organization Name) 欄位(例如,"/O=system:masters")來確定用戶組。接下來,基於角色訪問控制(RBAC)子系統會確定用戶是否有權針對 某資源執行特定的操作。

Kubernetes 有著以下幾個內建的用於特殊目的的組:

  • system:unauthenticated :未能通過任何一個授權插件檢驗的賬號,即未通過認證測 試的用戶所屬的組 。
  • system :authenticated :認證成功後的用戶自動加入的一個組,用於快捷引用所有正常通過認證的用戶賬號。
  • system : serviceaccounts :當前系統上的所有 Service Account 對象。
  • system :serviceaccounts :<namespace>:特定命名空間內所有的 Service Account 對象。

1)User

1、創建K8S 用戶

普通用戶並不是通過k8s來創建和維護,是通過創建證書和切換上下文環境的方式來創建和切換用戶。

a、創建證書

# 創建私鑰
$ openssl genrsa -out devuser.key 2048
 
# 用此私鑰創建一個csr(證書簽名請求)文件
$ openssl req -new -key devuser.key -subj "/CN=devuser" -out devuser.csr
 
# 拿著私鑰和請求文件生成證書
$ openssl x509 -req -in devuser.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out devuser.crt -days 365

b、生成賬號

$ kubectl config set-credentials devuser --client-certificate=./devuser.crt --client-key=./devuser.key --embed-certs=true

c、設置上下文參數

# # 設置上下文, 預設會保存在 $HOME/.kube/config
$ kubectl config set-context devuser@kubernetes --cluster=kubernetes --user=devuser --namespace=dev

# 查看
$ kubectl config get-contexts

d、設置 預設上下文

$ kubectl config use-context devuser@kubernetes
# 查看
$ kubectl config get-contexts
$ kubectl get nodes

發現使用我們創建的用戶查詢是失敗的,是因為賬號還沒授權,接下來就是對賬號進行授權。這裡需要先把用切回來,要不然就無法進行下一步授權了。

$ kubectl config use-context kubernetes-admin@kubernetes
$ kubectl get nodes

2、對用戶授權

$ cat >devuser-role-bind<<EOF
kind: Role  # 角色
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: dev
  name: devuser-role
rules:
- apiGroups: [""] # ""代表核心api組
  resources: ["pods"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
kind: RoleBinding # 角色綁定
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: devuser-rolebinding
  namespace: dev
subjects:
- kind: User
  name: devuser   # 目標用戶
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: devuser-role  # 角色信息
  apiGroup: rbac.authorization.k8s.io
EOF

執行並驗證

$ kubectl apply -f devuser-role-bind
$ kubectl config use-context devuser@kubernetes
$ kubectl get pods # 不帶命名空間,這裡預設dev,也只能查看dev上面限制的命名空間的pods資源,從而也驗證了role是針對命名空間的許可權限制
#查看其它命名空間的資源
$ kubectl get pods -n default
$ kubectl get pods -n kube-system
$ kubectl get nodes

可以看到,用devuser,已經可以管理dev命名空間下的pod資源了,也只能管理dev命名空間下的pod資源,無法管理dev以外的資源類型,驗證ok。ClusterRoleBinding綁定類似,這裡就不重覆了。有興趣的小伙伴可以試試。

切回管理員用戶

$ kubectl config use-context kubernetes-admin@kubernetes

2)Group

因為跟user類型,這裡就不過多文字介紹,直接上命令和配置

1、創建K8S 用戶和用戶組

# 創建私鑰
$ openssl genrsa -out devgroupuser.key 2048
 
# 用此私鑰創建一個csr(證書簽名請求)文件
$ openssl req -new -key devgroupuser.key -subj "/O=devgroup/CN=devgroupuser" -out devgroupuser.csr
 
# 拿著私鑰和請求文件生成證書
$ openssl x509 -req -in devgroupuser.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out devgroupuser.crt -days 365

# 生成賬號
$ kubectl config set-credentials devgroupuser --client-certificate=./devgroupuser.crt --client-key=./devgroupuser.key --embed-certs=true

# 設置上下文參數
$ kubectl config set-context devgroupuser@kubernetes --cluster=kubernetes --user=devgroupuser --namespace=dev

# 查看
$ kubectl config get-contexts

2、對組授權

$ cat >devgroup-role-bind.yaml<<EOF
kind: Role  # 角色
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: dev
  name: devgroup-role
rules:
- apiGroups: [""] # ""代表核心api組
  resources: ["services","pods"]
  verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
kind: RoleBinding # 角色綁定
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: devgroup-rolebinding
  namespace: dev
subjects:
- kind: Group
  name: devgroup   # 目標用戶組
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: devgroup-role  # 角色信息
  apiGroup: rbac.authorization.k8s.io
EOF

執行並驗證(命名空間預設dev,而不是系統的default)

$ kubectl apply -f devgroup-role-bind.yaml
#切用戶
$ kubectl config use-context devgroupuser@kubernetes
# 查看
$ kubectl config get-contexts
$ kubectl get pods
$ kubectl get svc
$ kubectl get nodes
$ kubectl get jobs

從上圖實驗看,只能管理dev命名空間下的pods和services了,驗證ok。

切回管理員用戶

$ kubectl config use-context kubernetes-admin@kubernetes

3)ServiceAccount

上面第四節,已經很詳細的介紹了ServiceAccount,這裡也是直接上配置和操作命令。

$ cat >RoleBinding-ServiceAccount-001.yaml<<EOF
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: default
  name: role001
rules:
- apiGroups: [""] # "" indicates the core API group
  resources: ["pods"]
  verbs: ["get", "watch", "list"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: rb001
  namespace: default
subjects:
- kind: ServiceAccount
  name: lisi
  namespace: default
roleRef:
  kind: Role
  name: role001
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: lisi
  namespace: default
EOF

執行

$ kubectl delete -f RoleBinding-ServiceAccount-001.yaml

4)為ServiceAccount生成Token

cat >ClusterRoleBinding-ServiceAccount-token-001.yaml<<EOF
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: admin
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
  name: sa001
  namespace: kube-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: sa001
  namespace: kube-system
EOF

獲取token

$ kubectl -n kube-system get secret|grep sa001
$ kubectl -n kube-system describe secret sa001-token-c2klg
# 也可以使用 jsonpath 的方式直接獲取 token 的值,如:
$ kubectl -n kube-system get secret sa001-token-c2klg -o jsonpath={.data.token}|base64 -d

【註意】yaml 輸出里的那個 token 值是進行 base64 編碼後的結果

5)預設的Token

每次創建了新的namespace下都會生成一個預設的token,名為default-token-xxxx。default就相當於該namespace下的一個用戶。

$ kubectl -n dev get secret
$ kubectl -n dev describe secret default-token-67wgz
# 也可以使用 jsonpath 的方式直接獲取 token 的值,如:
$ kubectl -n dev get secret default-token-67wgz -o jsonpath={.data.token}|base64 -d

可以使用下麵的命令給該用戶分配該namespace的管理員許可權

kubectl create rolebinding $ROLEBINDING_NAME --clusterrole=admin --serviceaccount=$NAMESPACE:default --namespace=$NAMESPACE

  • $ROLEBINDING_NAME必須是該namespace下的唯一的
  • admin表示用戶該namespace的管理員許可權,關於使用clusterrole進行更細粒度的許可權控制請參考RBAC——基於角色的訪問控制。
  • 我們給預設的serviceaccount default分配admin許可權,這樣就不要再創建新的serviceaccount,當然你也可以自己創建新的serviceaccount,然後給它admin許可權

其實kubernetes-dashboard就是通過token授權的,可以不清楚的,可以看我之前的文章:Kubernetes(k8s)安裝以及搭建k8s-Dashboard詳解

五、總結

RoleBinding 和 ClusterRoleBinding:角色綁定和集群角色綁定,簡單來說就是把聲明的 Subject 和我們的 Role 進行綁定的過程(給某個用戶綁定上操作的許可權),二者的區別也是作用範圍的區別:RoleBinding 只會影響到當前namespace 下麵的資源操作許可權,而 ClusterRoleBinding 會影響到所有的namespace。

  • Rule:規則,規則是一組屬於不同 API Group 資源上的一組操作的集合
  • Role 和 ClusterRole:角色和集群角色,這兩個對象都包含上面的 Rules 元素,二者的區別在於,在 Role 中,定義的規則只適用於單個命名空間,也就是和namespace 關聯的,而 ClusterRole 是集群範圍內的,因此定義的規則不受命名空間的約束。另外 Role 和 ClusterRole 在Kubernetes中都被定義為集群內部的 API 資源,和我們前面學習過的 Pod、ConfigMap 這些類似,都是我們集群的資源對象,所以同樣的可以使用我們前面的kubectl相關的命令來進行操作
  • Subject:主題,對應在集群中嘗試操作的對象,集群中定義了3種類型的主題資源:
  1. User:用戶,這是有外部獨立服務進行管理的,管理員進行私鑰的分配,用戶可以使用 KeyStone或者 Goolge 帳號,甚至一個用戶名和密碼的文件列表也可以。對於用戶的管理集群內部沒有一個關聯的資源對象,所以用戶不能通過集群內部的 API 來進行管理
  2. Group:組,這是用來關聯多個賬戶的,集群中有一些預設創建的組,比如cluster-admin
  3. ServiceAccount:服務帳號,通過Kubernetes API 來管理的一些用戶帳號,和namespace 進行關聯的,適用於集群內部運行的應用程式,需要通過 API 來完成許可權認證,所以在集群內部進行許可權操作,我們都需要使用到 ServiceAccount,這也是我們這節課的重點

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • RAID:獨立硬碟冗餘陣列,簡稱磁碟陣列 作用:用來來提升性能和冗餘(容錯性)。 RAID把多個硬碟組合成為一個邏輯硬碟,因此,操作系統只會把它當作一個實體硬碟 RAID實現的功能: 性能提升 磁碟冗餘(容錯性) RAID實現方式: 硬體實現:RAID卡(外接和主板內置) 生產環境一般永這種 軟體實 ...
  • 1、創建工作目錄 創建jar部署的目錄,並且將jar上傳到該目錄下 mkdir -p /home/java-server/test-demo 2、創建啟動腳本 進入jar目錄: cd /home/java-server/test-demo 創建腳本文件: vim start.sh 啟動腳本內容: # ...
  • Linux基礎命令(二) 1. 壓縮,解壓縮命令 壓縮格式:gz、bz2、xz、zip、Z 1.1 gzip 壓縮,壓縮後文件以.gz結尾,壓縮後會刪除原文件 [root@zzd ~]# gzip 1.txt //將1.txt壓縮,以.gz結尾 -d 解壓縮,解壓完成後刪除原文件 [root@zzd ...
  • U盤的使用和硬碟的使用很相似 移動介質: 掛載意味著外來的文件系統看起來就是主目錄樹的一部分。所以移動介質也需要掛載,通常掛載到/media或/mnt下麵。 訪問前,介質必須被掛載 摘除時,介質必須被卸載 創建ISO文件: 方法一:cp /dev/cdrom /root/centos.iso 方法二 ...
  • 目錄 一、前景回顧 二、初識中斷 三、中斷分類 四、中斷號 五、可編程中斷控制器8259A 六、中斷描述符表IDT 一、前景回顧 上一回我們簡單地講解了特權級的原理,這一塊其實我當時也是啃的雲里霧裡,看了好大一會兒才明白。如果實在不怎麼理解特權級檢查也沒關係,因為後面的代碼中也不會涉及到手寫特權級檢 ...
  • 掛載:把指定的設備和根下麵的某個文件夾建立關聯 卸載:解除兩者關係的過程 掛載文件系統:mount 格式:mount device mountpoint mount 設備名 掛載點 mountpoint:掛載點目錄必須事先存在,建議使用空目錄 選項: -t fstype:指定文件系統類型,比如ext ...
  • 目錄 一、前景回顧 二、什麼是特權級檢查 三、門 四、如何進行特權級檢查 五、調用門的跳轉執行流程 六、調用門的跳轉許可權檢查 一、前景回顧 我們在前面講過保護模式較之於實模式的三大特點:分頁機制、特權級和分時機制。現在分頁機制的坑已經填好了,接下來我們開始填特權級的坑。 二、什麼是特權級檢查 首先我 ...
  • 寫在前面 我一直認為,對於電子工程師來講,最好的學習資料就是晶元或者電子器件的數據手冊,可能一開始讀起來會很吃力,但只要你能堅持住,並且本著一種不懂就問,不會就查的態度,相信我,不需要多久你就能看到自己的進步。所以今天我就帶大家解讀一種非常常見,但又似懂非懂的器件——MOSFET,也就是我們常說的M ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...