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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...