08-K8S之k8s認證和serviceaccount


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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM