目錄
k8s認證和serviceaccount
客戶端-->API server
user:username,uid
group:
extra:
API
Request path
http://192.168.1.130:6443/apis/apps/v1/namespaces/default/deployments/myapp-deploy/
HTTP request verb:
get,post,put,delete
API Request verb:
get,list,create,update,patch,watch,proxy,redirect,delete,deletecollection
watch: kubectl get pod -w
Resource:
Subresource:
Namespace:
API group
Object URL:
/apis/<GROUP>/<VERSION>/namespaces/<NAMESPACE_NAME>/<KIND>[/OBJECT_DI]/
kubernetes集群有兩類認證時的用戶賬號,一類是useraccount,叫用戶賬號,通常對應現實中的人使用的賬號;另一類叫serviceaccount,叫服務賬號,它是指pod中一種應用程序運行托管在k8s集群上,想訪問k8s集群上的apiserver時,需要的認證信息,包括:用戶名、賬號、密碼等等。。
kubectl get pod myapp-deploy-controll-55555dd47b-vsf8p -o yaml > myapp-deploy-controll.yaml # 根據一個已知pod的定義格式,生成一份yaml文件,然后修改之后即可使用,不用從頭開始編輯。
kubectl create sa mysa --dry-run=none/client/server -o yaml > mysa.yaml # 創建一個serviceaccount並重定向到yaml文件中。
每創建要給serviceaccount賬號就會自動生成一個secret:
kubectl get secret
kubectl explain pod.spec
serviceAccountName:指定此字段,相當於指定一個sa賬號,可以附帶認證到私有registry 雲上的secret信息的。
kubectl describe secret admin
'''
Name: admin
Namespace: default
Labels: <none>
Annotations: <none>
Image pull secrets: <none> #
Mountable secrets: admin-token-f9mk6
Tokens: admin-token-f9mk6
Events: <none>
'''
所以以后創建的secret對象不要定義在pod上,可以定義在sa上,然后把sa定義在pod上,然后pod通過sa的Image pull secrets 也能完成私有倉庫鏡像下載的認證。這樣在pod資源文件清單中就不被泄露出去secret使用的是哪些相關信息了。對於sa的細節我們可以認為是獲取不到的。
我們為pod獲取私有倉庫鏡像認證的兩種方式為:
1.直接使用imagePullSecret字段指定能完成認證時的secret對象;
2.在pod上自定義一個serviceaccout,在serviceaccount上附加pod獲取鏡像時使用的secret對象。
kubectl config view # 查看客戶端通過kubeconfig配置文件連接apiserver的配置信息
配置文件也是一個標准的k8s資源
'''
[root@master01 static-pod]# kubectl config view
apiVersion: v1
clusters: # 集群列表,cluster1、cluster2、cluster3、cluster4.....
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://192.168.1.130:6443
name: kubernetes
contexts: # 上下文列表
- context: # 表示用哪個賬號訪問哪個集群
cluster: kubernetes # 哪個集群
user: kubernetes-admin # 被哪個用戶賬號訪問
name: kubernetes-admin@kubernetes # 給context的取名
current-context: kubernetes-admin@kubernetes # 當前上下文,表示當前用哪個賬號訪問哪個集群:用kubernetes-admin賬號訪問cluster集群為kubernetes的k8s集群。
kind: Config
preferences: {}
users: # 用戶賬號名稱列表,user1、user2、user3、user4......
- name: kubernetes-admin # kubernetes-admin表示整個集群的管理員
user: # 用戶自己也需要被服務器端apiserver所認證。
client-certificate-data: REDACTED
client-key-data: REDACTED
'''
上下文是什么?kubeconfig配置文件不單單讓我們訪問一個k8s集群的,如果有多個k8s集群,我們只有一台可訪問遠端k8s集群的主機,我們一會兒想控制A集群,一會兒想控制B集群,一會兒想控制C集群,難道還要換用戶賬號(控制台上的系統用戶賬號)?為了一個kubectl能控制多個k8s集群
cd /etc/kubernetes/pki
(umask 077;openssl genrsa -out xiaochao.key 2048) # 創建私鑰
openssl req -new -key xiaochao.key -out xiaochao.csr -subj "/CN=xiaochao" # 創建證書簽名 /CN=xiaochao 就是創建的的認證apiserver的用戶,一定不能寫錯。
openssl x509 -req -in xiaochao.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out xiaochao.crt -days 3650 # 根據簽名和集群私鑰和證書簽發用戶證書
openssl x509 -in xiaochao.crt -text -noout # 以文本格式輸出頒發的證書 如下圖
kubectl config --help
current-context:顯示當前上下文
set-cluster:
set-context:創建一個新的上下文
set-credentials:創建一個新的用戶
use-context:切換當前上下文
view:查看./kubeconfig文件
--embed-certs=true:隱藏客戶端證書和私鑰
# 創建一個集群外部的客戶端
kubectl config set-credentials xiaochao --client-certificate=./xiaochao.crt --client-key=./xiaochao.key --embed-certs=true
# 創建一個集群上下文
kubectl config set-context xiaochao@kubernetes --cluster=kubernetes --user=xiaochao
# 切換當前上下文
kubectl config use-context xiaochao@kubernetes
在訪問集群用戶為xiaochao時,如下圖:
xiaochao用戶雖然是已經是認證的用戶,但是沒有授權,沒有操作集群的權限。。。
# 切換到kubernetes-admin用戶
kubectl config use-context kubernetes-admin@kubernetes
# 創建一個集群
kubectl config set-cluster mycluster --kubeconfig=/tmp/test.conf --server="https://192.168.1.130:6443" --certificate-authority=/etc/kubernetes/pki/ca.crt --embed-certs=true
授權
授權插件:
Node
ABAC(attribution based access control):基於屬性的訪問控制;在RBAC啟用之前用到的授權控制插件的算法
RBAC:Role based access control,基於角色的訪問控制。
Webhook:基於http回調機制的訪問控制
k8s上的所有組件或者說是所有內容可分為3類,絕大部分是對象和對象列表:
對象
對象列表
虛擬路徑(url):非對象資源,占有比例很少
什么是RBAC(基於角色的訪問控制)?
讓一個用戶(Users)扮演一個角色(Role),角色擁有權限,從而讓用戶擁有這樣的權限,隨后在授權機制當中,只需要將權限授予某個角色,此時用戶將獲取對應角色的權限,從而實現角色的訪問控制。如圖:
把對一個Object(對象)的Operation(操作)叫做許可權限(Permissions),授予Role擁有某種被許可的權限(Permissions),就擁有了某些對象上的某種操作權限。
在k8s的授權機制當中,采用RBAC的方式進行授權,其工作邏輯是,把對對象的操作權限定義到一個角色當中,再將用戶(user account or service account)綁定到該角色,從而使用戶(user account or service account)得到對應角色的權限。如果通過rolebinding綁定role,只能對rolebinding所在的名稱空間的資源有權限,上圖user1這個用戶(user account or service account)綁定到role1上,只對role1這個名稱空間的資源有權限,對其他名稱空間資源沒有權限,屬於名稱空間級別的;
role 和role binding授予名稱空間級別的權限,對某個名稱空間的操作權限
role:
operations
objects
rolebinding:
user account or service account
role
clusterrole 和 clusterrolebinding授予集群級別的權限,對所有名稱空間都有操作權限
另外,k8s為此還有一種集群級別的授權機制,就是定義一個集群角色(ClusterRole),對集群內的所有資源都有可操作的權限,從而將User2(user account or service account)通過ClusterRoleBinding到ClusterRole,從而使User2(user account or service account)擁有集群的操作權限。Role、RoleBinding、ClusterRole和ClusterRoleBinding的關系如下圖:
通過上圖可以看到,可以通過rolebinding綁定role,**rolebinding綁定clusterrole**,clusterrolebinding綁定clusterrole。
上面我們說了兩個角色綁定:
(1)用戶通過rolebinding綁定role
(2)用戶通過clusterrolebinding綁定clusterrole
還有一種:rolebinding綁定clusterrole
假如有6個名稱空間,每個名稱空間的用戶都需要對自己的名稱空間有管理員權限,那么需要定義6個role和rolebinding,然后依次綁定,如果名稱空間更多,我們需要定義更多的role,這個是很麻煩的,所以我們引入clusterrole,定義一個clusterrole,對clusterrole授予所有權限,然后用戶通過rolebinding綁定到clusterrole,就會擁有自己名稱空間的管理員權限了
注:RoleBinding僅僅對當前名稱空間有對應的權限。
Role
kubectl explain role --help
kubectl create role pod-reader --verb=get,list,watch --resource=pods --dry-run -o yaml
'''
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
creationTimestamp: null
name: pod-reader
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- list
- watch
'''
創建一個role角色pod-reader,--verb 可以執行get,list,watch操作,--resource 可以對pod資源進行操作。
kubectl create role pod-reader --verb=get,list,watch --resource=pods --dry-run -o yaml > pod-reader-role.yaml
vim pod-reader-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
rules:
- apiGroups:
- ""
resources:
- pods
verbs: ["get","list","watch"]
kubectl apply -f pod-reader-role.yaml
kubectl get role
kubectl describe role pod-reader
Resources:資源類別
Resource Names:資源名稱,對某一類別資源的某個或某些個資源進行限制操作
Non-Resource URLs:在k8s上不能被定義成對象的資源,通常表示是來定義對某些資源的一種操作
rolebinding
rolebinding 既可以綁定到role,有可以綁定到clusterrole;而clusterrolebinding只能綁定到clusterrole。
將用戶綁定(rolebinding)到role
在上面創建的xiaochao用戶,是沒有讀取pod資源權限的,現在我們通過rolebinding,將xiaochao用戶綁定到pod-reader角色上。
kubectl create rolebinding --help
kubectl create rolebinding NAME --clusterrole=NAME|--role=NAME [--user=username] [--group=groupname]
[--serviceaccount=namespace:serviceaccountname] [--dry-run=server|client|none] [options]
kubectl create rolebinding xiaochao-read-pods --role=pod-reader --user=xiaochao --dry-run -o yaml
'''
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
creationTimestamp: null
name: xiaochao-read-pods
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: pod-reader
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: xiaochao
'''
kubectl create rolebinding xiaochao-read-pods --role=pod-reader --user=xiaochao --dry-run -o yaml > xiaochao-read-pods.yaml
vim xiaochao-read-pods.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
# creationTimestamp: null
name: xiaochao-read-pods
roleRef: # roleRef:roleReference,role引用
apiGroup: rbac.authorization.k8s.io
kind: Role
name: pod-reader
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User # 並不是單獨存在的一種資源,但是在綁定用戶時,我們需要這樣來定義
name: xiaochao
kubectl apply -f xiaochao-read-pods.yaml
kubectl get rolebinding -o wide
kubectl describe rolebinding xiaochao-read-pods
kubectl explain rolebinding
apiVersion <string>
kind <string>
metadata <Object>
roleRef <Object> -required-
apiGroup <string> -required-
kind <string> -required-
name <string> -required-
subjects <[]Object>
apiGroup <string>
kind <string> -required- # "User", "Group", and "ServiceAccount".
name <string> -required-
namespace <string> # 指明sa是哪個名稱空間中的sa,因為sa是名稱空間級別的資源,不同名稱空間sa名稱可能重名。
切換集群上下文到xiaochao用戶,操作role定義資源的動作
# 切換集群上下文到xiaochao用戶
kubectl config use-context xiaochao@kubernetes
kubectl get pods # 現在能對pod資源進行get list watch操作了,但如果create,delete,edit還是不行,因為我們rolebinding role對象pod-reader中沒定義此操作的--verb
kubectl get svc # 通過rolebinding 綁定的用戶xiaochao到role資源操作對象的pod-reader,只有對pod的操作get list watch的權限,其他資源無法操作.
kubectl get po -n kube-system # 沒有權限,因為定義的role和rolebinding屬於名稱空間級別的資源,都只對當前名稱空間(當前是default名稱空間)有效,所以不能訪問kube-system名稱空間下的資源。
clusterrole
clusterrole和role的定義方式是一樣的。。。
kubectl create clusterrole --help
創建clusterrole:
kubectl create clusterrole cluster-reader --verb=get,list,watch --resource=pods --dry-run -o yaml
'''
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
creationTimestamp: null
name: cluster-reader
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- list
- watch
'''
# 切換系統上下文,
kubectl config use-context kubernetes-admin@kubernetes
kubectl create clusterrole cluster-reader --verb=get,list,watch --resource=pods --dry-run -o yaml > clusterrole-reader.yaml
vim clusterrole-reader.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
# creationTimestamp: null
name: cluster-reader
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- list
- watch
kubectl apply -f clusterrole-reader.yaml
clusterrolebinding
kubectl create clusterrolebinding --help
創建clusterrolebinding
創建一個linux系統用戶,並使用此用戶將kubernetes集群的上下文切換為xiaochao,使用k8s的xiaochao賬號去操作集群,就和liunx root用戶在k8s的admin賬號操作就分開了,互不干涉。
[root@master01 authority]# useradd ik8s
[root@master01 authority]# cp -rp /root/.kube/ /home/ik8s/
[root@master01 authority]# chown -R ik8s.ik8s /home/ik8s/
[root@master01 authority]# ls -ld /home/ik8s/
drwx------. 3 ik8s ik8s 75 Dec 23 09:57 /home/ik8s/
[root@master01 authority]# su - ik8s
kubectl config use-context xiaochao@kubernetes
kubectl get po
先刪除之前創建的rolebinding-->xiaochao-read-pods,為了接下來將xiaochao賬號綁定到clusterrolebinding。
kubectl delete rolebinding xiaochao-read-pods
kubectl create clusterrolebinding xiaochao-read-all-pods --clusterrole=cluster-reader --user=xiaochao --dry-run -o yaml
kubectl create clusterrolebinding xiaochao-read-all-pods --clusterrole=cluster-reader --user=xiaochao --dry-run -o yaml > clusterrolebinding-xiaochao-read-all-pods-cluster-reader.yaml
vim clusterrolebinding-xiaochao-read-all-pods-cluster-reader.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
# creationTimestamp: null
name: xiaochao-read-all-pods
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-reader
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: xiaochao
kubectl apply -f clusterrolebinding-xiaochao-read-all-pods-cluster-reader.yaml
在之前創建的linux用戶上,在集群上下文為xiaochao的賬號上:
kubectl get pod
kubectl get pod -kube-system
將rolebinding綁定到clusterrole
**1.將xiaochao通過rolebinding綁定到clusterrole cluster-reader **
xiaochao -> rolebinding -> clusterrole
先將之間xiaochao賬號 clusterrolebinding xiaochao-read-all-pods刪除:
kubectl delete clusterrolebinding xiaochao-read-all-pods
kubectl create rolebinding xiaochao-by-clusterrole-read-pods --clusterrole=cluster-reader --user=xiaochao --dry-run -o yaml
'''
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
creationTimestamp: null
name: xiaochao-by-clusterrole-read-pods
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-reader
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: xiaochao
'''
kubectl create rolebinding xiaochao-by-clusterrole-read-pods --clusterrole=cluster-reader --user=xiaochao --dry-run -o yaml > rolebinding-clusterrole-read_pods.yaml
kubectl apply -f rolebinding-clusterrole-read_pods.yaml
kubectl get pods
kubectl get pod -n kube-system # 只能讀取自己名稱空間的pods。。。
2.將xiaochao通過rolebinding綁定到clusterrole admin
將xiaochao通過rolebinding綁定到clusterrole admin,則xiaochao 在rolebinding所在名稱空間下的所有資源均能執行各類操作,類似管理員的權限。。。
kubectl create rolebinding default-ns-admin --clusterrole=admin --user=xiaochao --dry-run -o yaml > rolebinding-cluster_admin-ops_all-resource.yaml
vim rolebinding-cluster_admin-ops_all-resource.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
# creationTimestamp: null
name: default-ns-admin
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: admin
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: xiaochao
kubectl apply -f rolebinding-cluster_admin-ops_all-resource.yaml
在k8s集群搭建完之后,默認的賬號就有操作所有名稱空間下的所有資源,這是為什么呢?
kubectl get clusterrolebinding
kubectl get clusterrolebinding cluster-admin -o yaml
clusterrolebinding cluster-admin定義了一個組(Group:不是系統上常見資源,不能創建)system:masters,而這個組內定義了集群初始化完成之后的用戶kubernetes-admin:
kubectl config view
那為什么 kubernetes-admin會屬於system:masters 組呢?這是在kubernetes證書中定義的:
cd /etc/kubernetes/pki
openssl x509 -in apiserver-kubelet-client.crt -text -noout
RBAC三類組件綁定到role或者clusterrole
在RBAC上授權時,RBAC允許3類組件:
user:綁定到roelbding或者clusterolebinding,表示只授權一個用戶來扮演相關角色
group:綁定到組上,表示授權組上所有用戶都能扮演角色。如果想一次授權多個用戶,在一個名稱空間中,擁有同樣的權限,可以把多個用戶定義成組,授權時做總的授權。。如何定義成組?在創建xiaochao 證書簽名的時候將xiaochao添加到組中即可:
openssl req -new -key xiaochao.key -out xiaochao.csr -subj "/CN=xiaochao/O=admin"
以后再授權的時候,綁定到system:masters組上,xiaochao就有權限
serviceaccount:
serviceaccount綁定rolebinding或者clusterrolebinding
當serviceaccount做了rolebinding或者clusterrolebinding,則serviceaccount擁有了rolebinding或者clusterrolebinding,任何一個pod啟動時如果以這個serviceAccountName作為它使用的serviceaccount的話,這個pod中運行的應用程序就擁有了serviceaccouont授予的權限。
pod中,pod.spec.serviceAccountName以serviceaccount來連接apiserver獲取訪問資源。比如把serviceAccountName指定的賬號(serivceaccount)授予admin權限,那么間接就讓pod擁有了管理員權限,擁有了管理集群資源的權限。
以flannel網絡插件為例:
https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: flannel
rules:
- apiGroups: ['extensions']
resources: ['podsecuritypolicies']
verbs: ['use']
resourceNames: ['psp.flannel.unprivileged']
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- apiGroups:
- ""
resources:
- nodes
verbs:
- list
- watch
- apiGroups:
- ""
resources:
- nodes/status
verbs:
- patch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: flannel
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: flannel
subjects:
- kind: ServiceAccount # flannel pod就有了serviceAccount(flannel)的所有權限
name: flannel
namespace: kube-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: flannel
namespace: kube-system
kubectl get po -n kube-system
kubectl get po kube-flannel-ds-hjhgr -o yaml -n kube-system