RBAC受權

RBAC

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

RBAC API 對象

Kubernetes有一個很基本的特性就是它的全部資源對象都是模型化的 API 對象,容許執行 CRUD(Create、Read、Update、Delete)操做(也就是咱們常說的增、刪、改、查操做),好比下面的這下資源:api

  • Pods
  • ConfigMaps
  • Deployments
  • Nodes
  • Secrets
  • Namespaces

上面這些資源對象的可能存在的操做有:app

  • create
  • get
  • delete
  • list
  • update
  • edit
  • watch
  • exec

在更上層,這些資源和 API Group 進行關聯,好比Pods屬於 Core API Group,而Deployements屬於 apps API Group,要在Kubernetes中進行RBAC的管理,除了上面的這些資源和操做之外,咱們還須要另外的一些對象:工具

  • Rule:規則,規則是一組屬於不一樣 API Group 資源上的一組操做的集合
  • Role 和 ClusterRole:角色和集羣角色,這兩個對象都包含上面的 Rules 元素,兩者的區別在於,在 Role 中,定義的規則只適用於單個命名空間,也就是和 namespace 關聯的,而 ClusterRole 是集羣範圍內的,所以定義的規則不受命名空間的約束。另外 Role 和 ClusterRole 在Kubernetes中都被定義爲集羣內部的 API 資源,和咱們前面學習過的 Pod、ConfigMap 這些相似,都是咱們集羣的資源對象,因此一樣的可使用咱們前面的kubectl相關的命令來進行操做
  • Subject:主題,對應在集羣中嘗試操做的對象,集羣中定義了3種類型的主題資源:學習

    • User Account:用戶,這是有外部獨立服務進行管理的,管理員進行私鑰的分配,用戶可使用 KeyStone或者 Goolge 賬號,甚至一個用戶名和密碼的文件列表也能夠。對於用戶的管理集羣內部沒有一個關聯的資源對象,因此用戶不能經過集羣內部的 API 來進行管理
    • Group:組,這是用來關聯多個帳戶的,集羣中有一些默認建立的組,好比cluster-admin
    • Service Account:服務賬號,經過Kubernetes API 來管理的一些用戶賬號,和 namespace 進行關聯的,適用於集羣內部運行的應用程序,須要經過 API 來完成權限認證,因此在集羣內部進行權限操做,咱們都須要使用到 ServiceAccount,這也是咱們這節課的重點
  • RoleBinding 和 ClusterRoleBinding:角色綁定和集羣角色綁定,簡單來講就是把聲明的 Subject 和咱們的 Role 進行綁定的過程(給某個用戶綁定上操做的權限),兩者的區別也是做用範圍的區別:RoleBinding 只會影響到當前 namespace 下面的資源操做權限,而 ClusterRoleBinding 會影響到全部的 namespace。測試

接下來咱們來經過幾個示例來演示下RBAC的配置方法。jsonp

建立一個只能訪問某個 namespace 的用戶

咱們來建立一個 User Account,只能訪問 kube-system 這個命名空間:spa

  • username: haimaxy
  • group: youdianzhishi

第1步:建立用戶憑證

咱們前面已經提到過,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.crtca.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" 

第2步:建立角色

用戶建立完成後,接下來就須要給該用戶添加操做權限,咱們來定義一個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這個上下文了,由於木有權限啦

第3步:建立角色權限綁定

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

第4步. 測試

如今咱們應該能夠上面的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 這個命名空間的操做權限

建立一個只能訪問某個 namespace 的ServiceAccount

上面咱們建立了一個只能訪問某個命名空間下面的普通用戶,咱們前面也提到過 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 頁面進行登陸: Dashboard

咱們能夠看到上面的提示信息,這是由於咱們登陸進來後默認跳轉到 default 命名空間,咱們切換到 kube-system 命名空間下面就能夠了: Dashboard

咱們能夠看到能夠訪問pod列表了,可是也會有一些其餘額外的提示:events is forbidden: User 「system:serviceaccount:kube-system:haimaxy-sa」 cannot list events in the namespace 「kube-system」,這是由於當前登陸用只被受權了訪問 pod 和 deployment 的權限,一樣的,訪問下deployment看看能夠了嗎?

一樣的,你能夠根據本身的需求來對訪問用戶的權限進行限制,能夠本身經過 Role 定義更加細粒度的權限,也可使用系統內置的一些權限……

建立一個能夠訪問全部 namespace 的ServiceAccount

剛剛咱們建立的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 clusterrolekubectl 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後的字符串 
相關文章
相關標籤/搜索