Kebernetes 學習總結(9)認證-受權-RBAC

1、概述
Kubernetes集羣的全部操做基本上都是經過kube-apiserver這個組件進行的,它提供HTTP RESTful形式的API供集羣內外客戶端調用。這就引起了安全問題:假如別人知道你的API地址,那麼你的服務器就很容易遭到惡意破壞。因此k8s 認證受權過程不支持HTTP鏈接到kube-apiserver。
使用kubectl cluster-info 能夠看到API server的Endpoint地址,以下:node

[root@k8s-master-dev ~]# kubectl cluster-info
Kubernetes master is running at https://192.168.20.79:6443
KubeDNS is running at https://192.168.20.79:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
[root@k8s-master-dev ~]# 

對APIServer的訪問要通過的三個步驟,前面兩個是認證和受權,第三個是 Admission Control,它也能在必定程度上提升安全性,不過更可能是資源管理方面的做用。web

client --> | authentication(認證 驗證用戶名與密碼是否正確)
          | authorization (受權 控制當前用戶的權限)
          | admissionControl (資源依賴、關聯及環境檢查)      --> Resources

k8s模塊化程度很是高,認證、受權、准入控制都是由用戶指定某種插件實現相應功能。docker

Authentication
kubernetes提供了多種認證方式,好比客戶端證書、靜態token、靜態密碼文件、ServiceAccountTokens等等,都是以插件(plugin)的形式由用戶指定。能夠同時指定使用一種或多種認證方式。client 通過任何一種plugin的成功認證 即表示認證成功,無需再通過其它額外認證。
常見以下兩種:
1) token(例預共享密鑰,是經過http首部Restful方式傳遞密鑰)
2) SSL/TLS(authentication、雙向身份驗證、https通訊) shell

Authorization
k8s 1.6以後支持 RBAC、node、ABAC、webhook等plugins。 RBAC(Role-Based Access)只有許可受權(默認拒絕全部),kubeadm安裝的k8s默認都是使用RBAC的受權。 RBAC讓集羣管理員能夠針對特定使用者或服務帳號的角色,進行更精確的資源訪問控制。在RBAC中,權限與角色相關聯,用戶經過成爲適當角色的成員而獲得這些角色的權限。這就極大地簡化了權限的管理。在一個組織中,角色是爲了完成各類工做而創造,用戶則依據它的責任和資格來被指派相應的角色,用戶能夠很容易地從一個角色被指派到另外一個角色。vim

AdmissionControl
准入控制:本質上爲一段准入代碼,在對kubernetes api的請求過程當中,順序爲:先通過認證 & 受權,而後執行准入操做,最後對目標對象進行操做。這個准入代碼在api-server中,並且必須被編譯到二進制文件中才能被執行。在對集羣進行請求時,每一個准入控制代碼都按照必定順序執行。若是有一個准入控制拒絕了這次請求,那麼整個請求的結果將會當即返回,並提示用戶相應的error信息。
經常使用組件(控制代碼)以下:api

  • AlwaysAdmit:容許全部請求
  • AlwaysDeny:禁止全部請求,多用於測試環境
  • ServiceAccount:它將serviceAccounts實現了自動化,它會輔助serviceAccount作一些事情,好比若是pod沒有serviceAccount屬性,它會自動添加一個default,並確保pod的serviceAccount始終存在
  • LimitRanger:他會觀察全部的請求,確保沒有違反已經定義好的約束條件,這些條件定義在namespace中LimitRange對象中。若是在kubernetes中使用LimitRange對象,則必須使用這個插件。
  • NamespaceExists:它會觀察全部的請求,若是請求嘗試建立一個不存在的namespace,則這個請求被拒絕

2、訪問API server的方式
k8s API server 提供了豐富的Restful接口 提用戶訪問 。
REST request path: http://apiServerName:port/apis/apps/version_name/namespaces/default/deployments/myapp-deploy/(add/delete/edit/get)
API request verb : get/list/create/update/patch/watch/proxy/redirect/delete/deletecollection/安全

使用kubectl 命令時默認調用${HOME}/.kube/目錄中的認證信息,但其它訪問方式則不能調用這些認證信息(例curl),若是但願經過curl方式訪問API server,可使用代理功能。
在本地啓用代理:服務器

[root@k8s-master-dev ~]# ls .kube/
cache  config  http-cache
[root@k8s-master-dev ~]# kubectl proxy --port=8080
Starting to serve on 127.0.0.1:8080

而後在另外一個終端使用curl 的方式訪問,以下所示:app

[root@k8s-master-dev ~]# curl http://localhost:8080/api/v1/namespaces
{
  "kind": "NamespaceList",
  "apiVersion": "v1",
  "metadata": {
    "selfLink": "/api/v1/namespaces",
    "resourceVersion": "768383"
  }
    ...

[root@k8s-master-dev ~]# curl http://localhost:8080/apis/apps/v1/namespaces/kube-system/deployments
{
  "kind": "DeploymentList",
  "apiVersion": "apps/v1",
  "metadata": {
    "selfLink": "/apis/apps/v1/namespaces/kube-system/deployments",
    "resourceVersion": "768654"
  },
    ...

3、Authentication
哪些client須要與API server 交互?cluster 外部的client (kubectl)和cluster內部的 client(Pod)都須要與API server交互。frontend

[root@k8s-master-dev ~]# kubectl get svc
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)     AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP     5d
mongo        ClusterIP   None         <none>        27017/TCP   1d
[root@k8s-master-dev ~]# kubectl describe svc kubernetes
Name:              kubernetes
Namespace:         default
Labels:            component=apiserver
                   provider=kubernetes
Annotations:       <none>
Selector:          <none>
Type:              ClusterIP
IP:                10.96.0.1
Port:              https  443/TCP
TargetPort:        6443/TCP
Endpoints:         192.168.20.79:6443
Session Affinity:  None
Events:            <none>
[root@k8s-master-dev ~]#

以上顯示 cluster內部的各pods 、及其它組件訪問API server時使用 10.96.0.1; 而 kubectl 命令及外部訪問API server時使用 172.16.20.79:6443 。

訪問API server 時的認證用戶也分爲兩類:
1) serviceAccountName (cluster內部pod客戶端)
2) UserAccount (cluster外部訪問)

一、serviceAccountName
ServiceAccount(服務賬戶)是由Kubernetes API管理的用戶。它們綁定到特定的命名空間,並由API服務器自動建立或經過API調用手動建立。服務賬戶與存儲爲Secrets的一組證書相關聯,這些憑據被掛載到pod中,以便集羣進程與Kubernetes API通訊。(登陸dashboard時咱們使用的就是ServiceAccount)
當kubernetes集羣搭建好後,系統中就存在多個ServiceAccount,它們隸屬於不一樣的名稱空間,不一樣名稱空間之間的ServiceAccount名稱能夠相同。經過下面的命令查看當前系統的ServiceAccount

[root@k8s-master-dev ~]# kubectl get sa
NAME      SECRETS   AGE
default   1         5d
[root@k8s-master-dev ~]#

使用kubectl get sa --all-namespaces 查看全部名稱空間的sa 。
手工建立ServiceAccount,語法以下:
kubectl create serviceaccount my-service-account
例:

[root@k8s-master-dev ~]# kubectl create sa admin
serviceaccount/admin created
[root@k8s-master-dev ~]#  kubectl get sa
NAME      SECRETS   AGE
admin     1         23h
default   1         5d

ServiceAccount建立的同時會自動建立secrets,名稱以account的名稱爲前綴。例:

[root@k8s-master-dev ~]# kubectl get secrets
NAME                  TYPE                                  DATA      AGE
admin-token-q99pz     kubernetes.io/service-account-token   3         23h
default-token-m66jg   kubernetes.io/service-account-token   3         5d
[root@k8s-master-dev ~]#

ServiceAccount中主要用於保存token,而token又屬於 secrets 資源,以下:

[root@k8s-master-dev ~]# kubectl describe sa admin
Name:                admin
Namespace:           default
Labels:              <none>
Annotations:         <none>
Image pull secrets:  <none>
Mountable secrets:   admin-token-q99pz
Tokens:              admin-token-q99pz
Events:              <none>
[root@k8s-master-dev ~]#

可使用 kubectl describe secrets admin-token-q99pz 命令查看該token的信息。例:

[root@k8s-master-dev ~]# kubectl describe secrets/admin-token-q99pz
Name:         admin-token-q99pz
Namespace:    default
Labels:       <none>
Annotations:  kubernetes.io/service-account.name=admin
              kubernetes.io/service-account.uid=3f0f0199-4539-11e9-ac19-000c295011ce

Type:  kubernetes.io/service-account-token

Data
====
ca.crt:     1025 bytes
namespace:  7 bytes
token:      eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJ..............
[root@k8s-master-dev ~]#

每個Pod建立的時候,都會被分配到指定的ServiceAccount下面,一般是default,也能夠在編寫Pod的manifest文件的時候指定。例:

[root@k8s-master-dev ~]# vim pod-sa-demo.yaml
[root@k8s-master-dev ~]# cat pod-sa-demo.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-sa-demo
  namespace: default
  labels:
    app: myapp
    tier: frontend
  annotations:
    inspiry.com/author: "cluster admin"
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    ports:
    - name: http
      containerPort: 80
  serviceAccountName: admin
[root@k8s-master-dev ~]#  kubectl apply -f pod-sa-demo.yaml
pod/pod-sa-demo created
[root@k8s-master-dev ~]#

在Pod建立時,相關的認證文件會被以volume的形式掛載進Pod,目的是方便在Pod裏訪問API SERVER(例如kubernetes的dashboard)。例:

[root@k8s-master-dev ~]# kubectl describe pods pod-sa-demo
Name:               pod-sa-demo
Namespace:          default
Priority:           0
PriorityClassName:  <none>
Node:               k8s-node1-dev/192.168.20.78
Start Time:         Wed, 13 Mar 2019 10:41:59 +0800
Labels:             app=myapp
                    tier=frontend
Annotations:        inspiry.com/author=cluster admin
                    kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{"inspiry.com/author":"cluster admin"},"labels":{"app":"myapp","tier":"frontend"},"name":"pod..."
Status:             Running
IP:                 10.244.1.107
Containers:
  myapp:
    Container ID:   docker://729b24ee03040b09a0d93a977e65e206bd434b6c35003f0fea953b661c635af2
    Image:          ikubernetes/myapp:v1
    Image ID:       docker-pullable://ikubernetes/myapp@sha256:9c3dc30b5219788b2b8a4b065f548b922a34479577befb54b03330999d30d513
    Port:           80/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Wed, 13 Mar 2019 10:42:00 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from admin-token-q99pz (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True
Volumes:
  admin-token-q99pz:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  admin-token-q99pz
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:          <none>
[root@k8s-master-dev ~]#

二、UserAccount
是用於 k8s集羣 外部或獨立服務 管理訪問集羣使用的,由管理員分配私鑰。平時經常使用的kubectl命令就是UserAccount執行的。
kubeconfig 稱爲認證配置,就是爲集羣外部client訪問k8s集羣所做的認證配置。
外部用戶訪問k8s集羣(例使用kubectl命令)時,須要配置用戶訪問k8s集羣所用到的帳戶、證書、私鑰、集羣名、API server地址等,這些信息被存放在kubeconfig 中。
可使用kubectl config 命令對 訪問k8s集羣的認證配置文件 進行各類操做。具體可參考:kubectl config --help 。
使用kubectl config view 可查看認證配置,以下所示:

[root@k8s-master-dev ~]# kubectl config view
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: REDACTED
    server: https://192.168.20.79:6443
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: kubernetes-admin
  name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
  user:
    client-certificate-data: REDACTED
    client-key-data: REDACTED
[root@k8s-master-dev ~]#

說明:
apiVersion: v1
clusters: [] #配置要訪問的kubernetes集羣名稱列表。
contexts: [] #配置訪問kubernetes集羣的具體上下文列表。定義哪一個集羣被哪一個用戶訪問
current-context: "" #配置當前使用的上下文環境
kind: Config
preferences: {}
users: [] #配置訪問的用戶信息列表,用戶名以及證書信息 (其中REDACTED表示私密數據)

建立UserAccount所須要的訪問密鑰及證書,利用當前k8s的CA證書進行簽名

[root@k8s-master-dev ~]# cd /etc/kubernetes/pki/
[root@k8s-master-dev pki]# ls
apiserver.crt              apiserver.key                 ca.crt  front-proxy-ca.crt      front-proxy-client.key
apiserver-etcd-client.crt  apiserver-kubelet-client.crt  ca.key  front-proxy-ca.key      sa.key
apiserver-etcd-client.key  apiserver-kubelet-client.key  etcd    front-proxy-client.crt  sa.pub
[root@k8s-master-dev pki]# (umask 077; openssl genrsa -out meteor.key 2048)
Generating RSA private key, 2048 bit long modulus
.......................................................+++
.............+++
e is 65537 (0x10001)
[root@k8s-master-dev pki]# openssl req -new -key meteor.key -out meteor.csr -subj "/CN=meteor"
[root@k8s-master-dev pki]# openssl x509 -req -in meteor.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out meteor.crt -days 365
Signature ok
subject=/CN=meteor
Getting CA Private Key
[root@k8s-master-dev pki]# openssl x509 -in meteor.crt -text -noout
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number:
            b2:d2:50:2a:92:52:e0:63
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=kubernetes
        Validity
            Not Before: Mar 13 07:35:17 2019 GMT
            Not After : Mar 12 07:35:17 2020 GMT
        Subject: CN=meteor
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:d0:69:52:bd:c8:f2:43:39:3c:5e:b3:49:f7:5a:
                    29:17:1d:80:f9:b8:b1:f5:dc:1a:72:d9:96:7b:96:
                    77:bd:cc:73:ac:88:dd:be:8f:32:d5:7f:37:f7:57:
                    d8:c1:ae:bd:04:1a:5f:9f:64:8a:34:49:9b:06:96:
                    91:16:2e:1e:af:b7:9a:e0:c8:ca:1f:73:12:54:0d:
                    ff:95:c1:c0:b0:8c:e5:0c:fe:c1:20:9d:32:fb:2b:
                    09:59:7e:9b:39:17:9c:83:4f:a5:34:4a:4c:4f:e4:
                    22:ef:ee:ba:ee:80:21:49:ca:62:6c:3b:46:45:a5:
                    98:bd:37:4b:3b:b0:eb:4b:63:1a:f2:9d:1a:f9:19:
                    9d:22:43:70:83:1b:c9:a8:70:de:45:e1:9c:89:e3:
                    db:a9:41:47:83:cc:38:1e:f3:16:17:4d:91:b1:44:
                    b3:8a:ee:5f:77:aa:db:9c:de:50:c7:c2:be:9e:9d:
                    a9:ff:a6:a7:e1:0a:8d:b3:48:c5:34:e2:c3:2d:ac:
                    8c:e0:ed:fa:2c:03:7e:05:ce:df:ba:66:24:bc:4c:
                    8b:36:a1:1a:90:7b:11:3d:54:ba:22:c9:58:ce:de:
                    8a:07:3c:ca:50:df:4e:6b:e3:3b:62:77:88:99:c2:
                    a8:b5:48:f2:cd:93:20:3b:7e:46:e4:ba:ef:8d:86:
                    ac:a9
                Exponent: 65537 (0x10001)
    Signature Algorithm: sha256WithRSAEncryption
         1c:02:98:15:57:e1:60:c7:90:7f:6d:c0:d4:2c:f5:5e:33:9e:
         c1:23:48:91:9f:8d:d1:20:4c:17:8d:c6:b5:fe:09:e7:92:5f:
         7f:5a:5a:c0:13:d7:03:4e:a9:03:be:a2:09:56:90:06:ef:47:
         94:29:13:81:61:f0:c7:9b:de:c6:89:7d:c6:43:8a:9b:89:d6:
         10:b5:cb:1e:46:16:3f:89:8f:70:4a:28:33:05:84:61:d3:ed:
         88:fd:ab:63:d4:33:c8:1b:b5:bf:36:b1:84:a4:a0:24:20:ec:
         cd:35:d1:82:57:fa:09:ff:48:07:a2:04:c3:90:2b:ba:c0:f9:
         4b:ea:2e:55:45:79:f3:d9:7c:8c:e5:08:f8:0a:b2:51:3e:11:
         16:6d:e1:ec:8c:03:f0:b6:c4:a1:77:80:22:aa:48:b1:40:e5:
         61:3d:3c:9f:cf:d3:d0:3e:e3:73:46:84:96:0d:f8:3a:4e:6f:
         cf:cd:97:ea:d6:25:98:af:3e:b7:15:f1:17:30:56:be:32:a5:
         45:bb:8d:53:bb:4c:00:ef:b2:94:5f:da:da:72:f7:da:81:09:
         3e:47:15:a0:d8:ff:79:af:9c:42:8d:da:e4:44:6f:a9:38:e0:
         b4:8d:58:fb:15:7a:39:cb:87:b7:db:fe:4a:af:8e:b7:7c:fc:
         ab:77:eb:c0
[root@k8s-master-dev pki]# ls
apiserver.crt              apiserver-kubelet-client.crt  ca.srl              front-proxy-client.crt  meteor.key
apiserver-etcd-client.crt  apiserver-kubelet-client.key  etcd                front-proxy-client.key  sa.key
apiserver-etcd-client.key  ca.crt                        front-proxy-ca.crt  meteor.crt              sa.pub
apiserver.key              ca.key                        front-proxy-ca.key  meteor.csr
[root@k8s-master-dev pki]#

建立一個訪問憑證(UserAccount),並指定相應的證書及私鑰
若是指定了一個已存在的名字,將合併新字段並覆蓋舊字段

[root@k8s-master-dev pki]# kubectl config set-credentials meteor --client-certificate=meteor.crt --client-key=meteor.key --embed-certs=true
User "meteor" set.

修改kubeconfig(認證配置),建立一個新的Context及指定訪問憑據(UserAccount)

[root@k8s-master-dev pki]# kubectl config set-context meteor@kubernetes --cluster=kubernetes --user=meteor
Context "meteor@kubernetes" created.
[root@k8s-master-dev pki]# kubectl config view
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: REDACTED
    server: https://192.168.20.79:6443
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: kubernetes-admin
  name: kubernetes-admin@kubernetes
- context:                    #上下文建立成功
    cluster: kubernetes
    user: meteor
  name: meteor@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
  user:
    client-certificate-data: REDACTED
    client-key-data: REDACTED
- name: meteor
  user:                            #meteor用戶憑據(證書)成功
    client-certificate-data: REDACTED
    client-key-data: REDACTED
[root@k8s-master-dev pki]#

切換並測試新的上下文配置

[root@k8s-master-dev pki]# kubectl config use-context meteor@kubernetes
Switched to context "meteor@kubernetes".
[root@k8s-master-dev pki]# kubectl config view
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: REDACTED
    server: https://192.168.20.79:6443
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: kubernetes-admin
  name: kubernetes-admin@kubernetes
- context:
    cluster: kubernetes
    user: meteor
  name: meteor@kubernetes
current-context: meteor@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
  user:
    client-certificate-data: REDACTED
    client-key-data: REDACTED
- name: meteor
  user:
    client-certificate-data: REDACTED
    client-key-data: REDACTED
[root@k8s-master-dev pki]#

[root@k8s-master-dev pki]# kubectl get pods
No resources found.
Error from server (Forbidden): pods is forbidden: User "meteor" cannot list pods in the namespace "default"
[root@k8s-master-dev pki]#

固然也能夠在當前新定義一個集羣的認證配置(kubeconfig),例:
須要指定ca的證書、API service地址、隱藏證書選項、配置文件的路徑(不指定默認在當前家目錄),以下所示:

[root@k8s-master-dev pki]# kubectl config set-cluster mycluster --kubeconfig=/tmp/test.conf --server="https://192.168.20.79:6443" --certificate-authority=/etc/kubernetes/pki/ca.crt --embed-certs=true
Cluster "mycluster" set.
[root@k8s-master-dev pki]# kubectl config view --kubeconfig=/tmp/test.conf
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: REDACTED
    server: https://192.168.20.79:6443
  name: mycluster
contexts: []
current-context: ""
kind: Config
preferences: {}
users: []
[root@k8s-master-dev pki]# cd

4、Authorization
當認證經過,下一步要作的就是受權,受權決定一個用戶能夠幹什麼。Kubernetes能夠配置多種受權方式,其中目前使用的是RBAC(Role Based Access Control)。RBAC涉及幾個重要概念,它們是: Role/ RoleBinding / ClusterRole / ClusterRoleBinding
首先必須清楚一點:受權離不開認證,受權是基於ServiceAccount/UserAccount的。Role能夠理解爲權限(例如get,list,update,delete,add),它決定了ServiceAccount能夠幹什麼,RoleBinding用於把Role綁定到指定的ServiceAccount。
下圖是Role的綁定
Kebernetes 學習總結(9)認證-受權-RBAC
ClusterRole和ClusterRoleBinding的做用同樣,不一樣的是,它們的做用域是整個集羣,而Role和RoleBinding的做用域是namespace。
Kebernetes 學習總結(9)認證-受權-RBAC

建立角色role

[root@k8s-master-dev ~]# kubectl config use-context kubernetes-admin@kubernetes
Switched to context "kubernetes-admin@kubernetes".
[root@k8s-master-dev ~]#
[root@k8s-master-dev ~]# kubectl create role pods-reader --verb=get,list,watch --resource=pods --dry-run -o yaml > manifests/role-demo.yaml
[root@k8s-master-dev ~]# vim manifests/role-demo.yaml
[root@k8s-master-dev ~]# cat manifests/role-demo.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: pods-reader
  namespace: default
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
  - list
  - watch
[root@k8s-master-dev ~]# kubectl apply -f manifests/role-demo.yaml
role.rbac.authorization.k8s.io/pods-reader created
[root@k8s-master-dev ~]#

[root@k8s-master-dev ~]# kubectl get roles
NAME          AGE
pods-reader   14m
[root@k8s-master-dev ~]# kubectl describe roles/pods-reader
Name:         pods-reader
Labels:       <none>
Annotations:  kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"rbac.authorization.k8s.io/v1","kind":"Role","metadata":{"annotations":{},"name":"pods-reader","namespace":"default"},"rules":[{"apiGroup..."
PolicyRule:
  Resources  Non-Resource URLs  Resource Names  Verbs
  ---------  -----------------  --------------  -----
  pods       []                 []              [get list watch]
[root@k8s-master-dev ~]#

建立角色綁定rolebinding,並綁定用戶到角色

[root@k8s-master-dev ~]# kubectl create rolebinding meteor-read-pods --role=pods-reader --user=meteor --dry-run -o yaml > manifests/rolebinding-demo.yaml
[root@k8s-master-dev ~]# vim manifests/rolebinding-demo.yaml
[root@k8s-master-dev ~]# cat manifests/rolebinding-demo.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: meteor-read-pods
  namespace: default
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: pods-reader
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: meteor
[root@k8s-master-dev ~]# kubectl apply -f manifests/rolebinding-demo.yaml
rolebinding.rbac.authorization.k8s.io/meteor-read-pods created
[root@k8s-master-dev ~]# kubectl get rolebinding
NAME               AGE
meteor-read-pods   13s
[root@k8s-master-dev ~]# kubectl describe rolebinding/meteor-read-pods
Name:         meteor-read-pods
Labels:       <none>
Annotations:  kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"rbac.authorization.k8s.io/v1","kind":"RoleBinding","metadata":{"annotations":{},"name":"meteor-read-pods","namespace":"default"},"roleRe..."
Role:
  Kind:  Role
  Name:  pods-reader
Subjects:
  Kind  Name    Namespace
  ----  ----    ---------
  User  meteor
[root@k8s-master-dev ~]#

建立新用戶,測試新的配置

[root@k8s-master-dev ~]# useradd k8suser01
[root@k8s-master-dev ~]# cp -rp .kube ~k8suser01/
[root@k8s-master-dev ~]# chown -R k8suser01.k8suser01 ~k8suser01/.kube
[root@k8s-master-dev ~]# su - k8suser01
[k8suser01@k8s-master-dev ~]$ kubectl config use-context meteor@kubernetes
Switched to context "meteor@kubernetes".
[k8suser01@k8s-master-dev ~]$ kubectl get pods
NAME          READY     STATUS    RESTARTS   AGE
mongo-0       2/2       Running   0          6h
mongo-1       2/2       Running   0          6h
mongo-2       2/2       Running   0          6h
pod-sa-demo   1/1       Running   0          5h
[k8suser01@k8s-master-dev ~]$ kubectl get pods -n kube-system
No resources found.
Error from server (Forbidden): pods is forbidden: User "meteor" cannot list pods in the namespace "kube-system"
[k8suser01@k8s-master-dev ~]$ logout

因爲Role和RoleBinding的做用域namespace 爲default,因此meteor@kubernetes上下文沒法訪問kube-system 名稱空間中的資源。若是但願該上下文能夠訪問kube-system名稱空間內的資源 ,須要使用ClusterRole和ClusterRoleBinding。以下所示:

[root@k8s-master-dev ~]# kubectl get rolebinding
NAME               AGE
meteor-read-pods   4m
[root@k8s-master-dev ~]# kubectl delete rolebinding meteor-read-pods
rolebinding.rbac.authorization.k8s.io "meteor-read-pods" deleted
[root@k8s-master-dev ~]#
[root@k8s-master-dev ~]# kubectl create clusterrole cluster-reader --verb=get,list,watch --resource=pods -o yaml --dry-run > manifests/clusterRole-demo.yaml
[root@k8s-master-dev ~]# vim manifests/clusterRole-demo.yaml
[root@k8s-master-dev ~]# cat manifests/clusterRole-demo.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: cluster-reader
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
  - list
  - watch
[root@k8s-master-dev ~]# kubectl apply -f manifests/clusterRole-demo.yaml
clusterrole.rbac.authorization.k8s.io/cluster-reader created
[root@k8s-master-dev ~]# kubectl get clusterrole
NAME                                                                   AGE
admin                                                                  5d
cluster-admin                                                          5d
cluster-reader                                                         8s
edit                                                                   5d
flannel                                                                5d
......
[root@k8s-master-dev ~]# kubectl describe clusterrole cluster-reader
Name:         cluster-reader
Labels:       <none>
Annotations:  kubectl.kubernetes.io/last-applied-configuration={"apiVersion":"rbac.authorization.k8s.io/v1","kind":"ClusterRole","metadata":{"annotations":{},"name":"cluster-reader","namespace":""},"rules":[{"apiGr..."
PolicyRule:
  Resources  Non-Resource URLs  Resource Names  Verbs
  ---------  -----------------  --------------  -----
  pods       []                 []              [get list watch]
[root@k8s-master-dev ~]#
[root@k8s-master-dev ~]# kubectl create clusterrolebinding meteor-read-all-pods --clusterrole=cluster-reader --user=meteor --dry-run -o yaml >> manifests/clusterRoleBinding-demo.yaml
[root@k8s-master-dev ~]# vim manifests/clusterRoleBinding-demo.yaml
[root@k8s-master-dev ~]# cat manifests/clusterRoleBinding-demo.yaml
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: meteor-read-all-pods
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-reader
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: meteor
[root@k8s-master-dev ~]# kubectl apply -f manifests/clusterRoleBinding-demo.yaml
clusterrolebinding.rbac.authorization.k8s.io/meteor-read-all-pods created
[root@k8s-master-dev ~]# kubectl get clusterrolebinding meteor-read-all-pods
NAME                   AGE
meteor-read-all-pods   16s
[root@k8s-master-dev ~]#

再次測試meteor@kubernetes 上下文 ,以下所示:

[root@k8s-master-dev ~]# su - k8suser01
上一次登陸:三 3月 13 16:09:07 CST 2019pts/0 上
[k8suser01@k8s-master-dev ~]$ kubectl get pods
NAME          READY     STATUS    RESTARTS   AGE
mongo-0       2/2       Running   0          1d
mongo-1       2/2       Running   0          1d
mongo-2       2/2       Running   0          1d
pod-sa-demo   1/1       Running   0          1d
[k8suser01@k8s-master-dev ~]$ kubectl get pods -n kube-system
NAME                                     READY     STATUS    RESTARTS   AGE
coredns-78fcdf6894-9t2x5                 1/1       Running   0          5d
coredns-78fcdf6894-tvbtd                 1/1       Running   0          5d
etcd-k8s-master-dev                      1/1       Running   0          5d
kube-apiserver-k8s-master-dev            1/1       Running   0          5d
kube-controller-manager-k8s-master-dev   1/1       Running   1          5d
kube-flannel-ds-amd64-9tmns              1/1       Running   0          5d
kube-flannel-ds-amd64-cn8v5              1/1       Running   0          5d
kube-flannel-ds-amd64-gwf76              1/1       Running   0          5d
kube-flannel-ds-amd64-v4g6w              1/1       Running   0          5d
kube-proxy-4ks89                         1/1       Running   0          5d
kube-proxy-b47qm                         1/1       Running   0          5d
kube-proxy-dz778                         1/1       Running   0          5d
kube-proxy-mg5rr                         1/1       Running   0          5d
kube-scheduler-k8s-master-dev            1/1       Running   1          5d
[k8suser01@k8s-master-dev ~]$ logout
[root@k8s-master-dev ~]#

RoleBinding也能夠引用ClusterRole,對屬於同一命名空間內ClusterRole定義的資源主體進行受權。但ClusterRoleBinding中的角色只能是ClusterRole。以下meter用戶僅能對它所在的名稱空間進行操做。

[root@k8s-master-dev rbac]# kubectl delete -f clusterRoleBinding-demo.yaml
clusterrolebinding.rbac.authorization.k8s.io "meteor-read-all-pods" deleted
[root@k8s-master-dev rbac]# kubectl create rolebinding meteor-read-pods --clusterrole=cluster-reader --user=meteor --dry-run -o yaml > rolebinding-clusterrole-demo.yaml
[root@k8s-master-dev rbac]# vim rolebinding-clusterrole-demo.yaml
[root@k8s-master-dev rbac]# cat rolebinding-clusterrole-demo.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: meteor-read-pods
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-reader
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: meteor
[root@k8s-master-dev rbac]# kubectl apply -f rolebinding-clusterrole-demo.yaml
rolebinding.rbac.authorization.k8s.io/meteor-read-pods created
[root@k8s-master-dev rbac]# kubectl get rolebinding
NAME               AGE
meteor-read-pods   10s
[root@k8s-master-dev rbac]#
[root@k8s-master-dev rbac]# su - k8suser01
上一次登陸:四 3月 14 15:33:42 CST 2019pts/0 上
[k8suser01@k8s-master-dev ~]$ kubectl get pods
NAME          READY     STATUS    RESTARTS   AGE
mongo-0       2/2       Running   0          1d
mongo-1       2/2       Running   0          1d
mongo-2       2/2       Running   0          1d
pod-sa-demo   1/1       Running   0          1d
[k8suser01@k8s-master-dev ~]$ kubectl get pods -n kube-system
No resources found.
Error from server (Forbidden): pods is forbidden: User "meteor" cannot list pods in the namespace "kube-system"
[k8suser01@k8s-master-dev ~]$ logout
[root@k8s-master-dev rbac]#

k8s集羣內置了一些clusterRole ,能夠利用上述方法爲某個名稱空間指定特定管理員。操做以下:

kubectl create rolebinding default-ns-admin --clusterrole=admin --user=meteor
相關文章
相關標籤/搜索