kubernetes認證,授權概括總結:
RBAC簡明總結摘要:
API Server認證授權過程:
subject(主體)----->認證----->授權【action(可做什么)】------>准入控制【Object(能對那些資源對象做操作)】
認證:
有多種方式,比較常用的:token,tls,user/password
賬號:
k8s中賬號的概念不是我們理解的賬號,它並不真的存在,它只是形式上存在。
它有兩種賬號: UserAccount(人使用的賬號), ServiceAccount(Pod使用的賬號)
授權:RBAC
k8s中的授權機制也有很多,但目前主流是RBAC(基於角色的訪問控制)
RBAC中的核心概念:
基於單個名稱空間:
role, clusterrole, rolebinding
整個集群級別:
clusterrole , clusterrolebinding
role, clusterrole : 是定義職務,權限,就像公司成立時,就事先制定好有CTO,CEO,總監,經理等職務
rolebinding, clusterrolebinding: 是將具體的賬號(Subject) 和 某個role/clusterrole關聯,即授權,或叫任職。
subject:
在k8s中,主體是個泛稱,它表示k8s中的三類主體, user, group, serviceAccount
object:
Object這個詞,含義比較豐富,在不同場景理解要有變化,在k8s中我們通過
# kubectl describe role myrole
Name: myrole
.............
Resources Non-Resource URLs Resource Names Verbs
--------- ----------------- -------------- -----
deployments [] [] [get list watch]
pods [] [] [get list watch]
其中,Resources: 它可被稱為Resource Group
Resource Names: 它可被稱為 Resource,它表ResourceGroup中具體的單個資源
Non-Resource URLs: 它被稱為非資源URL
而這三類Object是k8s系統基本的Object。
在yaml清單中,經常看到某種屬性為<[]Object>它實際上是yaml語法中的字典 或叫映射(map)。這在報錯時,經常看到。
它和這里說的Object可不是一回事。
action:
即具體能對Ojbect做什么,它有: get, list, watch, patch, delete, update, create 等。。。
RBAC核心概念公式
role/clusterrole = object + action
授權單個名稱空間: rolebinding = subject + role/clusterRole
授權集群: clusterRoleBinding = subject + clusterRole
基本原理:
K8s中的認證和授權機制:
在K8s中我們操作任何資源都需要經歷三個檢查步驟:認證、授權 和 准入控制。
當然這些僅針對普通用戶,k8s中默認clusteradmin是擁有最高權限的。
- 認證: 即用戶要登陸k8s上操作資源,你必須提供合法的用戶名和密碼。
- 授權: 用戶認證通過后,要查看該用戶能操作什么資源,若其要操作的資源在其允許操作的資源范圍內則通過。
- 准入控制: 用戶要操作的資源,也許需要級聯其它相關資源或級聯了其它相關操作,那么這些級聯的資源 或 級聯的操作該用戶是否有權限訪問?這個就是有准入控制來檢查的,若不允許訪問級聯資源,那么該資源也將無法訪問。因為k8s是高度模塊化設計,因此,這三種檢查都允許用戶自定義使用何種檢測機制來進行訪問控制。
認證:
- token: 此方式又稱為預共享密鑰方式的認證,即用戶名和密碼,如同MySQL中root要登陸,必須事先在user表中創建root密碼.
- TLS: 此中方式為證書認證方式,此時K8s服務端 和 客戶端要做雙向證書認證,即客戶端要認證服務端的證書是否為自己認可的CA所簽發的證書,且證書中的subject信息CN(主機名)必須與服務端的主機名一致,等等;而服務器端也要認證客戶端的證書,也要認可簽發該證書的CA,以及證書中的信息也要匹配。以上是兩種比較常用的認證方式,還有其它認證,可自行研究。需要注意的是 認證插件中只有一個認證通過,其它插件就無需再次認證了。
授權:
它也是模塊化設計,它和認證一樣都同時支持多個模塊並存,但只要有一個模塊認證通過,即通過了此關,可進入下一關進一步檢查。
除了下面幾種常用授權模塊,我們也可在測試時,使用“總是允許” 或 “總是拒絕”來測試賬號。
- RBAC:基於角色的訪問控制機制,它只有允許授權,沒有拒絕授權,因為默認是拒絕所有,我們僅需要定義允許該用戶做什么即可。默認kubectl創建的K8s資源,都是默認啟用強制RBAC的
- ABAC
- 基於Node的授權
- Web-huke的授權(這是一種通過Web的回調機制實現的授權)
准入控制:
這塊主要是對認證授權通過后,后期對要操作的級聯對象操作的檢查,無需過多關注。
K8s上的用戶賬戶:
k8s客戶端(一般用:kubectl) ------>API Server
APIServer需要對客戶端做認證,默認使用工具安裝的K8s,會在用戶家目錄下創建一個認證配置文件 .kube/config 這里面保存了客戶端訪問API Server的密鑰相關信息,這樣當用kubectl訪問k8s時,它就會自動讀取該配置文件,向API Server發起認證,然后完成操作請求。
通常一個正常的API請求是包含: 用戶認證信息,API請求的URL,共同組成。
1. 在K8s中用戶賬戶為:
user: username + userID
group:
extra: 一些擴展信息
2. 在k8s中發起API請求,其內部實際是一個URL請求路徑:
格式: http://API_Server_IP:6443/apis/apps/v1/namespaces/default/deployments/myapp-deploy/
一個普通的HTTP請求有:
get, post, put, delete
在K8s中實際用的還是基本的請求方法,但K8s將這些基本方法,又做了更細致的封裝,於是就有以下API 請求命令:
get, list, create, update, patch, watch, proxy, redirect(重定向), delete,deletecollection(級聯刪除)
一個API請求的URL拆解開后會包含以下信息,當然這些信息是不包含認證,僅是資源:
API Group
Namespace
Resource
Subresource
#再進一步理解授權:
若當前僅授權某用戶可get資源,那么它就不能做create,update,delete等操作。
在k8s中訪問資源,其實就是對URL發起增刪改查的操作.
驗證方式:
1. 在安裝了kubectl的節點上,啟動kubectl的代理. 【注: kubectl所在節點必須有認證配置信息,即 .kube/config】
kubectl proxy --port=8888
2. 接着就可以在本地使用HTTP訪問8888來向運行在HTTPS協議上的API Server發起請求了
curl http://localhost:8888/....
#注意:一定要先啟動一個Proxy,因為,kubectl自身是有認證信息的,你每次執行kubectl命令時,它都會讀取 ~/.kube/config 文件中的認證信息,所以你不需要輸入任何認證信息,其實背后,是自動做了認證數據傳遞的。但你若直接使用curl 來請求APIServer,你就必須給 curl 制作一個API Server認可的認證信息,否則,curl是獲取不到任何信息的!所以為了簡單演示期間,可以使用上面的命令,先啟動一個kubectl代理,然后,curl向它發起請求,這樣curl就不需要提供任何認證信息,所有認證都將在kubectl proxy 和 API Server之間自動進行,但通常為了安全,通常僅將代理啟動為監聽在127.0.0.1上,然后在本地做 curl 請求。
kind(即:類型): 它有三種類型:【每種類型都有一個固定的JSON表達方式,配置清單使用yaml寫,但在提交時,會被自動轉換為JSON格式】 1. 對象類型,如: Pod, deployment, service,namespace等這些都稱為對象,它們都是可在集群上創建出來的具體實體。 2. 列表類型,在RESTful風格下它被稱為集合,在K8s上稱為列表(list) # curl http://localhost:8888/api/v1/namespaces #注意:namespaces其實就是一個集合,它會列出該對象集合中的所有子資源. # curl http://localhost:8888/api/v1/namespaces/default { "kind": "Namespace", "apiVersion": "v1", "metadata": { "name": "default", "selfLink": "/api/v1/namespaces/default", "uid": "2486e6a1-a8a6-11e9-8872-000c291a5fb6", "resourceVersion": "4", "creationTimestamp": "2019-07-17T15:18:34Z" }, "spec": { "finalizers": [ "kubernetes" ] }, "status": { "phase": "Active" } } RESTful: REST 稱為表針狀態轉移,通常用於承載對象數據狀態的格式,也稱為序列化的數據結構,一般用於流式化數據的格式有xml,yaml,json。 在K8s中,使用的都是Json來作為其輸出輸入數據的格式,即便我們編寫的所有清單文件都是yaml格式,但kubectl在將清單信息提交給API Server 前還是會自動將其轉換為Json格式再提交給API Server去處理。 curl http://localhost:8888/apis/apps/v1/namespaces/kube-system/deployments/coredns 注意: 以上兩個URL,一個是起始於api ,一個是起始於apis 區別: api 它是一個特殊鏈接,只有在核心v1群組中的對象才能使用。 apis 它是一般API訪問的入口固定格式名。
在K8s上有兩類客戶端需要訪問API Server: 1. 遠程的kubectl ,我們經常在Master上使用kubectl來操作k8s,很容易以為,kubectl是只能在Master上運行的, 其實不是,這樣做僅僅是為了方便訪問,才將kubectl安裝在Master上,其實你可以在Windows上安裝一個kubectl 然后,將~/.kube/config 這個記錄了認證信息的文件拷貝過去,就可以在Windows上使用了。因此它其實是個遠程客戶端. 2. Pod,如: coreDNS, K8s的儀表盤圖型界面接口 像kube-dns 它本身也是需要訪問API Server的,因為當集群中新增資源對象時,它需要動態的生成一條該資源對象的A記錄, 所以它需要訪問API Server來獲取這個對象的信息,Dashboard也需要,因為它提供了一個Web界面,可讓我們通過圖像界面 來管理操作k8s,如創建,刪除Pod,創建刪除名稱空間等,所以它也需要訪問API Server。 Pod中訪問API Server通常是人去訪問,或寫的腳本去訪問,所以這類訪問使用的賬號為:UserAccount 而Pod自身去連接API Server時,使用的賬號是:ServiceAccount 集群中的Pod如何訪問API Server? kubectl get svc kubectl describe svc kubernetes #可以看到API Server被映射為K8s上的Service了,Pod就是通過這個Service訪問API Server的. 注: 由於API Server的訪問必須要通過證書認證,它是雙向認證,即客戶端Pod要驗證API Server的身份,API也要驗證客戶端的身份. 所以對於Pod來說,它訪問API Server時,使用的地址是Service的地址.假如是10.96.0.1,而真實API Server所在Node節點的IP為 172.20.0.1。這就導致我們在創建API Server的證書時,必須要能夠實現,Pod獲取API Server的證書,去驗證里面的主機名時, 解析到的IP中必須有10.96.0.1,這就意味着DNS上要有兩條A記錄,一條解析為10.96.0.1,一條解析為172.20.0.1,這樣Pod 驗證API Server才能通過,而kubectl這種外部客戶端訪問驗證API Server解析的地址中有172.20.0.1,也能驗證API身份通過。 或者在證書中直接寫兩個IP地址,也是可以的。 但是我們又該知道,Pod驗證API Server是必須,但我們更需要的是API Server去驗證客戶端! Pod中的應用要訪問API Server,它事先是不可能專門為API Server設計一個讀取kubernetes認證信息的功能的, 就如: nginx 它是不可能直接去讀取kubernetes的認證信息,然后去訪問API Server的! 所以,訪問API Server時的認證信息要由Pod本身來完成。 kubectl describe pods myapp-1 #可看到它默認掛載了一個存儲卷,類型是secret的.它其實就是Pod訪問APIServer 時提供的認證信息,不過默認的token是普通用戶,它僅能查看自己的相關信息. kubectl get secret #使用它可看到,當前名稱空間的默認token,即 default-token-... 它就是當名稱空間中所有Pod ,默認訪問API Server時,提供的認證信息,當然你可加“ -n 名稱空間名” 來查看 其它名稱空間中的默認token,而且其中一定有一個default-token-xxx..的標准k8s資源。 #所以結合上面提到的兩類賬號,這里的default-token 其實就是第二類賬號,即serviceAccount。 #下面還有部分關於serviceAccount的說明,但為了讓知識點集中,在這里繼續深入 kubectl create serviceaccount admin 此命名創建了一個admin的serviceAccount,即可通過該賬號登錄k8s,但此自定義賬號並不能做任何事,因為 這里僅是創建了認證信息,真正決定是否能操作k8s資源對象的是 授權 ,這點需要注意!! 知道了這些,若我們需要運行一個Pod,這個Pod是用來管理其它Pod,Service,deployment等資源的,那么,我們就需要 給該Pod提供一個secret,它里面要包含足夠的權限的認證信息,這樣該Pod就可以用於管理K8s上的資源了。 創建清單文件的快捷方式: 方式一: kubectl create serviceaccount mysa -o yaml --dry-run > mysa-serviceaccount.yaml 注: 只有支持create創建的K8s資源,都可以使用這種方式生成一個yaml格式的配置清單文件,我們就可以 使用該清單模板來修改出我們需要的清單。 --dry-run: 它是測試運行,並不真正執行。 方式二: kubectl get pods myapp-1 -o yaml --exprots
關於serviceaccount: Pod中訪問API Server通常是人去訪問,或寫的腳本去訪問,所以這類訪問使用的賬號為:UserAccount 而Pod自身去連接API Server時,使用的賬號是:ServiceAccount 總結如下: useraccount: 它是現實中的人使用的用戶名和密碼的認證賬戶。 serviceaccount: 它是Pod中應用程序使用的認證賬戶和密碼。 另外,在創建serviceAccount時,也可以指定docker私有鏡像服務器的認證信息,並且這樣做會更加安全, 可避免docker私鑰信息泄露。 先前在說secret時,它里面有一種類型叫 docker-registry,它可用來創建連接docker私有鏡像服務器的信息, 但這種方式定義的secret,需要在Pod定義中指定 imagePullSecrets來指明使用哪個secret,但這樣很不安全. 很容易泄漏私有鏡像的認證信息。 因此可將認證信息添加到serviceAccount中,這樣在定義pod時,只需要指明使用那個SA就可以了,因為sa 的訪問權限,一般只有集群管理員才能訪問。 # kubectl describe sa mysa Name: mysa .......... Image pull secrets: <none> 。。。。。 創建一個serviceaccount的示例: # kubectl create serviceaccount mysa # kubectl get sa # kubectl describe sa mysa #可看到一個Tokens信息,以及它所掛載的secret。這是k8s自動生成的認證信息, 使用該信息就可以登陸到K8s上,但是需要注意,登陸可以,但該賬戶是沒有任何 權限的,因為權限是由授權來完成的。 Name: mysa Namespace: default Labels: <none> Annotations: <none> Image pull secrets: <none> Mountable secrets: mysa-token-cwgpg Tokens: mysa-token-cwgpg Events: <none> # kubectl get secrets NAME TYPE DATA AGE default-token-6xlcj kubernetes.io/service-account-token 3 4d14h mysa-token-cwgpg kubernetes.io/service-account-token 3 112s # kubectl describe secrets mysa-token-cwgpg Name: mysa-token-cwgpg Namespace: default ............ Type: kubernetes.io/service-account-token Data ==== ca.crt: 1346 bytes namespace: 7 bytes token: eyJhb.................72gU_ViYAHUZC-jmB8t7Xg 創建一個使用自定義ServiceAccount的Pod示例: vim pod-sa-demo.yaml apiVersion: v1 kind: Pod metadata: name: pod-sa-demo namespace: default labels: app: myapp tier: frontend annotations: test.com/created-by: “cluster admin” spec: containers: - name: myapp image: ikubernetes/myapp:v1 ports: - name: http containerPort: 80 serviceAccountName: admin kubectl apply -f pod-sa-demo.yaml kubectl describe pods pod-sa-demo #這里就可以看到,此Pod使用了自定義的admin認證信息。 任何需要訪問API Server的應用都可認為是API Server的客戶端,則這些客戶端都需要被API Server所認證, 這些客戶端包括: kubectl, kubelet, kube-proxy等等,那么它們要被API Server所認證,就必須提供用戶認證信息, 那么它們是如何知道使用那些認證信息的? 其實默認它們使用的都是 ~/.kube/config 中的認證信息,但是若我們 需要使用多個不同權限的賬戶來訪問集群,是不是要不斷的切換系統賬戶,才能使用不同的~/.kube/config ? 若有多個集群,是否也需要創建多個系統賬戶,在不同系統賬戶的家目錄下創建不同的.kube/config ? 其實這是不必的,在K8s中,認證信息被稱為kubeconfig, 它可使用下面命令查看: # kubectl config view apiVersion: v1 kind: Config preferences: {} clusters: #這是定義一個要管理的K8s集群,可定義多個,若需要同時管理多個集群時. - cluster: #這是服務器端的證書數據,用於客戶端驗證APIserver的.REDACTED:表示真實數據以隱藏. certificate-authority-data: REDACTED server: https://172.20.0.70:6443 #指明API Server的地址 name: kubernetes #給這個集群信息取一個名字叫 kubernetes users: #這是定義一個登陸某K8s集群時,使用的用戶賬戶信息,若需要管理多個集群,就需要定義多個. #當然一個集群也可有多個不同權限的賬號. - name: kubernetes-admin #定義這個用戶的用戶名叫 kubernetes-admin user: client-certificate-data: REDACTED #定義此用戶的證書數據 client-key-data:REDACTED #定義此用戶的私鑰數據 contexts: #這是定義一個訪問集群的上下文信息,即那個users + 那個clusters = 登陸該cluster,它也可定義多個. - context: cluster: kubernetes #這里指明要登陸kubernetes這個集群,需要使用 user: kubernetes-admin # kubernetes-admin這個用戶認證數據。 name: kubernetes-admin@kubernetes #為這個上下文定義一個引用名字 current-context: kubernetes-admin@kubernetes #指明當前使用kubernetes-admin@kubernetes這個上下文來登陸集群。 創建一個自定義用戶來登陸API Server: cd /etc/kubernetes/ssl #這是kubeasz部署后,CA證書默認存放位置。 cp admin-csr.json test-csr.json
vim test-csr.json { "CN": "test", "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "HangZhou", "L": "XS" } ] } # grep -A1 'profile' ca-config.json "profiles": { "kubernetes": { # cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes test-csr.json | cfssljson -bare test 查看創建的證書: openssl x509 -in test.pem -text -noout #-text:使用文本輸出, -noout: 不適應base64編碼. 注: Issuer: 顯示當前證書是由誰來簽署的. Subject: 中顯示的CN是連入K8s集群的用戶賬戶名 Validity: 這是顯示當前證書的有效期限. 創建k8s的認證信息(kubeconfig): kubectl config set-credentials testuser --client-certificate=./test.crt \ --client-key=./test.key --embed-certs=true 注: --embed-certs: ture:表示將證書和私鑰包含到k8s中,並且隱藏不顯示具體數據. 若需要創建token認證信息: kubectl config set-credentials testuser --token=預共享的密鑰 若需要創建基於用戶名和密碼的認證信息: kubectl config set-credentials testuser --username=test --password=PU@&@Xs 若要基於外部認證信息需要使用: --auth-provider= 和 --auth-provider-arg=.. 等信息。 查看kubeconfig的信息: kubectl config view #可以看到剛創建的testuser的相關信息. 接着讓test可以訪問kubernetes集群: kubectl config set-context test@kubernetes --cluster=kubernetes --user=test 使用自己定義的用戶做為當前連接K8s集群的用戶: kubectl config use-context test@kubernetes kubectl get pods #將看到權限被拒絕的錯誤 切換回管理員權限: kubectl config use-context ... 創建一個新集群配置信息: kubectl config set-cluster mycluster --kubeconfig=/tmp/test.conf --server="https://1.1.1.2:6443" \ --certificate-authority=/etc/kubernetes/pki/ca.crt --embed-certs=true 查看: kubectl config view --kubeconfig=/tmp/test.conf
K8s的授權插件:
Node, ABAC, RBAC, Webhook
下面主要以RBAC(Role-based Access Controller)來介紹。
RBAC: 基於角色的授權認證
重要概念:
Role(角色):它通過內生的一種叫“角色”的概念,來完成對權限的授予和分配等,所以從此角度講 角色 是一個組織或任務中的職位或位置,它通常代表一種權力或資格。
Permission(許可):其實就是權限,而權限是多種Operations(操作)的集合,而Operations是附加在對象(Object)上的具體Action(動作),每一個Action就是一個Operation,
多個Operation就是Operations,即權限。
RBAC授權的過程:
首先,K8s中訪問資源其實就是發起HTTP訪問, HTTP訪問的通用URL格式為:
http://API_SERVER:PORT/<API_GROUP>/<API_VERSION>/namespaces/<NAMESPACE_NAME>/<KIND>[/OBJECT_ID]
而授權是一個組合userAccount或serviceAccount ,role 和 permission 的過程。
第一步要先組合Permission,因為Permission是有 Action組成的,而Action=Operation+Object。
Operation(操作): 它是GET,PUT,POST,DELETE,PATCH等,當然我這里列出的HTTP的原始方法,在K8s中它們是CREATE,GET,PATCH,DELETE,PROXY,WATCH,UPDATE等
Object(對象): 在K8s中,一切皆對象,它的對象分為三類:
1. 一般對象:基本上涵蓋了絕大部分資源主體。
2. 對象列表:就如:namespaceList
3. 虛擬對象(或叫 非對象資源):這部分通常是一些URL,很少。
知道了Operation和Object,那么Action就是它倆的組合。
比如:我定義一個Action是 GET + /api/v1/namespaces/default/pod/myapp-0 ,這就表示,我定義了一個只能列出默認名稱空間下pod類型資源中myapp-0的動作。
類似這種Action,我可以定義很多個,然后將其打包成Permissions,這樣我就有了一個授權。
第二步 就是要定義一個role
Role(角色):實際上,role可理解為一組Permissions的組合,即 我將一組權限打包后,取一個名字。
這就類似於公司中的職位一樣,技術部主管,就相當於一個Role,他的Permission就是能做什么,他能管理職員,他能管理部門內資源配置等。
第三步 就是將user 和 role關聯綁定,稱為rolebinding
這就相當於公司的中職位授予,如:A能力很強,公司授予他,技術部總監,另外還兼職公司副CTO等。
用上面兩個集群來說明Role,RoleBinding 和 clusterRole,clusterRoleBinding
集群1:
每個名稱空間(Namespace)中,為了定義一個此名稱空間的管理員,不得不每個名稱空間都創建相同的Admin Role,然后使用roleBinding將AdminRole關聯到用戶上,來讓指定用戶成為此名稱空間中的管理員。這樣做很顯然,非常繁瑣,若名稱空間很多,就要在這些名稱空間中都要做相同操作,很麻煩。
集群2:
在整個k8s集群級別創建一個admin role,然后,使用roleBinding來引用它,並將它和自己名稱空間中的用戶關聯,這樣該用戶就成功的擁有了對當前名稱空間的管理員權限。
這樣就很省事了。只需要創建一個集群級別的admin role即可。為啥這樣做可以? 因為所有名稱空間里的管理員操作基本都一樣,都是GET pod,update pod等等這些操作,因此將這些相同操作都定義為集群role,這樣就可讓所有名稱空間都可以引用它了,它就相當於一個模板了。但具體在自己的名稱空間中時,它就相當於被具體化為本名稱空間中的admin role了。
若現在還想創建一個用戶擁有管理所有名稱空間中的所有資源,就需要使用ClusterRoleBinding了,它能將ClusterRole具體化為集群級別的role,讓授予此role的用戶具有集群管理員的權限。
總的來說:
roleBinding可綁定名稱空間內部的role,也可綁定ClusterRole,但roleBinding綁定后,具體化的role是具體化成本名稱空間的role。
clusterRoleBinding:它僅可綁定ClusterRole,它具體化的role,就可訪問整個集群中所有的資源。
創建Role: kubectl create role myrole --verb=get,list,watch --resource=pods --dry-run -o yaml > role-demo.yaml #修改role-demo.yaml vim role-demo.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: myrole namespace: default rules: - apiGroups: - "" resources: - pods - deployments verbs: - get - list - watch # kubectl apply -f role-demo.yaml # kubectl describe role myrole Name: myrole ............. Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- deployments [] [] [get list watch] pods [] [] [get list watch] #這里要注意: # 若不定義Resource Names,則表示對Resources這個一類資源都可操作Verbs所指定的動作。 # Non-Resource URLs:這就是前面提到的非資源對象,或稱為虛擬URL對象, 它們是k8s中所需要的特殊動作。 創建roleBinding kubectl create rolebinding test-read-pods --role=myrole --user=test --dry-run -o yaml > rolebinding-demo.yaml vim rolebinding-demo.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: test-read-pod namespace: default roleRef: #指定要引用的role,在那個API組中,它的類型是role,還是clusterRole,還有要引用role的具體名稱。 apiGroup: rbac.authorization.k8s.io kind: Role name: myrole subjects: #注意:subjects是對k8s中兩種訪問資源的賬號的統稱,這兩種賬號是 userAccount 和 serviceAccount - apiGroup: rbac.authorization.k8s.io kind: User #此處的kind並非真實的k8s資源類型,僅用於標識, 它只能是 user, group,serviceAccount name: test namespace: default #因為test用戶可能在多個名稱空間都有,因此最好加上namespace做限定。 #kubectl apply -f rolebinding-demo.yaml #kubectl describe rolebinding test-read-pod .................... Role: Kind: Role Name: myrole Subjects: Kind Name Namespace ---- ---- --------- User test 測試切換到test用戶,查看權限是否生效 kubectl config use-context test@kubernetes #但測試發現,test用戶可以列出所有名稱空間的所有資源,這個我很是不解? # 此問題:注解部分在: k8s集群認證 > admin權限問題 但其中原理還是不明。 創建clusterRole: kubectl create clusterrole clusterRole-manger-pods \ --verb=get,list,watch,create,update,delete \ --resource=pods,rs.extensions \ --dry-run -o yaml > clusterrole-pod-manger.yaml vim clusterrole-pods-manger.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: creationTimestamp: null name: clusterRole-manger-pods rules: - apiGroups: #注意: pods就是主API,它沒有子API,因此其api組為空 - "" resources: - pods verbs: - get - list - watch - delete - create - update - apiGroups: #replicaSet控制器有兩個子API組,一個是apps,一個是extensions,所以這里必須指定,你要授予那個子API組權限. - extensions #否則,綁定此role的用戶僅能訪問replicSet主組的資源,但replicaSet其實沒有主組,因此實際上就沒有給綁定用戶訪問replicaSet的權限. resources: - replicasets verbs: - get - list - watch - delete - create - update #創建此ClusterRole kubectl apply -f clusterrole-pods-manger.yaml #使用rolebinding來綁定此clusterRole kubectl create rolebinding rbind-clusterRoleMangerPods \ --clusterrole=clusterRole-manger-pods --user=test \ --dry-run -o yaml >rbind-clusterRoleMangerPods.yaml # vim rbind-clusterRoleMangerPods.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: rbind-clusterRoleMangerPods namespace: default #這里指定將該rolebinding創建在default 名稱空間中 roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: clusterRole-manger-pods subjects: - apiGroup: rbac.authorization.k8s.io kind: User name: test #創建此rolebinding kubectl apply -f rbind-clusterRoleMangerPods.yaml #測試此clusterRole kubectl config use-context test@kubernetes #測試是否能獲取pod 和 replicasets.extensions 的資源 kubectl get pods kubectl get rs #創建clusterRoleBinding kubectl create clusterrolebinding cbind-crolePodManger \ --clusterrole=clusterRole-manger-pods --user=test \ --dry-run -o yaml > cbind-demo.yaml vim cbind-demo.yaml apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: name: cbind-crolePodManger roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: clusterRole-manger-pods subjects: - apiGroup: rbac.authorization.k8s.io kind: User name: test #切換用戶 kubectl config use-context test@kubernetes #測試是否能看不同名稱空間的資源. kubectl get pod -n kube-system kubectl get rs -n ingress-nginx