?? 歡迎大家來到景天科技苑??
🎈🎈 養成好習慣,先贊后看哦~🎈🎈
🏆 作者簡介:景天科技苑
🏆《頭銜》:大廠架構師,華為云開發者社區專家博主,阿里云開發者社區專家博主,CSDN全棧領域優質創作者,掘金優秀博主,51CTO博客專家等。
🏆《博客》:Python全棧,前后端開發,小程序開發,人工智能,js逆向,App逆向,網絡系統安全,數據分析,Django,fastapi,flask等框架,云原生k8s,linux,shell腳本等實操經驗,網站搭建,數據庫等分享。所屬的專欄:云原生K8S,零基礎到進階實戰
景天的主頁:景天科技苑
文章目錄
- 1、k8s安全管理:認證、授權、準入控制概述
- 1.1 認證
- 1、認證支持多種插件
- 2、kubernetes上的賬號
- 3.kubeconfig文件
- 1.2 授權
- 1.3 準入控制
- 2、Useraccount和ServiceAccount介紹
- ServiceAccount使用案例介紹
- 3、對sa做授權
- 4、RBAC認證授權策略
- 4.1 Role:角色
- 4.2 ClusterRole:集群角色
- 4.3 RoleBinding:角色綁定、ClusterRolebinding:集群角色綁定
- 5、資源的引用方式
- 6、常見角色(role)授權的案例
- 7、常見的角色綁定示例
- 8、對Service Account的授權管理
- 9、使用kubectl命令行工具創建資源對象
- (1)在命名空間rbac中為用戶es授權admin ClusterRole:
- (2)在命名空間rbac中為名為myapp的Service Account授予view ClusterRole:
- (3)在全集群范圍內為用戶root授予cluster-admin ClusterRole:
- (4)在全集群范圍內為名為myapp的Service Account授予view ClusterRole:
- 10、限制不同的用戶操作k8s集群
- ssl認證
- 11、準入控制
- 11.1 ResourceQuota準入控制器
- 1.限制cpu、內存、pod、deployment數量
- 2.限制存儲空間大小
- 11.2 LimitRanger準入控制器
- 1)在limit名稱空間創建pod,不指定資源,看看是否會被limitrange規則自動附加其資源限制?
- 2)創建pod,指定cpu請求是100m,看看是否允許創建
1、k8s安全管理:認證、授權、準入控制概述
k8s對我們整個系統的認證,授權,訪問控制做了精密的設置;對于k8s集群來說,
apiserver是整個集群訪問控制的唯一入口,我們在k8s集群之上部署應用程序的時候,
也可以通過宿主機的NodePort暴露的端口訪問里面的程序,
用戶訪問kubernetes集群需要經歷如下認證過程:認證->授權->準入控制(adminationcontroller)
-
1.認證(Authenticating)是對客戶端的認證,通俗點就是用戶名密碼驗證
-
2.授權(Authorization)是對資源的授權,k8s中的資源無非是容器,
最終其實就是容器的計算,網絡,存儲資源,當一個請求經過認證后,需要訪問某一個資源(比如創建一個pod),
授權檢查會根據授權規則判定該資源(比如某namespace下的pod)是否是該客戶可訪問的。 -
3.準入(Admission Control)機制:
準入控制器(Admission Controller)位于 API Server 中,在對象被持久化之前,
準入控制器攔截對 API Server 的請求,一般用來做身份驗證和授權。其中包含兩個特殊的控制器:
MutatingAdmissionWebhook 和 ValidatingAdmissionWebhook。分別作為配置的變異和驗證準入控制 webhook。
變更(Mutating)準入控制:修改請求的對象
驗證(Validating)準入控制:驗證請求的對象
準入控制器是在 API Server 的啟動參數配置的。一個準入控制器可能屬于以上兩者中的一種,也可能兩者都屬于。
當請求到達 API Server 的時候首先執行變更準入控制,然后再執行驗證準入控制。
我們在部署 Kubernetes 集群的時候都會默認開啟一系列準入控制器,
如果沒有設置這些準入控制器的話可以說你的 Kubernetes 集群就是在裸奔,應該只有集群管理員可以修改集群的準入控制器。
例如我會默認開啟如下的準入控制器。
--admission-control=ServiceAccount,NamespaceLifecycle,NamespaceExists,LimitRanger,ResourceQuota,MutatingAdmissionWebhook,
ValidatingAdmissionWebhook
k8s的整體架構也是一個微服務的架構,所有的請求都是通過一個GateWay,
也就是kube-apiserver這個組件(對外提供REST服務),k8s中客戶端有兩類,
一種是普通用戶,一種是集群內的Pod,這兩種客戶端的認證機制略有不同,但無論是哪一種,
都需要依次經過認證,授權,準入這三個機制。
1.1 認證
1、認證支持多種插件
(1)令牌(token)認證:
雙方有一個共享密鑰,服務器上先創建一個密碼下來,客戶端登陸的時候拿這個密碼登陸即可,
這個就是對稱密鑰認證方式;k8s提供了一個restful風格的接口,它的所有服務都是通過http協議提供的,
因此認證信息只能經由http協議的認證首部進行傳遞,這種認證首部進行傳遞通常叫做令牌;
(2)ssl認證:
對于k8s訪問來講,ssl認證能讓客戶端確認服務器的認證身份,我們在跟服務器通信的時候,
需要服務器發過來一個證書,我們需要確認這個證書是不是ca簽署的,如果是我們認可的ca簽署的,
里面的subjects信息與我們訪問的目標主機信息保持一致,沒有問題,那么我們就認為服務器的身份得到認證了,
k8s中最重要的是服務器還需要認證客戶端的信息,kubectl也應該有一個證書,這個證書也是server所認可的ca簽署的證書,
雙方需要互相認證,實現加密通信,這就是ssl認證。
2、kubernetes上的賬號
客戶端對apiserver發起請求,apiserver要識別這個用戶是否有請求的權限,
要識別用戶本身能否通過apiserver執行相應的操作,
那么需要哪些信息才能識別用戶信息來完成對用戶的相關的訪問控制呢?
kubectl explain pods.spec可以看到有一個字段serviceAccountName(服務賬號名稱),
這個就是我們pod連接apiserver時使用的賬號,
因此整個kubernetes集群中的賬號有兩類,
ServiceAccount(服務賬號),User account(用戶賬號)
User account:實實在在現實中的人,人可以登陸的賬號,客戶端想要對apiserver發起請求,
apiserver要識別這個客戶端是否有請求的權限,那么不同的用戶就會有不同的權限,靠用戶賬號表示,叫做username,是kubectl調用的賬號
我們執行kubectl時,使用的用戶時經過RBAC授權的
[root@master01 ~ ]#cat .kube/config
apiVersion: v1
clusters:
- cluster:certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLvdsffsfvakNDQWVhZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJeU1Ea3hOREF5TURjek5Wb1hEVE15TURreE1UQXlNRGN6TlZvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTVB0CmJNNHg3STgvK01FQ29nY3lTNFRxK0ZzVHVtZi9JeFNXMXY4Q3NHVHVodEgrVElia21oYmlvenI4U0JtSGR2L1YKYTRjSjdzNGhxcE1LTnRiNk1IK1VZN0JqT25OT0J6TWYwbTg2cS9rRVFGRmZEdlRIU0kzYzBXK3BaRHZ5Y1EregphdXRGOHRjTWFtWk9KQU95U2xBN3NOelFCYlgrQW9lVFE0a29aVURGQm1oZjNIamdkanVtV3NERnZwVHMvd0wxCmlaV2p5dFd3c3J4RDIxK1lwa0ZkVUhRYnlxR2VuT0JscUYxbWhoTjkyY2VDcW80TDJSQlRYQXlKNVMxdG5EZ2gKR1B6WFNzN2cwNmhaaTlycEhPZ0RjdjByenBvdEdLc21LQm9DZ2RmcXovYlJ0UDk3UlA5ampXUHdDdUllR3Vwcwp6WGI4a1RINThleFp1cXNiS2dzQ0F3RUFBYU5aTUZjd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZMUFRZRWppaWUrU3RYbENVK1REaWVRT3BjdWZNQlVHQTFVZEVRUU8KTUF5Q0NtdDFZbVZ5Ym1WMFpYTXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBSDF6OHZjazBDaVZPT1J5QXZRYQpXV0s3WSt0WWZNSXhzcVBkU3A5My9yeXl2MkE0dWhTQjRiMDRGTmlLNWp4b2cvaDhoWmxIbFJoNDZzaUdMWlRjCmgwUHhmSlZ5L3UvdzNXZ2N0bXJMVTJ1VHVkcERkNm10YlhJRGhNempGWlh1VjFQa01oQk5ZVDUxS1hqY0dmTkMKY1JxMm5Vc1dCM0U5SjZJakNhWi80ME9wcjZBYUNoNWlWRUpmUzR6M3hHcm1uQ0lBeG5UaHBVUHEybjJ1NjZXOApQc2FvS0ZmTmZkUlEvSk5CUHVDUUs2RzRZM0syVEFYRkFMQzFXNEVmRmhKWUQ5RkxzQVk0TjUwQ1p2OVFNOXFuCmhrcW5SSGJqSGI4ZWdITThSRFU0UWNybm9IZzMycnB2MUtWcnZtVExQVVZ5dm85eUZpSm53ZzBJVVF3Rlc1R1UKelQwPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==server: https://10.10.0.10:6443name: kubernetes
contexts:
- context:cluster: kubernetesuser: kubernetes-adminname: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
使用的是kubernetes-admin這個用戶,這個是user account
ServiceAccount:方便Pod里面的進程調用Kubernetes API或其他外部服務而設計的,是kubernetes中的一種資源
sa賬號:登陸dashboard使用的賬號
user account:這個是登陸k8s物理機器的用戶
1.ServiceAccount
Service account是為了方便Pod里面的進程調用Kubernetes API或其他外部服務而設計的。
它與User account不同,User account是為人設計的,而service account則是為Pod中的進程調用Kubernetes API而設計;
User account是跨namespace的,而service account則是僅局限它所在的namespace;
每個namespace都會自動創建一個default service account;
開啟ServiceAccount Admission Controller后
1)每個Pod在創建后都會自動設置spec.serviceAccount為default(除非指定了其他ServiceAccout)
2)驗證Pod引用的service account已經存在,否則拒絕創建;
當創建 pod 的時候,如果沒有指定一個 serviceaccount,
系統會自動在與該pod 相同的 namespace 下為其指派一個default service account。
這是pod和apiserver之間進行通信的賬號,如下:
kubectl get pods siweb-866d9955bd-pjg8r -n h5-web -oyaml|grep -i "serviceaccountname"
查看某命名空間下有哪些sa
kubectl get sa -n h5-web
查看密鑰
kubectl get secret -n h5-web
默認有一個default-token-h5fdg
創建sa時,會自動創建一個secret
[root@master01 ~ ]#kubectl create sa test
serviceaccount/test created
[root@master01 ~ ]#
[root@master01 ~ ]#
[root@master01 ~ ]#kubectl get sa
NAME SECRETS AGE
default 1 12d
nfs-provisioner 1 5d2h
test 1 4s
[root@master01 ~ ]#kubectl describe sa test
Name: test
Namespace: default
Labels: <none>
Annotations: <none>
Image pull secrets: <none>
Mountable secrets: test-token-h9tkr
Tokens: test-token-h9tkr
Events: <none>
[root@master01 ~ ]#kubectl get secret
NAME TYPE DATA AGE
default-token-xc8dr kubernetes.io/service-account-token 3 12d
mysecret Opaque 2 3h12m
mysql-password Opaque 1 3h27m
nfs-provisioner-token-8mxt9 kubernetes.io/service-account-token 3 5d2h
test-token-h9tkr kubernetes.io/service-account-token 3 20s 這個就是新創建的secret
[root@master01 ~ ]#kubectl describe secret test-token-h9tkr
Name: test-token-h9tkr
Namespace: default
Labels: <none>
Annotations: kubernetes.io/service-account.name: testkubernetes.io/service-account.uid: edd4d5c7-403c-4bc3-8a7b-4912def671e7Type: kubernetes.io/service-account-tokenData
====
ca.crt: 1099 bytes
namespace: 7 bytes
token: eyJhbGciOiJSUzI1NiIsImtpZCI6InFpN2JVd1VkbllDM3dvSk1INkdRUVhqUExMejNEeVJWQnlHM0dUR052VWcifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6InRlc3QtdG9rZW4taDl0a3IiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoidGVzdCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6ImVkZDRkNWM3LTQwM2MtNGJjMy04YTdiLTQ5MTJkZWY2NzFlNyIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OnRlc3QifQ.N9R_IoTJrrKLINaKw_A-xT1FfVTyHGYpIshcpZrQ_40o6gEEnaye4KY4HRrIQG-tXbVERMQcsHEJBFu7W2nmWHlN-Ar-1BgSYGWYKbemqXhht7zQwK6RWMxF9cV-mu-66m4IPTA7Hxl2XrH8R4c7bcmsPN4nSCBGwJsE2c2pItXpckuCaeHoXQOQ7PSMAdLjiZaZO4gVnYuIH-01uJauss0ofh7uXk5O8WrDM-EM-QuQLFrgzSwmFrWzqiPWIC11XnF1p5RyRXhyje5F0UZfhZ92rtLr4k-uzWs0VwjCpMoMremW_3UEnLN1nDa7anU9gFOBIW8UlWi_94NcIdv4LA
這個token就是創建sa時創建的token
從上面可以看到每個Pod無論定義與否都會有個存儲卷,這個存儲卷為default-token-***。
pod和apiserver的認證信息通過secret進行定義,由于認證信息屬于敏感信息,所以需要保存在secret資源當中,
并以存儲卷的方式掛載到Pod當中。從而讓Pod內運行的應用通過對應的secret中的信息來連接apiserver,并完成認證。
每個 namespace 中都有一個默認的叫做 default 的 serviceaccount 資源。
查看名稱空間內的secret,也可以看到對應的default-token。
讓當前名稱空間中所有的pod在連接apiserver時可以使用的預制認證信息,從而保證pod之間的通信。
默認的service account 僅僅只能獲取當前Pod自身的相關屬性,
無法觀察到其他名稱空間Pod的相關屬性信息。
如果想要擴展Pod,假設有一個Pod需要用于管理其他Pod或者是其他資源對象,
是無法通過自身的名稱空間的serviceaccount進行獲取其他Pod的相關屬性信息的,
此時就需要進行手動創建一個serviceaccount,并在創建Pod時進行定義。
那么serviceaccount該如何進行定義呢?實際上,service accout也屬于一個k8s資源,
serviceAccount也屬于標準的k8s資源,可以創建一個serviceAccount,
創建之后由我們創建的pod使用serviceAccountName去加載自己定義的serviceAccount就可以了,如下:
(1)創建一個serviceaccount:
kubectl create serviceaccount test
[root@master01 RBAC ]#kubectl get sa
NAME SECRETS AGE
default 1 12d
nfs-provisioner 1 5d15h
test 1 13h
可以看到已經創建了test的serviceacount
kubectl describe sa test 查看test這個賬號的詳細信息
[root@master01 RBAC ]#kubectl describe sa test
Name: test
Namespace: default
Labels: <none>
Annotations: <none>
Image pull secrets: <none>
Mountable secrets: test-token-h9tkr
Tokens: test-token-h9tkr
Events: <none>
上面可以看到生成了一個test-token-h9tkr的secret和test-token-h9tkr的token
kubectl get secret 顯示如下:
[root@master01 RBAC ]#kubectl get secret
NAME TYPE DATA AGE
default-token-xc8dr kubernetes.io/service-account-token 3 12d
mysecret Opaque 2 16h
mysql-password Opaque 1 16h
nfs-provisioner-token-8mxt9 kubernetes.io/service-account-token 3 5d15h
test-token-h9tkr kubernetes.io/service-account-token 3 13h
kubectl describe secret test-token-h9tkr 顯示如下:
[root@master01 RBAC ]#kubectl describe secret test-token-h9tkr
Name: test-token-h9tkr
Namespace: default
Labels: <none>
Annotations: kubernetes.io/service-account.name: testkubernetes.io/service-account.uid: edd4d5c7-403c-4bc3-8a7b-4912def671e7Type: kubernetes.io/service-account-tokenData
====
ca.crt: 1099 bytes
namespace: 7 bytes
token: eyJhbGciOiJSUzI1NiIsImtpZCI6InFpN2JVd1VkbllDM3dvSk1INkdRUVhqUExMejNEeVJWQnlHM0dUR052VWcifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6InRlc3QtdG9rZW4taDl0a3IiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoidGVzdCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6ImVkZDRkNWM3LTQwM2MtNGJjMy04YTdiLTQ5MTJkZWY2NzFlNyIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OnRlc3QifQ.N9R_IoTJrrKLINaKw_A-xT1FfVTyHGYpIshcpZrQ_40o6gEEnaye4KY4HRrIQG-tXbVERMQcsHEJBFu7W2nmWHlN-Ar-1BgSYGWYKbemqXhht7zQwK6RWMxF9cV-mu-66m4IPTA7Hxl2XrH8R4c7bcmsPN4nSCBGwJsE2c2pItXpckuCaeHoXQOQ7PSMAdLjiZaZO4gVnYuIH-01uJauss0ofh7uXk5O8WrDM-EM-QuQLFrgzSwmFrWzqiPWIC11XnF1p5RyRXhyje5F0UZfhZ92rtLr4k-uzWs0VwjCpMoMremW_3UEnLN1nDa7anU9gFOBIW8UlWi_94NcIdv4LA
上面可以看到生成了test-token-h9tkr的token詳細信息,
這個token就是sa連接apiserver的認證信息,這個token也是登陸k8s dashboard的token,
這些是一個認證信息,能夠登陸k8s,能認證到k8s,但是不能做別的事情,不代表權限,想要做其他事情,需要授權
3.kubeconfig文件
在K8S集群當中,每一個用戶對資源的訪問都是需要通過apiserver進行通信認證才能進行訪問的,
那么在此機制當中,對資源的訪問可以是token,也可以是通過配置文件的方式進行保存和使用認證信息,
可以通過kubectl config進行查看配置,如下:
[root@master01 RBAC ]#kubectl config view
apiVersion: v1
clusters:
- cluster:certificate-authority-data: DATA+OMITTEDserver: https://10.10.0.10:6443 #apiserver的地址name: kubernetes #集群的名字
contexts:
- context:cluster: kubernetesuser: kubernetes-adminname: kubernetes-admin@kubernetes #上下文的名字
current-context: kubernetes-admin@kubernetes #當前上下文的名字
kind: Config
preferences: {}
users:
- name: kubernetes-adminuser:client-certificate-data: REDACTEDclient-key-data: REDACTED
在上面的配置文件當中,定義了集群、上下文以及用戶。其中Config也是K8S的標準資源之一,
在該配置文件當中定義了一個集群列表,指定的集群可以有多個;用戶列表也可以有多個,
指明集群中的用戶;而在上下文列表當中,是進行定義可以使用哪個用戶對哪個集群進行訪問,以及當前使用的上下文是什么。
認證就是被人信任
指定認證文件
kubectl get pods --kubeconfig=./config
1.2 授權
如果用戶通過認證,什么權限都沒有,需要一些后續的授權操作,如對資源的增刪該查等,
kubernetes1.6之后開始有RBAC(基于角色的訪問控制機制)授權檢查機制。
Kubernetes的授權是基于插件形成的,其常用的授權插件有以下幾種:
1)Node(節點認證)
2)ABAC(基于屬性的訪問控制)
3)RBAC(基于角色的訪問控制)***
4)Webhook(基于http回調機制的訪問控制)
什么是RBAC(基于角色的訪問控制)?
讓一個用戶(Users)扮演一個角色(Role),角色擁有權限,從而讓用戶擁有這樣的權限,
隨后在授權機制當中,只需要將權限授予某個角色,此時用戶將獲取對應角色的權限,從而實現角色的訪問控制。如圖:
在k8s的授權機制當中,采用RBAC的方式進行授權,其工作邏輯是,把對對象的操作權限定義到一個角色當中,
再將用戶綁定到該角色,從而使用戶得到對應角色的權限。如果通過rolebinding綁定role,
只能對rolebingding所在的名稱空間的資源有權限,上圖user1這個用戶綁定到role1上,
只對role1這個名稱空間的資源有權限,對其他名稱空間資源沒有權限,屬于名稱空間級別的;
另外,k8s為此還有一種集群級別的授權機制,就是定義一個集群角色(ClusterRole),
對集群內的所有資源都有可操作的權限,
從而將User2通過ClusterRoleBinding到ClusterRole,從而使User2擁有集群的操作權限。
Role、RoleBinding、ClusterRole和ClusterRoleBinding的關系如下圖:
通過上圖可以看到,可以通過rolebinding綁定role,rolebinding綁定clusterrole,clusterrolebinding綁定clusterrole。
上面我們說了兩個角色綁定:
(1)用戶通過rolebinding綁定role, 限定在rolebinding所在的名稱空間,有權限
(2)用戶通過clusterrolebinding綁定clusterrole 集群內所有名稱空間都有權限
clusterrolebinding綁定clusterrole的好處:
用戶user1通過clusterrolebinding 綁定clusterrole ,然后這個user1對任何名稱空間的資源都有了權限
(3)還有一種:rolebinding綁定clusterrole
cluserrole創建時不用指定名稱空間,對clusterrole進行授權,讓它具有操作K8S資源的權限,
然后用戶只需要在不同的名稱空間創建不同的rolebinding,綁定clusterrole即可
rolebinding綁定clusterrole的好處:
假如有6個名稱空間,每個名稱空間的用戶都需要對自己的名稱空間有管理員權限,
那么需要定義6個role和rolebinding,然后依次綁定,如果名稱空間更多,我們需要定義更多的role,
這個是很麻煩的,所以我們引入clusterrole,定義一個clusterrole,對clusterrole授予所有權限,
然后用戶通過rolebinding綁定到clusterrole,就會擁有自己名稱空間的管理員權限了
注:RoleBinding僅僅對當前名稱空間有對應的權限。
1.3 準入控制
一般而言,準入控制只是用來定義我們授權檢查完成之后的后續的其他安全檢查操作的,
進一步補充了授權機制,由多個插件組合實行,一般而言在創建,刪除,修改或者做代理時做補充;
Kubernetes的Admission Control實際上是一個準入控制器(Admission Controller)插件列表,
發送到APIServer的請求都需要經過這個列表中的每個準入控制器插件的檢查,如果某一個控制器插件準入失敗,就準入失敗。
控制器插件如下:
AlwaysAdmit:允許所有請求通過
AlwaysPullImages:在啟動容器之前總是去下載鏡像,相當于每當容器啟動前做一次用于是否有權使用該容器鏡像的檢查
AlwaysDeny:禁止所有請求通過,用于測試
DenyEscalatingExec:拒絕exec和attach命令到有升級特權的Pod的終端用戶訪問。
如果集中包含升級特權的容器,而要限制終端用戶在這些容器中執行命令的能力,推薦使用此插件
ImagePolicyWebhook
ServiceAccount:這個插件實現了serviceAccounts等等自動化,如果使用ServiceAccount對象,強烈推薦使用這個插件SecurityContextDeny:將Pod定義中定義了的SecurityContext選項全部失效。
SecurityContext包含在容器中定義了操作系統級別的安全選型如fsGroup,selinux等選項
ResourceQuota:用于namespace上的配額管理,它會觀察進入的請求,
確保在namespace上的配額不超標。推薦將這個插件放到準入控制器列表的最后一個。
ResourceQuota準入控制器既可以限制某個namespace中創建資源的數量,
又可以限制某個namespace中被Pod請求的資源總量。ResourceQuota準入控制器和ResourceQuota資源對象一起可以實現資源配額管理。
LimitRanger:用于Pod和容器上的配額管理,它會觀察進入的請求,
確保Pod和容器上的配額不會超標。準入控制器LimitRanger和資源對象LimitRange一起實現資源限制管理
NamespaceLifecycle:當一個請求是在一個不存在的namespace下創建資源對象時,
該請求會被拒絕。當刪除一個namespace時,將會刪除該namespace下的所有資源對象
DefaultStorageClass
DefaultTolerationSeconds
PodSecurityPolicy
當Kubernetes版本>=1.6.0,官方建議使用這些插件:admission-control=NamespaceLifecycle,LimitRanger,ServiceAccount,
PersistentVolumeLabel,DefaultStorageClass,ResourceQuota,DefaultTolerationSeconds
當Kubernetes版本>=1.4.0,官方建議使用這些插件:
admission-control=NamespaceLifecycle,LimitRanger,
ServiceAccount,DefaultStorageClass,ResourceQuota
以上是標準的準入插件,如果是自己定制的話,
k8s1.7版 出了兩個alpha features, Initializers 和 External Admission Webhooks
在k8s上準入控制器的模塊有很多,
其中比較常用的有LimitRanger、ResourceQuota、ServiceAccount、這幾種默認開啟。PodSecurityPolicy(k8s1.25廢棄了)等等,
對于前面三種準入控制器系統默認是啟用的,我們只需要定義對應的規則即可;
對于PodSecurityPolicy(k8s1.25廢棄了)這種準入控制器,系統默認沒有啟用,如果我們要使用,
就必需啟用以后,對應規則才會正常生效;這里需要注意一點,對應psp準入控制器,一定要先寫好對應的規則,
把規則和權限綁定好以后,在啟用對應的準入控制器,否則先啟用準入控制器,沒有對應的規則,
默認情況它是拒絕操作,這可能導致現有的k8s系統跑的系統級pod無法正常工作;所以對于psp準入控制器要慎用,
如果規則和權限做的足夠精細,它會給我們的k8s系統安全帶來大幅度的提升,反之,可能導致整個k8s系統不可用。
查看apiserver啟用的準入控制器有哪些?
[root@master01 containers ]#cat /etc/kubernetes/manifests/kube-apiserver.yaml
apiVersion: v1
kind: Pod
metadata:annotations:kubeadm.kubernetes.io/kube-apiserver.advertise-address.endpoint: 10.10.0.10:6443creationTimestamp: nulllabels:component: kube-apiservertier: control-planename: kube-apiservernamespace: kube-system
spec:containers:- command:- kube-apiserver- --feature-gates=RemoveSelfLink=false- --advertise-address=10.10.0.10- --allow-privileged=true- --authorization-mode=Node,RBAC- --client-ca-file=/etc/kubernetes/pki/ca.crt- --enable-admission-plugins=NodeRestriction- --enable-bootstrap-token-auth=true- --etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt
提示:
apiserver啟用準入控制插件需要使用–enable-admission-plugins選項來指定,
該選項可以使用多個值,用逗號隔開表示啟用指定的準入控制插件;
這里配置文件中顯式啟用了NodeRestrication這個插件;
默認沒有寫在這上面的內置準入控制器,它也是啟用了的,
比如LimitRanger、ResourceQuota、ServiceAccount等等;
對于不同的k8s版本,內置的準入控制器和啟用與否請查看相關版本的官方文檔;
對于那些沒有啟動的準入控制器,我們可以在上面選項中直接啟用,分別用逗號隔開即可。
對應的官網地址:
https://kubernetes.io/zh-cn/docs/reference/access-authn-authz/admission-controllers/
要修改準入控制,只需要修改kube-apiserver.yaml文件,然后重啟kubelet就可以生效
2、Useraccount和ServiceAccount介紹
kubernetes中賬戶分為:UserAccounts(用戶賬戶) 和 ServiceAccounts(服務賬戶) 兩種:
UserAccount是給kubernetes集群外部用戶使用的,如kubectl訪問k8s集群要用useraccount用戶,
kubeadm安裝的k8s,默認的useraccount用戶是kubernetes-admin;而且這個用戶是被證書簽發的用戶
k8s客戶端(一般用:kubectl) ------>API Server
APIServer需要對客戶端做認證,使用kubeadm安裝的K8s,
會在用戶家目錄下創建一個認證配置文件 .kube/config 這里面保存了客戶端訪問API Server的密鑰相關信息,
這樣當用kubectl訪問k8s時,它就會自動讀取該配置文件,向API Server發起認證,然后完成操作請求。
用戶名稱可以在kubeconfig中查看
[root@master01 ~ ]#cd .kube/
[root@master01 .kube ]#ll
total 8
drwxr-x--- 4 root root 35 Sep 14 10:11 cache
-rw------- 1 root root 5634 Sep 14 10:09 config
[root@master01 .kube ]#cat config
apiVersion: v1
clusters:
- cluster:certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMvakNDQWVhZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJeU1Ea3hOREF5TURjek5Wb1hEVE15TURreE1UQXlNRGN6TlZvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTVB0CmJNNHg3STgvK01FQ29nY3lTNFRxK0ZzVHVtZi9JeFNXMXY4Q3NHVHVodEgrVElia21oYmlvenI4U0JtSGR2L1YKYTRjSjdzNGhxcE1LTnRiNk1IK1VZN0JqT25OT0J6TWYwbTg2cS9rRVFGRmZEdlRIU0kzYzBXK3BaRHZ5Y1EregphdXRGOHRjTWFtWk9KQU95U2xBN3NOelFCYlgrQW9lVFE0a29aVURGQm1oZjNIamdkanVtV3NERnZwVHMvd0wxCmlaV2p5dFd3c3J4RDIxK1lwa0ZkVUhRYnlxR2VuT0JscUYxbWhoTjkyY2VDcW80TDJSQlRYQXlKNVMxdG5EZ2gKR1B6WFNzN2cwNmhaaTlycEhPZ0RjdjByenBvdEdLc21LQm9DZ2RmcXovYlJ0UDk3UlA5ampXUHdDdUllR3Vwcwp6WGI4a1RINThleFp1cXNiS2dzQ0F3RUFBYU5aTUZjd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZMUFRZRWppaWUrU3RYbENVK1REaWVRT3BjdWZNQlVHQTFVZEVRUU8KTUF5Q0NtdDFZbVZ5Ym1WMFpYTXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBSDF6OHZjazBDaVZPT1J5QXZRYQpXV0s3WSt0WWZNSXhzcVBkU3A5My9yeXl2MkE0dWhTQjRiMDRGTmlLNWp4b2cvaDhoWmxIbFJoNDZzaUdMWlRjCmgwUHhmSlZ5L3UvdzNXZ2N0bXJMVTJ1VHVkcERkNm10YlhJRGhNempGWlh1VjFQa01oQk5ZVDUxS1hqY0dmTkMKY1JxMm5Vc1dCM0U5SjZJakNhWi80ME9wcjZBYUNoNWlWRUpmUzR6M3hHcm1uQ0lBeG5UaHBVUHEybjJ1NjZXOApQc2FvS0ZmTmZkUlEvSk5CUHVDUUs2RzRZM0syVEFYRkFMQzFXNEVmRmhKWUQ5RkxzQVk0TjUwQ1p2OVFNOXFuCmhrcW5SSGJqSGI4ZWdITThSRFU0UWNybm9IZzMycnB2MUtWcnZtVExQVVZ5dm85eUZpSm53ZzBJVVF3Rlc1R1UKelQwPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==server: https://10.10.0.10:6443
ServiceAccount是Pod使用的賬號,Pod容器的進程需要訪問API Server時用的就是ServiceAccount賬戶;
ServiceAccount僅局限它所在的namespace,每個namespace創建時都會自動創建一個default service account;
創建Pod時,如果沒有指定Service Account,Pod則會使用default Service Account。
[root@master01 RBAC ]#kubectl get pods mysql-pod -oyaml
apiVersion: v1serviceAccount: defaultserviceAccountName: default
ServiceAccount使用案例介紹
創建sa,并綁定到pod
1、創建sa
[root@master01 RBAC ]#kubectl create sa sa-test
serviceaccount/sa-test created
2、創建pod
[root@master01 RBAC ]#vim pod.yaml
apiVersion: v1
kind: Pod
metadata:name: sa-testnamespace: defaultlabels:app: sa
spec:serviceAccountName: sa-test 指定sacontainers:- name: sa-nginxports:- containerPort: 80image: nginximagePullPolicy: IfNotPresent
[root@master01 RBAC ]#kubectl get pods
NAME READY STATUS RESTARTS AGE
sa-test 1/1 Running 0 33s
創建pod時,會在pod里面創建一個目錄 /var/run/secrets/kubernetes.io/serviceaccount ,里面有sa等相關文件信息
進入pod里面,
[root@master01 RBAC ]#kubectl exec -it sa-test -- /bin/bash
root@sa-test:/# cd /var/run/secrets/kubernetes.io/serviceaccount/root@sa-test:/var/run/secrets/kubernetes.io/serviceaccount# ls
ca.crt namespace token
請求K8S資源:
基于ca.crt 這個證書,找到token,訪問kubernetes資源,訪問的是kube-system名稱空間
root@sa-test:/var/run/secrets/kubernetes.io/serviceaccount# curl --cacert ./ca.crt -H "Authorization: Bearer $(cat ./token)" https://kubernetes/api/v1/namespaces/kube-system
{"kind": "Status","apiVersion": "v1","metadata": {},"status": "Failure","message": "namespaces \"kube-system\" is forbidden: User \"system:serviceaccount:default:sa-test\" cannot get resource \"namespaces\" in API group \"\" in the namespace \"kube-system\"","reason": "Forbidden","details": {"name": "kube-system","kind": "namespaces"},"code": 403
上面結果能看到sa能通過https方式成功認證API,能夠訪問,但是沒有權限訪問k8s資源,所以code狀態碼是403,表示沒有權限操作k8s資源
3、對sa做授權
[root@master01 ~ ]#kubectl create clusterrolebinding sa-test-admin-clusterrolebinding --clusterrole=cluster-admin --serviceaccount=default:sa-test
clusterrolebinding.rbac.authorization.k8s.io/sa-test-admin-clusterrolebinding created
解讀:
kubectl create clusterrolebinding sa-test-admin-clusterrolebinding 創建clusterrolebinding ,對集群內所有名稱空間都有權限
sa-test-admin-clusterrolebinding 這個是clusterrolebinding 的名字,自己隨意取,跟已經存在的不沖突就行
–clusterrole=cluster-admin 表示與cluster-admin綁定 ,cluster-admin默認就存在的管理員,擁有集群內所有資源的所有權限,與它綁定后,
該clusterrolebinding也就有了所有集群資源權限
–serviceaccount=default:sa-test 指定sa的名稱空間和名字 default是名稱空間,sa-test是sa名字
再次請求:
root@sa-test:/var/run/secrets/kubernetes.io/serviceaccount# curl --cacert ./ca.crt -H "Authorization: Bearer $(cat ./token)" https://kubernetes/api/v1/namespaces/kube-system
{"kind": "Namespace","apiVersion": "v1","metadata": {"name": "kube-system","selfLink": "/api/v1/namespaces/kube-system","uid": "cb69328a-4655-4bdc-b105-1561b4a133fb","resourceVersion": "20","creationTimestamp": "2022-09-14T02:07:47Z","labels": {"kubernetes.io/metadata.name": "kube-system"},"managedFields": [{
可見已有權限
4、RBAC認證授權策略
RBAC介紹
在Kubernetes中,所有資源對象都是通過API進行操作,他們保存在etcd里。
而對etcd的操作我們需要通過訪問 kube-apiserver 來實現,上面的Service Account其實就是APIServer的認證過程,
而授權的機制是通過RBAC:基于角色的訪問控制實現。
RBAC有四個資源對象,分別是Role、ClusterRole、RoleBinding、ClusterRoleBinding
4.1 Role:角色
一組權限的集合,在一個命名空間中,可以用其來定義一個角色,
只能對命名空間內的資源進行授權。
如果是集群級別的資源,則需要使用ClusterRole。
例如:定義一個角色用來讀取Pod的權限
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:namespace: rbacname: pod-read
rules:
- apiGroups: [""]resources: ["pods"]resourceNames: []
verbs: ["get","watch","list"]
rules中的參數說明:
1、apiGroups:支持的API組列表,例如:"apiVersion: apps/v1"等,不寫的話支持所有api
2、resources:支持的資源對象列表,例如pods、deployments、jobs等
3、resourceNames: 指定resource的名稱,不寫指對所有的pod授權
4、verbs:對資源對象的操作方法列表。API 請求動詞 - API
動詞 get、list、create、update、patch、watch、 proxy、redirect、delete 和 deletecollection 用于資源請求
HTTP 請求動詞 - HTTP 動詞 get、post、put 和 delete 用于非資源請求。
Resource - 正在訪問的資源的 ID 或名稱(僅限資源請求)-
對于使用 get、update、patch 和 delete 動詞的資源請求,你必須提供資源名稱。
4.2 ClusterRole:集群角色
具有和角色一致的命名空間資源的管理能力,還可用于以下特殊元素的授權,對名稱空間沒有限制
1、集群范圍的資源,例如Node
2、非資源型的路徑,例如:/healthz
3、包含全部命名空間的資源,例如Pods
例如:定義一個集群角色可讓用戶訪問任意secrets
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:name: secrets-clusterrole
rules:
- apiGroups: [""]resources: ["secrets"]
verbs: ["get","watch","list"]
如果創建的用戶通過rolebinding方式綁定了這個clusterrole,那么該sa只能對其所在名稱空間下的secrets有查看權限
通過clusterrolebinding綁定該clusterrole,該用戶對任何名稱空間下的secrets有訪問權限
4.3 RoleBinding:角色綁定、ClusterRolebinding:集群角色綁定
角色綁定和集群角色綁定用于把一個角色綁定在一個目標上,
可以是User,Group,Service Account,使用RoleBinding為某個命名空間授權,使用ClusterRoleBinding為集群范圍內授權。
例如:將在rbac命名空間中把pod-read角色授予用戶es
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:name: pod-read-bindnamespace: rbac
subjects:
- kind: Username: esapiGroup: rbac.authorization.k8s.io
roleRef: 綁定哪個rolekind: Rolename: pod-readapiGroup: rbac.authorizatioin.k8s.io
Useraccount用戶,一般給kubectl使用
這樣es用戶只能對rbac名稱空間下的 pod有查看權限,通過rolebinding綁定的,只能對特定的名稱空間有權限
RoleBinding也可以引用ClusterRole,對屬于同一命名空間內的ClusterRole定義的資源主體進行授權,
例如:es能獲取到集群中所有的資源信息
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:name: es-allresourcenamespace: rbac
subjects:
- kind: Username: esapiGroup: rbac.authorization.k8s.io
roleRef:apiGroup: rbac.authorization.k8s.iokind: ClusterRolename: cluster-admin
這樣es綁定了cluster-admin,es用戶就有了rbac名稱空間下的所有資源有增刪改查等任何權限
[root@master01 RBAC ]#kubectl explain rolebinding.subjects
KIND: RoleBinding
VERSION: rbac.authorization.k8s.io/v1RESOURCE: subjects <[]Object>DESCRIPTION:Subjects holds references to the objects the role applies to.Subject contains a reference to the object or user identities a rolebinding applies to. This can either hold a direct API object reference, ora value for non-objects such as user and group names.FIELDS:apiGroup <string>APIGroup holds the API group of the referenced subject. Defaults to "" forServiceAccount subjects. Defaults to "rbac.authorization.k8s.io" for Userand Group subjects.kind <string> -required-Kind of object being referenced. Values defined by this API group are"User", "Group", and "ServiceAccount". If the Authorizer does notrecognized the kind value, the Authorizer should report an error.
默認 ClusterRole 默認 ClusterRoleBindingcluster-admin: system:masters 組 允許超級用戶在平臺上的任何資源上執行所有操作。
當在 ClusterRoleBinding 中使用時,可以授權對集群中以及所有名字空間中的全部資源進行完全控制。當在 RoleBinding 中使用時,可以授權控制角色綁定所在名字空間中的所有資源,包括名字空間本身。admin 無 允許管理員訪問權限,旨在使用 RoleBinding 在名字空間內執行授權。
如果在 RoleBinding 中使用,則可授予對名字空間中的大多數資源的讀/寫權限,
包括創建角色和角色綁定的能力。 此角色不允許對資源配額或者名字空間本身進行寫操作。此角色也不允許對 Kubernetes v1.22+ 創建的 Endpoints 進行寫操作。 更多信息參閱 “Endpoints 寫權限”小節。 edit 允許對名字空間的大多數對象進行讀/寫操作。
此角色不允許查看或者修改角色或者角色綁定。 不過,此角色可以訪問 Secret,
以名字空間中任何 ServiceAccount 的身份運行 Pod,所以可以用來了解名字空間內所有服務賬戶的 API 訪問級別。 此角色也不允許對 Kubernetes v1.22+ 創建的 Endpoints 進行寫操作。 更多信息參閱 “Endpoints 寫操作”小節。view 允許對名字空間的大多數對象有只讀權限。 它不允許查看角色或角色綁定。
此角色不允許查看 Secrets,因為讀取 Secret 的內容意味著可以訪問名字空間中 ServiceAccount 的憑據信息,
進而允許利用名字空間中任何 ServiceAccount 的身份訪問 API(這是一種特權提升)。
5、資源的引用方式
多數資源可以用其名稱的字符串表示,也就是Endpoint中的URL相對路徑,
例如pod中的日志是GET /api/v1/namaspaces/{namespace}/pods/{podname}/log
如果需要在一個RBAC對象中體現上下級資源,就需要使用“/”分割資源和下級資源。
例如:若想授權讓某個主體同時能夠讀取Pod和Pod log,則可以配置 resources為一個數組
創建test名稱空間:
[root@master01 RBAC ]#kubectl create ns test
namespace/test created
創建一個在test名稱空間下的角色logs-reader,對pod和pod的日志有訪問權限
[root@master01 RBAC ]#vim role-test.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:name: logs-readernamespace: test
rules:
- apiGroups: [""]resources: ["pods","pods/log"]verbs: ["get","list","watch"]
[root@master01 RBAC ]#kubectl apply -f role-test.yaml
role.rbac.authorization.k8s.io/logs-reader created
[root@master01 RBAC ]#kubectl get role -n test
NAME CREATED AT
logs-reader 2022-09-28T07:41:55Z
[root@master01 ~ ]#kubectl describe role logs-reader -n test
Name: logs-reader
Labels: <none>
Annotations: <none>
PolicyRule:Resources Non-Resource URLs Resource Names Verbs--------- ----------------- -------------- -----pods/log [] [] [get list watch]pods [] [] [get list watch]
創建一個sa賬號:
[root@master01 RBAC ]#kubectl create sa sa-test -n test
serviceaccount/sa-test created
[root@master01 RBAC ]#kubectl get sa -n test
NAME SECRETS AGE
default 1 4m17s 創建名稱空間時,會自動創建一個默認的sa default
sa-test 1 21s
通過rolebinding將sa-test綁定logs-reader這個role
[root@master01 RBAC ]#cat rolebinding-test.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:name: sa-test-rolebindingnamespace: test
subjects:
- kind: ServiceAccountname: sa-testnamespace: test
roleRef:kind: Rolename: logs-readerapiGroup: rbac.authorization.k8s.io
也可以用命令行方式:
kubectl create rolebinding sa-test-rolebinding -n test --role=logs-reader --serviceaccount=test:sa-test
創建個pod
[root@master01 RBAC ]#vim pod-test.yaml
apiVersion: v1
kind: Pod
metadata:name: sa-test-podnamespace: testlabels:app: sa
spec:serviceAccountName: sa-testcontainers:- name: sa-nginxports:- containerPort: 80image: nginximagePullPolicy: IfNotPresent
[root@master01 RBAC ]#kubectl get pods -n test -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
sa-test-pod 1/1 Running 0 9s 172.29.55.29 node01 <none> <none>
進入容器:
[root@master01 RBAC ]#kubectl exec -it sa-test-pod -n test -- /bin/bash
訪問pod日志:
由于kubernetes這個svc是在default名稱空間下,所以訪問的請求需要加default https://kubernetes.default
查看默認名稱空間下的pod
root@sa-test-pod:/var/run/secrets/kubernetes.io/serviceaccount# curl --cacert ./ca.crt -H "Authorization: Bearer $(cat ./token)" https://kubernetes.default/api/v1/namespaces/defaults/pods
{"kind": "Status","apiVersion": "v1","metadata": {},"status": "Failure","message": "pods is forbidden: User \"system:serviceaccount:test:sa-test\" cannot list resource \"pods\" in API group \"\" in the namespace \"defaults\"","reason": "Forbidden","details": {"kind": "pods"},"code": 403
由此可見,訪問默認名稱空間下的pod是沒有權限的
查看test名稱空間下test-pod的日志:
root@sa-test-pod:/var/run/secrets/kubernetes.io/serviceaccount# curl --cacert ./ca.crt -H "Authorization: Bearer $(cat ./token)" https://kubernetes.default/api/v1/namespaces/test/pods/sa-test-pod/log
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2022/09/29 00:51:20 [notice] 1#1: using the "epoll" event method
2022/09/29 00:51:20 [notice] 1#1: nginx/1.23.1
2022/09/29 00:51:20 [notice] 1#1: built by gcc 10.2.1 20210110 (Debian 10.2.1-6)
2022/09/29 00:51:20 [notice] 1#1: OS: Linux 4.19.12-1.el7.elrepo.x86_64
2022/09/29 00:51:20 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2022/09/29 00:51:20 [notice] 1#1: start worker processes
2022/09/29 00:51:20 [notice] 1#1: start worker process 31
2022/09/29 00:51:20 [notice] 1#1: start worker process 32
2022/09/29 00:51:20 [notice] 1#1: start worker process 33
由于對sa-test在test名稱空間下做了授權,所有有權限查看test名稱空間下的資源
資源還可以通過名稱(ResourceName)進行引用,在指定ResourceName后,
使用get、delete、update、patch請求,就會被限制在這個資源實例范圍內
例如,下面的聲明讓一個主體只能對名為my-configmap的Configmap進行get和update操作:
apiVersion: rabc.authorization.k8s.io/v1
kind: Role
metadata:namaspace: defaultname: configmap-update
rules:
- apiGroups: [""]resources: ["configmaps"]resourceNames: ["my-configmap"]verbs: ["get","update"]
6、常見角色(role)授權的案例
常見的角色和用戶綁定模式:
(1)允許讀取核心API組的Pod資源
rules:
- apiGroups: [""]resources: ["pods"]verbs: ["get","list","watch"]
(2)允許讀寫apps API組中的deployment資源
rules:
- apiGroups: ["apps"] 想對任意組資源有權限,就填空resources: ["deployments"]verbs: ["get","list","watch","create","update","patch","delete"]
(3)允許讀取Pod以及讀寫job信息
rules:
- apiGroups: [""]resources: ["pods"]verbs: ["get","list","watch"]
- apiGroups: [""]resources: ["jobs"]verbs: ["get","list","watch","create","update","patch","delete"]
(4)允許讀取一個名為my-config的ConfigMap(必須綁定到一個RoleBinding來限制到一個Namespace下的ConfigMap):
rules:
- apiGroups: [""]resources: ["configmaps"]resourceNames: ["my-configmap"]verbs: ["get"]
(5)讀取核心組的Node資源(Node屬于集群級的資源,所以必須存在于ClusterRole中,并使用ClusterRoleBinding進行綁定):
rules:
- apiGroups: [""]resources: ["nodes"]verbs: ["get","list","watch"]
(6)允許對非資源端點“/healthz”及其所有子路徑進行GET和POST操作(必須使用ClusterRole和ClusterRoleBinding):
rules:
- nonResourceURLs: ["/healthz","/healthz/*"]verbs: ["get","post"]
7、常見的角色綁定示例
(1)用戶名alice
subjects:
- kind: Username: aliceapiGroup: rbac.authorization.k8s.io
(2)組名alice
subjects:
- kind: Groupname: aliceapiGroup: rbac.authorization.k8s.io
(3)kube-system命名空間中默認Service Account
subjects:
- kind: ServiceAccountname: defaultnamespace: kube-system
8、對Service Account的授權管理
Service Account也是一種賬號,是給運行在Pod里的進程提供了必要的身份證明。
需要在Pod定義中指明引用的Service Account,這樣就可以對Pod的進行賦權操作。
例如:pod內可獲取rbac命名空間的所有Pod資源,pod-reader-sc的Service Account是綁定了名為pod-read的Role
創建名稱空間rbac
[root@master01 RBAC ]#vim rbac-namespace.yaml
apiVersion: v1
kind: Namespace
metadata:name: rbac
[root@master01 RBAC ]#kubectl apply -f rbac-namespace.yaml
namespace/rbac created
也可以命令行創建:
創建sa:
[root@master01 RBAC ]#vim sa.yaml
apiVersion: v1
kind: ServiceAccount
metadata:name: pod-reader-scnamespace: rbac
創建pod:
[root@master01 RBAC ]#vim pod-rbac.yaml
apiVersion: v1
kind: Pod
metadata:name: nginxnamespace: rbac
spec:serviceAccountName: pod-reader-sccontainers:- name: nginximage: nginximagePullPolicy: IfNotPresentports:- containerPort: 80
[root@master01 RBAC ]#kubectl get pods -n rbac -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 19s 172.29.55.32 node01 <none> <none>
進入容器:
[root@master01 RBAC ]#kubectl exec -it nginx -n rbac -- /bin/bashcd /var/run/secrets/kubernetes.io/serviceaccountcurl --cacert ./ca.crt -H "Authorization: Bearer $(cat ./token)" https://kubernetes.default/api/v1/namespaces/rbac/pods
root@nginx:/var/run/secrets/kubernetes.io/serviceaccount# curl --cacert ./ca.crt -H "Authorization: Bearer $(cat ./token)" https://kubernetes.default/api/v1/namespaces/rbac/pods
{"kind": "Status","apiVersion": "v1","metadata": {},"status": "Failure","message": "pods is forbidden: User \"system:serviceaccount:rbac:pod-reader-sc\" cannot list resource \"pods\" in API group \"\" in the namespace \"rbac\"","reason": "Forbidden","details": {"kind": "pods"},"code": 403
發現沒有權限,給sa授予查看權限:
[root@master01 RBAC ]#kubectl create rolebinding rbac-rolebinding --clusterrole=view --serviceaccount=rbac:pod-reader-sc -n rbac
rolebinding.rbac.authorization.k8s.io/rbac-rolebinding created
創建rolebinding時,必須指定命名空間。否在是創建在默認命名空間下,這樣對指定的命名空間就沒有權限
再次訪問
root@nginx:/var/run/secrets/kubernetes.io/serviceaccount# curl --cacert ./ca.crt -H "Authorization: Bearer $(cat ./token)" https://kubernetes.default/api/v1/namespaces/rbac/pods
{"kind": "PodList","apiVersion": "v1","metadata": {"selfLink": "/api/v1/namespaces/rbac/pods","resourceVersion": "1395069"},"items": [{"metadata": {"name": "nginx","namespace": "rbac","selfLink": "/api/v1/namespaces/rbac/pods/nginx","uid": "ea47146a-0b17-47fc-a018-7f4d6b77e7c4",
有權限了
(1)my-namespace中的my-sa Service Account授予只讀權限
kubectl create rolebinding my-sa-view --clusterrole=view --serviceaccount=my-namespace:my-sa --namespace=my-namespace
(2)為一個命名空間中名為default的Service Account授權
如果一個應用沒有指定 serviceAccountName,則會使用名為default的Service Account。
注意,賦予Service Account “default”的權限會讓所有沒有指定serviceAccountName的Pod都具有這些權限
例如,在my-namespace命名空間中為Service Account“default”授予只讀權限:
kubectl create rolebinding default-view --clusterrole=view --serviceaccount=my-namespace:default --namespace=my-namespace
(3)為命名空間中所有Service Account都授予一個角色
如果希望在一個命名空間中,任何Service Account應用都具有一個角色,則可以為這一命名空間的Service Account群組進行授權
kubectl create rolebinding serviceaccounts-view --clusterrole=view --group=system:serviceaccounts:my-namespace --namespace=my-namespace
這樣,就算在那個名稱空間下創建的sa沒有做授權,那該sa還是有對該名稱空間下資源查看的權限
(4)為集群范圍內所有Service Account都授予一個低權限角色
如果不想為每個命名空間管理授權,則可以把一個集群級別的角色賦給所有Service Account。
kubectl create clusterrolebinding serviceaccounts-view --clusterrole=view --group=system:serviceaccounts
(5)為所有Service Account授予超級用戶權限
kubectl create clusterrolebinding serviceaccounts-view --clusterrole=cluster-admin --group=system:serviceaccounts
這樣,在任何名稱空間下創建的sa都具有超級管理員權限
服務賬戶(ServiceAccount) 的用戶名前綴為 system:serviceaccount:,屬于前綴為 system:serviceaccounts: 的用戶組。
說明:
system:serviceaccount: (單數)是用于服務賬戶用戶名的前綴;
system:serviceaccounts: (復數)是用于服務賬戶組名的前綴。
9、使用kubectl命令行工具創建資源對象
(1)在命名空間rbac中為用戶es授權admin ClusterRole:
kubectl create rolebinding bob-admin-binding --clusterrole=admin --user=es --namespace=rbac
admin不能對資源配額和名稱空間本身進行修改,此角色不允許對資源配額或者名字空間本身進行寫操作
(2)在命名空間rbac中為名為myapp的Service Account授予view ClusterRole:
kubctl create rolebinding myapp-role-binding --clusterrole=view --serviceaccount=rbac:myapp --namespace=rbac
myapp僅能查看rbac名稱空間下的資源
(3)在全集群范圍內為用戶root授予cluster-admin ClusterRole:
kubectl create clusterrolebinding cluster-binding --clusterrole=cluster-admin --user=root
root用戶對K8S資源進行任何操作
(4)在全集群范圍內為名為myapp的Service Account授予view ClusterRole:
kubectl create clusterrolebinding service-account-binding --clusterrole=view --serviceaccount=myapp
yaml文件進行rbac授權:https://kubernetes.io/zh/docs/reference/access-authn-authz/rbac/
當命令記不住可以 --help查看幫助:
Usage:
kubectl create rolebinding NAME --clusterrole=NAME|–role=NAME [–user=username] [–group=groupname]
[–serviceaccount=namespace:serviceaccountname] [–dry-run=server|client|none] [options]
kubectl create clusterrolebinding NAME --clusterrole=NAME [–user=username] [–group=groupname]
[–serviceaccount=namespace:serviceaccountname] [–dry-run=server|client|none] [options]
10、限制不同的用戶操作k8s集群
限制不同的用戶只能訪問哪些名稱空間,哪些資源,不能全部訪問所有
操作K8S集群需要用戶,用戶要被K8S信任,
ssl認證
生成一個證書
(1)生成一個私鑰
cd /etc/kubernetes/pki/
umask 077; openssl genrsa -out lucky.key 2048
(2)生成一個證書請求
openssl req -new -key lucky.key -out lucky.csr -subj "/CN=lucky"
(3)生成一個證書,基于ca證書生成的
openssl x509 -req -in lucky.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out lucky.crt -days 3650
在kubeconfig下新增加一個lucky這個用戶
(1)把lucky這個用戶添加到kubernetes集群中,可以用來認證apiserver的連接 集群有CA認證,并且將證書的輸入嵌入到配置文件中
[root@xianchaomaster1 pki]# kubectl config --kubeconfig=config-demo set-credentials lucky --client-certificate=./lucky.crt --client-key=./lucky.key --embed-certs=true
指定–kubeconfig參數后,所有的配置都會寫到對應的文件中,1.23.6版本默認保存在當前目錄
注意:
[root@master01 pki ]#echo $KUBECONFIG
/etc/kubernetes/admin.conf
不去掉的話修改的是/etc/kubernetes/admin.conf
去掉這個環境變量,之后不用添加 --kubeconfig=config-demo 也能修改默認的/root/.kube/config文件
[root@master01 pki ]#cat config-demo
apiVersion: v1
clusters: null
contexts: null
current-context: ""
kind: Config
preferences: {}
users:
- name: luckyuser:client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNvVENDQVlrQ0NRQ1ZrOWJRek9FeXpEQU5CZ2txaGtpRzl3MEJBUXNGQURBVk1STXdFUVlEVlFRREV3cHIKZFdKbGNtNWxkR1Z6TUI0WERUSXlNRGt5T1RBMU16TXhNRm9YRFRNeU1Ea3lOakExTXpNeE1Gb3dFREVPTUF3RwpBMVVFQXd3RmJIVmphM2t3Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRQ3A0d3QxCnFKMTVwTXBuR0JtdjNBdFhxOE5DVERvaldES01CaTEyaW5jNDhLYTdGa3J1RG9CSzNSNUNPRHZlRERaNStWWkkKWlY4S2xNdnRCRVhHQkN5clZvNC9PRjMwMmttRkZqWXhkNnNQYXBFdFNnZEdQdm9ONVBhMUl5d0x6VU9SUkZFNwpSNU5VZVA0NENGRnFPQ3dOU1B0MFJ3emtYSzdPbE03UlBrbHQ4RU1WNFAwOUozMVFmeWlpN0lMQ2J1TlNxeGJsCjA3QVpQWDFFY3Z3V1RvYmVyN0FHYnE0UjhZMFRTWmdFdGNIZ1NPcUtCcytmZFl2TFE0S2dmM2JsbmNxTjlNSVkKeFozV1kySTJBWWw0dlZpWXlsS3FEdXdXaGo1cjZMaUx4K29Rd0U3Z3oyUkswNFlQa2I2U1pNSG1JK1Y4SjVVYgpPRFk5NFpCb3d6ZmVOUmxsQWdNQkFBRXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBRmVPbkRxeWlISnVNZWdwCnNodnNzRkpyV25VbndUUlVRaG5va1QzYUd4LytiaUcwYXNTSGV2MkErUFBsb1k2SnA5VVUwMm84TWtnbHY4djkKNTRCWXowbDVjMGxORnZ5RjVFRWlRdlh3dnN4bWpFeFpyTHFSSVVJclFzUi9MaktxUnQ4S0lYZVU2bm9abGFUZAp2RTFrVXRhbXZLZnlsWlNkcDZicUxWalJsYlg2eC92ZWNid2ViVmxJL1Z0OXJ2ZmxpOEpFY2dMU2NJa3Uxalc5Cms0REhqZm5BaC9NN1p6aitoSFZvUU5iQXlSZlA2ckpocEVjZ29ETEF4QmlEdWpPSzg1cnFaYXRRckljUEtSeDMKdnhURUJJTy9LZ3djeG51STlnY0RnWUhWb2VCVUJ0WEZ2dG9wNlFaRk5PK2poTTJVaXppeVBhVWlkYndIQ1B5SgpuaStIYWlFPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcEFJQkFBS0NBUUVBcWVNTGRhaWRlYVRLWnhnWnI5d0xWNnZEUWt3NkkxZ3lqQVl0ZG9wM09QQ211eFpLCjdnNkFTdDBlUWpnNzNndzJlZmxXU0dWZkNwVEw3UVJGeGdRc3ExYU9QemhkOU5wSmhSWTJNWGVyRDJxUkxVb0gKUmo3NkRlVDJ0U01zQzgxRGtVUlJPMGVUVkhqK09BaFJhamdzRFVqN2RFY001Rnl1enBUTzBUNUpiZkJERmVEOQpQU2Q5VUg4b291eUN3bTdqVXFzVzVkT3dHVDE5UkhMOEZrNkczcSt3Qm02dUVmR05FMG1ZQkxYQjRFanFpZ2JQCm4zV0x5ME9Db0g5MjVaM0tqZlRDR01XZDFtTmlOZ0dKZUwxWW1NcFNxZzdzRm9ZK2EraTRpOGZxRU1CTzRNOWsKU3RPR0Q1RytrbVRCNWlQbGZDZVZHemcyUGVHUWFNTTMzalVaWlFJREFRQUJBb0lCQUJ2Uk5IQW9rdGgzTmprWgpSaU40aVZicXBnYzJDaEw5ZnhGVWRaOUNYdkV3M213bDQxRUZpTlk1VEpvVk1TQlRxWnZoU3RLQjNzVVJ4aTVpCkU3YXZ1a3kzMklUYml1N3J5endDZmc4dGhCSDdKaGhmVmIrWDBrUHlLTDlTS2dVb3NCYWFOQjdid25FRGVzVGIKLzlDL3I5N2hBMk52dXRtdG4yWHVFY3RMUXFUQWZSUHl3a0FGTmhmV2c5L3lJWTd0STRYQWhkdlNOSkVHWFhQNwphaGRSM3JwaEdqdU5NcExkRlZYb24zSnA1TTZNM0hWTkdKK00wR05OOVdxM1BOMVp4R2JCR2MvU3YxMVBwd3BjCm1iNVBXSUxWS3QzWkI0bU9QcFJCbFN1V3ZhdU5QWlJORWQ3cVh0cUlRUGhmWU9ocGQ2bklYbXY5TlZwdDlyTS8KZjkxMUppVUNnWUVBMytPREg1T0Y0bE5PZ1VzQkE3QVVDNU8zY0F2ZTNZbFl4TGI3eHgxMmthNDZVZko5aTJRYQpUZjRZUkNSTEZoeEpOc3V3bFQwRlFmZXBlbnpRNVFGTFU1ZGFxU2RpMUhOSWI1VGZQNWpEbFhMbTNLRnVkb1RPCklsYmtkS1gxZ1J2S0pzdFgrbUZObTE1dGVaRkxZRkp6anZsRWltdzNmdFJubElIV1ZBc1l6K01DZ1lFQXdrREIKZS9vaWVUVWtXY3pRa3h3R0dGblRHUEp1WWxCRlU2Z2owL3E2cVV3S1NXRUkzb3RtbDlQbVJJOWtwMm5JYldOUQpBT0E0dElJZjhWMVRsN2o3L2dBVnJyYWpoeGJ1cVpUbmdTenU3NVp6Q012UjdYcmV4dm15a2xzK2JKK3RsVWpECjlzSlNYb1FHOWxYeWNQZ1hHN2xOU3NDcVJ3N3ZXbDRDcE42UHBCY0NnWUVBMVhQQmhZOU9hOUxrMjl1NFlkMnoKbnIzOGU3UzFqQnp3SnN3V0MyWUpyeWFlcjVZekgzd1dvQmtLNVp4OGdkNEI1MTRYUXBGa3U5bjFHTFI3TEhvcAphTTY2UHQ4d0dFQzQ1TGpZaDNlTHNLWlZlQy9vY3RKMi9NSS9HUDlJcXdqbG1FcngyK0o4N1EzLzdaRWFmZ0RkCjc0ZXpVdzJOY3p2cWJPbkVmMmY5QmVVQ2dZQm0wK2lZUER6cmRKb2RmeklaN1llOGREQXUwSVptUEorMlBSZGEKS3l1TVd0aEhKN3FPTTdUSFFrQnVvb2xocGJtWFRpOFhoNW44MDdVZEM0NG9qcCsyUVUwNUF5MWxZVnBOSXFtNQowNU5YK0loRWE4Qmd1ZDRiN2luOUY1ZmY0RmIrNDFuNDBielFrNHNyOHlzM2FkeXhyRkdoOUlNdXdsVXB2UUloClREODFXUUtCZ1FEV0d6dlBKU3IvWW5hMWE1cnU5TnZGWm42TDdFdHBiSU1wUUw1Y1c1YmtYQVpib0Exc1BQUjgKd1FDYW52OUdOSjEvT2JJajJpb0xrZHNGM2pKRlhSdnpGNWpjVGswb3UrdE1VWkNJR2F4TGxtbDdYZzdLank3RAphT0N1V1E2SWN2WlFSeW11N0ZKbXF1ektZYnVJZVVoL3Y0REFLSXc2MmFhTEFrWVVLOVRCNEE9PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=
(2)在kubeconfig下新增加一個lucky這個賬號
kubectl config set-context lucky@kubernetes --cluster=kubernetes --user=lucky
(3)切換賬號到lucky,默認沒有任何權限
kubectl config use-context lucky@kubernetes
kubectl config use-context kubernetes-admin@kubernetes 這個是集群用戶,有任何權限
把user這個用戶通過rolebinding綁定到clusterrole上,授予權限,權限只是在lucky這個名稱空間有效
(1)把lucky這個用戶通過rolebinding綁定到clusterrole上
kubectl create ns lucky-test
kubectl create rolebinding lucky -n lucky-test --clusterrole=cluster-admin --user=lucky
該角色只對lucky-test名稱空間下的資源有管理員權限,對其他名稱空間下沒有權限
[root@master01 .kube ]#kubectl get pods -n lucky-test
No resources found in lucky-test namespace.
[root@master01 .kube ]#kubectl get pods
Error from server (Forbidden): pods is forbidden: User "lucky" cannot list resource "pods" in API group "" in the namespace "default"
設置集群,不然配置文件里面沒有集群:
[root@master01 pki ]#kubectl config set-cluster development --server=https://10.10.0.10
這里直接采用原來的集群就可以
(2)切換到lucky這個用戶
kubectl config use-context lucky@kubernetes
(3)測試是否有權限
kubectl get pods -n lucky-test
有權限操作這個名稱空間
[root@master01 .kube ]#kubectl config view
apiVersion: v1
clusters:
- cluster:certificate-authority-data: DATA+OMITTEDserver: https://10.10.0.10:6443name: kubernetes
contexts:
- context:cluster: kubernetesuser: kubernetes-adminname: kubernetes-admin@kubernetes
- context:cluster: kubernetesuser: luckyname: lucky@kubernetes
current-context: lucky@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-adminuser:client-certificate-data: REDACTEDclient-key-data: REDACTED
- name: luckyuser:client-certificate-data: REDACTEDclient-key-data: REDACTED
在lucky-test名稱空間下有權限:
[root@master01 .kube ]#kubectl create sa jingtian -n lucky-test
serviceaccount/jingtian created
假如公司來了個K8S技術人員,只需要創建用戶
/root/.kube/config
文件copy到root/下
將kubernetes-admin相關內容刪掉,將剛才生成的config-daemon相關文件復制過來
[root@master01 ~ ]#cat config
apiVersion: v1
clusters:
- cluster:certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUMvakNDQWVhZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJeU1Ea3hOREF5TURjek5Wb1hEVE15TURreE1UQXlNRGN6TlZvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTVB0CmJNNHg3STgvK01FQ29nY3lTNFRxK0ZzVHVtZi9JeFNXMXY4Q3NHVHVodEgrVElia21oYmlvenI4U0JtSGR2L1YKYTRjSjdzNGhxcE1LTnRiNk1IK1VZN0JqT25OT0J6TWYwbTg2cS9rRVFGRmZEdlRIU0kzYzBXK3BaRHZ5Y1EregphdXRGOHRjTWFtWk9KQU95U2xBN3NOelFCYlgrQW9lVFE0a29aVURGQm1oZjNIamdkanVtV3NERnZwVHMvd0wxCmlaV2p5dFd3c3J4RDIxK1lwa0ZkVUhRYnlxR2VuT0JscUYxbWhoTjkyY2VDcW80TDJSQlRYQXlKNVMxdG5EZ2gKR1B6WFNzN2cwNmhaaTlycEhPZ0RjdjByenBvdEdLc21LQm9DZ2RmcXovYlJ0UDk3UlA5ampXUHdDdUllR3Vwcwp6WGI4a1RINThleFp1cXNiS2dzQ0F3RUFBYU5aTUZjd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0hRWURWUjBPQkJZRUZMUFRZRWppaWUrU3RYbENVK1REaWVRT3BjdWZNQlVHQTFVZEVRUU8KTUF5Q0NtdDFZbVZ5Ym1WMFpYTXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBSDF6OHZjazBDaVZPT1J5QXZRYQpXV0s3WSt0WWZNSXhzcVBkU3A5My9yeXl2MkE0dWhTQjRiMDRGTmlLNWp4b2cvaDhoWmxIbFJoNDZzaUdMWlRjCmgwUHhmSlZ5L3UvdzNXZ2N0bXJMVTJ1VHVkcERkNm10YlhJRGhNempGWlh1VjFQa01oQk5ZVDUxS1hqY0dmTkMKY1JxMm5Vc1dCM0U5SjZJakNhWi80ME9wcjZBYUNoNWlWRUpmUzR6M3hHcm1uQ0lBeG5UaHBVUHEybjJ1NjZXOApQc2FvS0ZmTmZkUlEvSk5CUHVDUUs2RzRZM0syVEFYRkFMQzFXNEVmRmhKWUQ5RkxzQVk0TjUwQ1p2OVFNOXFuCmhrcW5SSGJqSGI4ZWdITThSRFU0UWNybm9IZzMycnB2MUtWcnZtVExQVVZ5dm85eUZpSm53ZzBJVVF3Rlc1R1UKelQwPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==server: https://10.10.0.10:6443name: kubernetescontexts:
- context:cluster: kubernetesuser: luckyname: lucky@kubernetes
current-context: lucky@kubernetes
kind: Config
preferences: {}
users:
- name: luckyuser:client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNvVENDQVlrQ0NRQ1ZrOWJRek9FeXpEQU5CZ2txaGtpRzl3MEJBUXNGQURBVk1STXdFUVlEVlFRREV3cHIKZFdKbGNtNWxkR1Z6TUI0WERUSXlNRGt5T1RBMU16TXhNRm9YRFRNeU1Ea3lOakExTXpNeE1Gb3dFREVPTUF3RwpBMVVFQXd3RmJIVmphM2t3Z2dFaU1BMEdDU3FHU0liM0RRRUJBUVVBQTRJQkR3QXdnZ0VLQW9JQkFRQ3A0d3QxCnFKMTVwTXBuR0JtdjNBdFhxOE5DVERvaldES01CaTEyaW5jNDhLYTdGa3J1RG9CSzNSNUNPRHZlRERaNStWWkkKWlY4S2xNdnRCRVhHQkN5clZvNC9PRjMwMmttRkZqWXhkNnNQYXBFdFNnZEdQdm9ONVBhMUl5d0x6VU9SUkZFNwpSNU5VZVA0NENGRnFPQ3dOU1B0MFJ3emtYSzdPbE03UlBrbHQ4RU1WNFAwOUozMVFmeWlpN0lMQ2J1TlNxeGJsCjA3QVpQWDFFY3Z3V1RvYmVyN0FHYnE0UjhZMFRTWmdFdGNIZ1NPcUtCcytmZFl2TFE0S2dmM2JsbmNxTjlNSVkKeFozV1kySTJBWWw0dlZpWXlsS3FEdXdXaGo1cjZMaUx4K29Rd0U3Z3oyUkswNFlQa2I2U1pNSG1JK1Y4SjVVYgpPRFk5NFpCb3d6ZmVOUmxsQWdNQkFBRXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBRmVPbkRxeWlISnVNZWdwCnNodnNzRkpyV25VbndUUlVRaG5va1QzYUd4LytiaUcwYXNTSGV2MkErUFBsb1k2SnA5VVUwMm84TWtnbHY4djkKNTRCWXowbDVjMGxORnZ5RjVFRWlRdlh3dnN4bWpFeFpyTHFSSVVJclFzUi9MaktxUnQ4S0lYZVU2bm9abGFUZAp2RTFrVXRhbXZLZnlsWlNkcDZicUxWalJsYlg2eC92ZWNid2ViVmxJL1Z0OXJ2ZmxpOEpFY2dMU2NJa3Uxalc5Cms0REhqZm5BaC9NN1p6aitoSFZvUU5iQXlSZlA2ckpocEVjZ29ETEF4QmlEdWpPSzg1cnFaYXRRckljUEtSeDMKdnhURUJJTy9LZ3djeG51STlnY0RnWUhWb2VCVUJ0WEZ2dG9wNlFaRk5PK2poTTJVaXppeVBhVWlkYndIQ1B5SgpuaStIYWlFPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcEFJQkFBS0NBUUVBcWVNTGRhaWRlYVRLWnhnWnI5d0xWNnZEUWt3NkkxZ3lqQVl0ZG9wM09QQ211eFpLCjdnNkFTdDBlUWpnNzNndzJlZmxXU0dWZkNwVEw3UVJGeGdRc3ExYU9QemhkOU5wSmhSWTJNWGVyRDJxUkxVb0gKUmo3NkRlVDJ0U01zQzgxRGtVUlJPMGVUVkhqK09BaFJhamdzRFVqN2RFY001Rnl1enBUTzBUNUpiZkJERmVEOQpQU2Q5VUg4b291eUN3bTdqVXFzVzVkT3dHVDE5UkhMOEZrNkczcSt3Qm02dUVmR05FMG1ZQkxYQjRFanFpZ2JQCm4zV0x5ME9Db0g5MjVaM0tqZlRDR01XZDFtTmlOZ0dKZUwxWW1NcFNxZzdzRm9ZK2EraTRpOGZxRU1CTzRNOWsKU3RPR0Q1RytrbVRCNWlQbGZDZVZHemcyUGVHUWFNTTMzalVaWlFJREFRQUJBb0lCQUJ2Uk5IQW9rdGgzTmprWgpSaU40aVZicXBnYzJDaEw5ZnhGVWRaOUNYdkV3M213bDQxRUZpTlk1VEpvVk1TQlRxWnZoU3RLQjNzVVJ4aTVpCkU3YXZ1a3kzMklUYml1N3J5endDZmc4dGhCSDdKaGhmVmIrWDBrUHlLTDlTS2dVb3NCYWFOQjdid25FRGVzVGIKLzlDL3I5N2hBMk52dXRtdG4yWHVFY3RMUXFUQWZSUHl3a0FGTmhmV2c5L3lJWTd0STRYQWhkdlNOSkVHWFhQNwphaGRSM3JwaEdqdU5NcExkRlZYb24zSnA1TTZNM0hWTkdKK00wR05OOVdxM1BOMVp4R2JCR2MvU3YxMVBwd3BjCm1iNVBXSUxWS3QzWkI0bU9QcFJCbFN1V3ZhdU5QWlJORWQ3cVh0cUlRUGhmWU9ocGQ2bklYbXY5TlZwdDlyTS8KZjkxMUppVUNnWUVBMytPREg1T0Y0bE5PZ1VzQkE3QVVDNU8zY0F2ZTNZbFl4TGI3eHgxMmthNDZVZko5aTJRYQpUZjRZUkNSTEZoeEpOc3V3bFQwRlFmZXBlbnpRNVFGTFU1ZGFxU2RpMUhOSWI1VGZQNWpEbFhMbTNLRnVkb1RPCklsYmtkS1gxZ1J2S0pzdFgrbUZObTE1dGVaRkxZRkp6anZsRWltdzNmdFJubElIV1ZBc1l6K01DZ1lFQXdrREIKZS9vaWVUVWtXY3pRa3h3R0dGblRHUEp1WWxCRlU2Z2owL3E2cVV3S1NXRUkzb3RtbDlQbVJJOWtwMm5JYldOUQpBT0E0dElJZjhWMVRsN2o3L2dBVnJyYWpoeGJ1cVpUbmdTenU3NVp6Q012UjdYcmV4dm15a2xzK2JKK3RsVWpECjlzSlNYb1FHOWxYeWNQZ1hHN2xOU3NDcVJ3N3ZXbDRDcE42UHBCY0NnWUVBMVhQQmhZOU9hOUxrMjl1NFlkMnoKbnIzOGU3UzFqQnp3SnN3V0MyWUpyeWFlcjVZekgzd1dvQmtLNVp4OGdkNEI1MTRYUXBGa3U5bjFHTFI3TEhvcAphTTY2UHQ4d0dFQzQ1TGpZaDNlTHNLWlZlQy9vY3RKMi9NSS9HUDlJcXdqbG1FcngyK0o4N1EzLzdaRWFmZ0RkCjc0ZXpVdzJOY3p2cWJPbkVmMmY5QmVVQ2dZQm0wK2lZUER6cmRKb2RmeklaN1llOGREQXUwSVptUEorMlBSZGEKS3l1TVd0aEhKN3FPTTdUSFFrQnVvb2xocGJtWFRpOFhoNW44MDdVZEM0NG9qcCsyUVUwNUF5MWxZVnBOSXFtNQowNU5YK0loRWE4Qmd1ZDRiN2luOUY1ZmY0RmIrNDFuNDBielFrNHNyOHlzM2FkeXhyRkdoOUlNdXdsVXB2UUloClREODFXUUtCZ1FEV0d6dlBKU3IvWW5hMWE1cnU5TnZGWm42TDdFdHBiSU1wUUw1Y1c1YmtYQVpib0Exc1BQUjgKd1FDYW52OUdOSjEvT2JJajJpb0xrZHNGM2pKRlhSdnpGNWpjVGswb3UrdE1VWkNJR2F4TGxtbDdYZzdLank3RAphT0N1V1E2SWN2WlFSeW11N0ZKbXF1ektZYnVJZVVoL3Y0REFLSXc2MmFhTEFrWVVLOVRCNEE9PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=
添加一個test的普通用戶
useradd test
cp -ar /root/config /home/test/.kube/
修改/tmp/.kube/config文件,把kubernetes-admin相關的刪除,只留lucky用戶
chown -R test.test /home/test/
su - test
kubectl get pods -n lucky
[test@master01 .kube ]$kubectl get pods
Error from server (Forbidden): pods is forbidden: User "lucky" cannot list resource "pods" in API group "" in the namespace "default"
[test@master01 .kube ]$kubectl get pods -n lucky-test
No resources found in lucky-test namespace.
可以了
[test@master01 ~ ]$kubectl create sa nihao -n lucky-test
serviceaccount/nihao created
[test@master01 ~ ]$
[test@master01 ~ ]$
[test@master01 ~ ]$kubectl get sa -n lucky-test
NAME SECRETS AGE
default 1 102m
jinghao 1 74m
nihao 1 16s
如果報這個錯,可以把之前配置的環境變量去掉
[test@master01 ~ ]$kubectl create sa nihao -n lucky-test
error: error loading config file "/etc/kubernetes/admin.conf": open /etc/kubernetes/admin.conf: permission denied
[test@master01 ~ ]$unset KUBECONFIG
[test@master01 ~ ]$kubectl create sa nihao -n lucky-test
serviceaccount/nihao created
退出test用戶,需要在把集群環境切換成管理員權限
kubectl config use-context kubernetes-admin@kubernetes
創建具有集群所有pod的查看權限:
如上創建用戶lucky66-read
其他類似
創建clusterrole:
[root@master01 RBAC ]#vim read-clusterrole.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:name: lucky66
rules:
- apiGroups: [""]resources: ["pods"]verbs: ["get","list","watch"]
對所有pod有查看權限
[root@master01 RBAC ]#kubectl get clusterrole
NAME CREATED AT
lucky66 2022-09-29T08:06:05Z
然后將用戶與該角色綁定:
[root@master01 RBAC ]#kubectl create clusterrolebinding lucky66-rolebinding --clusterrole=lucky66 --user=lucky66-read
clusterrolebinding.rbac.authorization.k8s.io/lucky66-rolebinding created
其他類似。
11、準入控制
11.1 ResourceQuota準入控制器
ResourceQuota準入控制器是k8s上內置的準入控制器,默認該控制器是啟用的狀態,
它主要作用是用來限制一個名稱空間下的資源的使用,它能防止在一個名稱空間下的pod被過多創建時,
導致過多占用k8s資源,簡單講它是用來在名稱空間級別限制用戶的資源使用。
當多個用戶或團隊共享具有固定節點數目的集群時,人們會擔心有人使用超過其基于公平原則所分配到的資源量。
資源配額是幫助管理員解決這一問題的工具。
資源配額,通過 ResourceQuota 對象來定義,對每個命名空間的資源消耗總量提供限制。
它可以限制命名空間中某種類型的對象的總數目上限,也可以限制命名空間中的 Pod 可以使用的計算資源的總上限。
資源配額的工作方式如下:
不同的團隊可以在不同的命名空間下工作。這可以通過 RBAC 強制執行。
集群管理員可以為每個命名空間創建一個或多個 ResourceQuota 對象。
當用戶在命名空間下創建資源(如 Pod、Service 等)時,Kubernetes 的配額系統會跟蹤集群的資源使用情況,
以確保使用的資源用量不超過 ResourceQuota 中定義的硬性資源限額。
如果資源創建或者更新請求違反了配額約束,那么該請求會報錯(HTTP 403 FORBIDDEN),
并在消息中給出有可能違反的約束。
如果命名空間下的計算資源 (如 cpu 和 memory)的配額被啟用,
則用戶必須為這些資源設定請求值(request)和約束值(limit),
否則配額系統將拒絕 Pod 的創建。
提示: 可使用 LimitRanger 準入控制器來為沒有設置計算資源需求的 Pod 設置默認值
1.限制cpu、內存、pod、deployment數量
創建resourcequota資源
[root@xianchaomaster1 ~]# kubectl create ns quota
[root@xianchaomaster1 ~]# cat resourcequota-1.yaml
apiVersion: v1
kind: ResourceQuota
metadata:name: quota-testnamespace: quota
spec:hard:pods: "6"requests.cpu: "2"requests.memory: 2Gilimits.cpu: "4"limits.memory: 10Gicount/deployments.apps: "6"persistentvolumeclaims: "6"
[root@xianchaomaster1 ~]# kubectl apply -f resourcequota-1.yaml
創建pod進行測試
資源清單YAML文件解讀:
spec.hard字段是用來定義對應名稱空間下的資源限制規則;
pods用來限制在對應名稱空間下的pod數量,
requests.cpu字段 所有非終止狀態的 Pod,其 CPU 需求總量不能超過該值;
requests.memory所有非終止狀態的 Pod,其內存需求總量不能超過該值;
limits.cpu用來限制對應名稱空間下的podcpu資源的上限總和,
limits.memory用來限制對應名稱空間下pod內存資源上限總和;
count/deployments.apps用來限制對應名稱空間下apps群組下的deployments的個數;
以上配置清單表示,在quota名稱空間下運行的pod數量不能超過6個,
所有pod的cpu資源下限總和不能大于2個核心,
內存資源下限總和不能大于2G,
cpu上限資源總和不能大于4個核心,
內存上限總和不能超過10G,
apps群組下的deployments控制器不能超過6個,
pvc個數不能超過6個;
以上條件中任意一個條目不滿足,都將無法在對應名稱空間創建對應的資源。
[root@xianchaomaster1]# cat quota-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: quotanamespace: quota
spec:replicas: 7selector:matchLabels:app: quotatemplate:metadata:labels:app: quotaspec:containers:- name: myappimage: janakiramm/myapp:v1imagePullPolicy: IfNotPresentports:- containerPort: 80resources:requests:cpu: 10mmemory: 10Milimits:cpu: 10mmemory: 10Mi
[root@master01 RBAC ]#kubectl get pods -n quota
NAME READY STATUS RESTARTS AGE
quota-549dbc5564-2d929 1/1 Running 0 76s
quota-549dbc5564-2q9sg 1/1 Running 1 (35s ago) 73s
quota-549dbc5564-bswfx 1/1 Running 0 76s
quota-549dbc5564-clk7f 1/1 Running 0 73s
quota-549dbc5564-hbhx2 1/1 Running 0 76s
quota-549dbc5564-xhc67 1/1 Running 2 (26s ago) 73s
由于做了空間級別的資源限額,雖然配置了7個副本,最終只能創建資源限制的6個
資源限額的pod創建:
如果對命名空間做了resourcequota資源限額,
那在該命名空間下創建的pod也要做資源限額resources字段必須填寫,否則創建不出pod
[root@master01 RBAC ]#vim quota-deployment-2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: quotanamespace: quota
spec:replicas: 7selector:matchLabels:app: quotatemplate:metadata:labels:app: quotaspec:containers:- name: myappimage: janakiramm/myapp:v1imagePullPolicy: IfNotPresentports:- containerPort: 80
[root@master01 RBAC ]#kubectl apply -f quota-deployment-2.yaml
deployment.apps/quota created
[root@master01 RBAC ]#kubectl get pods -n quota
No resources found in quota namespace.
[root@master01 RBAC ]#kubectl get deploy -n quota
NAME READY UP-TO-DATE AVAILABLE AGE
quota 0/7 0 0 57s
有控制器,pod創建不出
2.限制存儲空間大小
[root@xianchaomaster1 ~]# vim resourcequota-2.yaml
apiVersion: v1
kind: ResourceQuota
metadata:name: quota-storage-testnamespace: quota
spec:hard:requests.storage: "5Gi"persistentvolumeclaims: "5"requests.ephemeral-storage: "1Gi"limits.ephemeral-storage: "2Gi"
[root@xianchaomaster1 ~]# kubectl apply -f resourcequota-2.yaml
備注:requests.storage用來限制對應名稱空間下的存儲下限總和,
persistenvolumeclaims用來限制pvc總數量,
requests.ephemeral-storage用來現在使用本地臨時存儲的下限總容量;
limits.ephemeral-storage用來限制使用本地臨時存儲上限總容量;
以上配置表示在default名稱空間下非停止狀態的容器存儲下限總容量不能超過5G,
pvc的數量不能超過5個,本地臨時存儲下限容量不能超過1G,上限不能超過2G。
可以與CPU,MEM寫到一塊
11.2 LimitRanger準入控制器
LimitRanger準入控制器是k8s上一個內置的準入控制器,LimitRange是k8s上的一個標準資源,
它主要用來定義在某個名稱空間下限制pod或pod里的容器對k8s上的cpu和內存資源使用;
它能夠定義我們在某個名稱空間下創建pod時使用的cpu和內存的上限和下限以及默認cpu、內存的上下限。
如果我們創建pod時定義了資源上下限,但不滿足LimitRange規則中定義的資源上下限,
此時LimitRanger就會拒絕我們創建此pod;
如果我們在LimitRange規則中定義了默認的資源上下限制,
我們創建資源沒有指定其資源限制,
它默認會使用LimitRange規則中的默認資源限制;
同樣的邏輯LimitRanger可以限制一個pod使用資源的上下限,
它還可以限制pod中的容器的資源上下限,比限制pod更加精準;
不管是針對pod還是pod里的容器,它始終只是限制單個pod資源使用。
[root@xianchaomaster1 ~]# cat limitrange.yaml
apiVersion: v1
kind: Namespace
metadata:name: limit
---
apiVersion: v1
kind: LimitRange
metadata:name: cpu-memorynamespace: limit
spec:limits:- default:cpu: 1000mmemory: 1000MidefaultRequest:cpu: 500mmemory: 500Mimin:cpu: 500mmemory: 500Mimax:cpu: 2000mmemory: 2000MimaxLimitRequestRatio:cpu: 4memory: 4type: Container
[root@xianchaomaster1 ~]# kubectl apply -f limitrange.yaml
備注:以上清單主要定義了兩個資源,一個創建limit名稱空間,
一個是在對應limit名稱空間下定義了LimitRange資源;
其中LimitRange資源的名稱為cpu-memory,default字段用來指定默認容器資源上限值;
defaultRequest用來指定默認容器資源下限值;
min字段用來指定限制用戶指定的資源下限不能小于對應資源的值;
max是用來限制用戶指定資源上限值不能大于該值;
maxLimitRequestRatio字段用來指定資源的上限和下限的比值;即上限是下限的多少倍;
type是用來描述對應資源限制的級別,該字段有兩個值pod和container。
上述資源清單表示在該名稱空間下創建pod時,默認不指定其容器的資源限制,
就限制對應容器最少要有0.5個核心的cpu和500M的內存;
最大為1個核心cpu,1g內存;
如果我們手動定義了容器的資源限制,那么對應資源限制最小不能小于cpu為0.5個核心,
內存為500M,最大不能超過cpu為2個核心,內存為2000M;
如果我們在創建pod時,只指定了容器的資源上限或下限,
那么上限最大是下限的的4倍,如果指定cpu上限為2000m那么下限一定不會小于500m,
如果只指定了cpu下限為500m那么上限最大不會超過2000m,對于內存也是同樣的邏輯。
1)在limit名稱空間創建pod,不指定資源,看看是否會被limitrange規則自動附加其資源限制?
[root@xianchaomaster1 ~]# cat pod-limit.yaml
apiVersion: v1
kind: Pod
metadata:name: nginx-pod-demonamespace: limit
spec:containers:- image: nginximagePullPolicy: IfNotPresentname: nginx
[root@master01 RBAC ]#kubectl describe pod nginx-pod-demo -n limitRestart Count: 0Limits:cpu: 1memory: 1000MiRequests:cpu: 500mmemory: 500MiEnvironment: <none>
通過上面結果可以看到我們在limit名稱空間下創建的pod沒有指定其容器資源限制,創建pod后,
其內部容器自動就有了默認的資源限制;
其大小就是我們在定義LimitRange規則中的default和defaultRequest字段中指定的資源限制。
2)創建pod,指定cpu請求是100m,看看是否允許創建
[root@master01 RBAC ]#vim pod-request.yaml
apiVersion: v1
kind: Pod
metadata:name: pod-requestnamespace: limit
spec:containers:- image: nginximagePullPolicy: IfNotPresentname: nginxresources:requests:cpu: 100mmemory: 400Mi
[root@master01 RBAC ]#kubectl apply -f pod-request.yaml
Error from server (Forbidden): error when creating "pod-request.yaml": pods "pod-request" is forbidden:
[minimum cpu usage per Container is 500m, but request is 100m, minimum memory usage per Container is 500Mi,but request is 400Mi, cpu max limit to request ratio per Container is 4, but provided ratio is 10.000000]
這里CPU用的是默認的大小1000 與配置的100計算的比值為10