RBAC
使用rbac.authorization.k8s.io
API Group 來實現受權決策,容許管理員經過 Kubernetes API 動態配置策略,要啓用RBAC
,須要在 apiserver 中添加參數--authorization-mode=RBAC
,若是使用的kubeadm
安裝的集羣,1.6 版本以上的都默認開啓了RBAC
,能夠經過查看 Master 節點上 apiserver 的靜態Pod
定義文件:shell
$ cat /etc/kubernetes/manifests/kube-apiserver.yaml ... - --authorization-mode=Node,RBAC ...
若是是二進制的方式搭建的集羣,添加這個參數事後,記得要重啓 apiserver 服務。json
Kubernetes
有一個很基本的特性就是它的全部資源對象都是模型化的 API 對象,容許執行 CRUD(Create、Read、Update、Delete)操做(也就是咱們常說的增、刪、改、查操做),好比下面的這下資源:api
上面這些資源對象的可能存在的操做有:app
在更上層,這些資源和 API Group 進行關聯,好比Pods
屬於 Core API Group,而Deployements
屬於 apps API Group,要在Kubernetes
中進行RBAC
的管理,除了上面的這些資源和操做之外,咱們還須要另外的一些對象:工具
Kubernetes
中都被定義爲集羣內部的 API 資源,和咱們前面學習過的 Pod、ConfigMap 這些相似,都是咱們集羣的資源對象,因此一樣的可使用咱們前面的kubectl
相關的命令來進行操做Subject:主題,對應在集羣中嘗試操做的對象,集羣中定義了3種類型的主題資源:學習
Kubernetes
API 來管理的一些用戶賬號,和 namespace 進行關聯的,適用於集羣內部運行的應用程序,須要經過 API 來完成權限認證,因此在集羣內部進行權限操做,咱們都須要使用到 ServiceAccount,這也是咱們這節課的重點RoleBinding 和 ClusterRoleBinding:角色綁定和集羣角色綁定,簡單來講就是把聲明的 Subject 和咱們的 Role 進行綁定的過程(給某個用戶綁定上操做的權限),兩者的區別也是做用範圍的區別:RoleBinding 只會影響到當前 namespace 下面的資源操做權限,而 ClusterRoleBinding 會影響到全部的 namespace。測試
接下來咱們來經過幾個示例來演示下RBAC
的配置方法。jsonp
咱們來建立一個 User Account,只能訪問 kube-system 這個命名空間:spa
咱們前面已經提到過,Kubernetes
沒有 User Account 的 API 對象,不過要建立一個用戶賬號的話也是挺簡單的,利用管理員分配給你的一個私鑰就能夠建立了,這個咱們能夠參考官方文檔中的方法,這裏咱們來使用OpenSSL
證書來建立一個 User,固然咱們也可使用更簡單的cfssl
工具來建立:code
給用戶 haimaxy 建立一個私鑰,命名成:haimaxy.key:
$ openssl genrsa -out haimaxy.key 2048
使用咱們剛剛建立的私鑰建立一個證書籤名請求文件:haimaxy.csr,要注意須要確保在-subj
參數中指定用戶名和組(CN表示用戶名,O表示組):
$ openssl req -new -key haimaxy.key -out haimaxy.csr -subj "/CN=haimaxy/O=youdianzhis"
而後找到咱們的Kubernetes
集羣的CA
,咱們使用的是kubeadm
安裝的集羣,CA
相關證書位於/etc/kubernetes/pki/
目錄下面,若是你是二進制方式搭建的,你應該在最開始搭建集羣的時候就已經指定好了CA
的目錄,咱們會利用該目錄下面的ca.crt
和ca.key
兩個文件來批准上面的證書請求
生成最終的證書文件,咱們這裏設置證書的有效期爲500天:
$ openssl x509 -req -in haimaxy.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out haimaxy.crt -days 500
如今查看咱們當前文件夾下面是否生成了一個證書文件:
$ ls haimaxy.csr haimaxy.key haimaxy.crt
如今咱們可使用剛剛建立的證書文件和私鑰文件在集羣中建立新的憑證和上下文(Context):
$ kubectl config set-credentials haimaxy --client-certificate=haimaxy.crt --client-key=haimaxy.key
咱們能夠看到一個用戶haimaxy
建立了,而後爲這個用戶設置新的 Context:
$ kubectl config set-context haimaxy-context --cluster=kubernetes --namespace=kube-system --user=haimaxy
到這裏,咱們的用戶haimaxy
就已經建立成功了,如今咱們使用當前的這個配置文件來操做kubectl
命令的時候,應該會出現錯誤,由於咱們尚未爲該用戶定義任何操做的權限呢:
$ kubectl get pods --context=haimaxy-context Error from server (Forbidden): pods is forbidden: User "haimaxy" cannot list pods in the namespace "default"
用戶建立完成後,接下來就須要給該用戶添加操做權限,咱們來定義一個YAML
文件,建立一個容許用戶操做 Deployment、Pod、ReplicaSets 的角色,以下定義:(haimaxy-role.yaml)
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: haimaxy-role namespace: kube-system rules: - apiGroups: ["", "extensions", "apps"] resources: ["deployments", "replicasets", "pods"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] # 也可使用['*']
其中Pod
屬於 core 這個 API Group,在YAML
中用空字符就能夠,而Deployment
屬於 apps 這個 API Group,ReplicaSets
屬於extensions
這個 API Group(我怎麼知道的?點這裏查文檔),因此 rules 下面的 apiGroups 就綜合了這幾個資源的 API Group:["", "extensions", "apps"],其中verbs
就是咱們上面提到的能夠對這些資源對象執行的操做,咱們這裏須要全部的操做方法,因此咱們也可使用['*']來代替。
而後建立這個Role
:
$ kubectl create -f haimaxy-role.yaml
注意這裏咱們沒有使用上面的
haimaxy-context
這個上下文了,由於木有權限啦
Role 建立完成了,可是很明顯如今咱們這個 Role 和咱們的用戶 haimaxy 尚未任何關係,對吧?這裏我就須要建立一個RoleBinding
對象,在 kube-system 這個命名空間下面將上面的 haimaxy-role 角色和用戶 haimaxy 進行綁定:(haimaxy-rolebinding.yaml)
apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: haimaxy-rolebinding namespace: kube-system subjects: - kind: User name: haimaxy apiGroup: "" roleRef: kind: Role name: haimaxy-role apiGroup: ""
上面的YAML
文件中咱們看到了subjects
關鍵字,這裏就是咱們上面提到的用來嘗試操做集羣的對象,這裏對應上面的 User 賬號 haimaxy,使用kubectl
建立上面的資源對象:
$ kubectl create -f haimaxy-rolebinding.yaml
如今咱們應該能夠上面的haimaxy-context
上下文來操做集羣了:
$ kubectl get pods --context=haimaxy-context ....
咱們能夠看到咱們使用kubectl
的使用並無指定 namespace 了,這是由於咱們已經爲該用戶分配了權限了,若是咱們在後面加上一個-n default
試看看呢?
$ kubectl --context=haimaxy-context get pods --namespace=default Error from server (Forbidden): pods is forbidden: User "haimaxy" cannot list pods in the namespace "default"
是符合咱們預期的吧?由於該用戶並無 default 這個命名空間的操做權限
上面咱們建立了一個只能訪問某個命名空間下面的普通用戶,咱們前面也提到過 subjects 下面還有一直類型的主題資源:ServiceAccount,如今咱們來建立一個集羣內部的用戶只能操做 kube-system 這個命名空間下面的 pods 和 deployments,首先來建立一個 ServiceAccount 對象:
$ kubectl create sa haimaxy-sa -n kube-system
固然咱們也能夠定義成YAML
文件的形式來建立。
而後新建一個 Role 對象:(haimaxy-sa-role.yaml)
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: haimaxy-sa-role namespace: kube-system rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "watch", "list"] - apiGroups: ["apps"] resources: ["deployments"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
能夠看到咱們這裏定義的角色沒有建立、刪除、更新 Pod 的權限,待會咱們能夠重點測試一下,建立該 Role 對象:
$ kubectl create -f haimaxy-sa-role.yaml
而後建立一個 RoleBinding 對象,將上面的 haimaxy-sa 和角色 haimaxy-sa-role 進行綁定:(haimaxy-sa-rolebinding.yaml)
kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: haimaxy-sa-rolebinding namespace: kube-system subjects: - kind: ServiceAccount name: haimaxy-sa namespace: kube-system roleRef: kind: Role name: haimaxy-sa-role apiGroup: rbac.authorization.k8s.io
添加這個資源對象:
$ kubectl create -f haimaxy-sa-rolebinding.yaml
而後咱們怎麼去驗證這個 ServiceAccount 呢?咱們前面的課程中是否是提到過一個 ServiceAccount 會生成一個 Secret 對象和它進行映射,這個 Secret 裏面包含一個 token,咱們能夠利用這個 token 去登陸 Dashboard,而後咱們就能夠在 Dashboard 中來驗證咱們的功能是否符合預期了:
$ kubectl get secret -n kube-system |grep haimay-sa haimay-sa-token-nxgqx kubernetes.io/service-account-token 3 47m $ kubectl get secret haimay-sa-token-nxgqx -o jsonpath={.data.token} -n kube-system |base64 -d # 會生成一串很長的base64後的字符串
使用這裏的 token 去 Dashboard 頁面進行登陸:
咱們能夠看到上面的提示信息,這是由於咱們登陸進來後默認跳轉到 default 命名空間,咱們切換到 kube-system 命名空間下面就能夠了:
咱們能夠看到能夠訪問pod列表了,可是也會有一些其餘額外的提示:events is forbidden: User 「system:serviceaccount:kube-system:haimaxy-sa」 cannot list events in the namespace 「kube-system」,這是由於當前登陸用只被受權了訪問 pod 和 deployment 的權限,一樣的,訪問下deployment看看能夠了嗎?
一樣的,你能夠根據本身的需求來對訪問用戶的權限進行限制,能夠本身經過 Role 定義更加細粒度的權限,也可使用系統內置的一些權限……
剛剛咱們建立的haimaxy-sa
這個 ServiceAccount 和一個 Role 角色進行綁定的,若是咱們如今建立一個新的 ServiceAccount,須要他操做的權限做用於全部的 namespace,這個時候咱們就須要使用到 ClusterRole 和 ClusterRoleBinding 這兩種資源對象了。一樣,首先新建一個 ServiceAcount 對象:(haimaxy-sa2.yaml)
apiVersion: v1 kind: ServiceAccount metadata: name: haimaxy-sa2 namespace: kube-system
建立:
$ kubectl create -f haimaxy-sa2.yaml
而後建立一個 ClusterRoleBinding 對象(haimaxy-clusterolebinding.yaml):
kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1beta1 metadata: name: haimaxy-sa2-clusterrolebinding subjects: - kind: ServiceAccount name: haimaxy-sa2 namespace: kube-system roleRef: kind: ClusterRole name: cluster-admin apiGroup: rbac.authorization.k8s.io
從上面咱們能夠看到咱們沒有爲這個資源對象聲明 namespace,由於這是一個 ClusterRoleBinding 資源對象,是做用於整個集羣的,咱們也沒有單獨新建一個 ClusterRole 對象,而是使用的 cluster-admin 這個對象,這是Kubernetes
集羣內置的 ClusterRole 對象,咱們可使用kubectl get clusterrole
和kubectl get clusterrolebinding
查看系統內置的一些集羣角色和集羣角色綁定,這裏咱們使用的 cluster-admin 這個集羣角色是擁有最高權限的集羣角色,因此通常須要謹慎使用該集羣角色。
建立上面集羣角色綁定資源對象,建立完成後一樣使用 ServiceAccount 對應的 token 去登陸 Dashboard 驗證下:
$ kubectl create -f haimaxy-clusterolebinding.yaml
$ kubectl get secret -n kube-system |grep haimay-sa2 haimay-sa2-token-nxgqx kubernetes.io/service-account-token 3 47m $ kubectl get secret haimay-sa2-token-nxgqx -o jsonpath={.data.token} -n kube-system |base64 -d # 會生成一串很長的base64後的字符串