K8s集羣RBAC認證授權詳解

1 什麼是RBAC

RBAC(Role-Based Access Control) 基於角色的訪問控制,顧名思義就是通過給角色賦予相應的權限,從而使得該角色具有訪問相關資源的權限,而在K8s中這些資源分屬於兩個級別,名稱空間(role/rolebinding)和集羣級別(clusterrole/clusterrolebinding)這兩個都是標準的K8s資源,可以直接定義。
k8s集羣有兩類認證時的Account:useraccount(管理者、訪問者)、serviceaccount(pod)。這些Account就是下文中我們提到的User,這兩種User面向的對象不同。
RBAC
如上圖所示,在不同名稱空間中,我們需要有一個Role,此Role定義了User訪問此名稱空間的權限,如GET、WATCH、LIST等,通過RoleBinding,使得Role和User進行關聯,從而授權User具有相關資源的訪問權限,這樣就是一個Role/RoleBinding。但是剛纔說的只是針對當前名稱空間的綁定授權,那如果一個Role想要具有訪問整個集羣的權限,這個時候就需要使用到ClusterRoleClusterRoleBinding了。
示例說明:

  • 上圖User1如果通過ClusterRoleBingClusterRole進行了綁定,那麼User1就具有了集羣所有的訪問權限
  • 如果User1通過RoleBingding綁定到了ClusterRole,那麼User1還是隻有其所屬名稱空間的權限
  • 那如果我們集羣有10個名稱空間,正常情況下我們需要給每個名稱空間都配置一個Role,即我們需要創建10個Role,然後再RoleBinding,操作複雜;此時如果我們定義了一個ClusterRole,那麼可以直接讓RoleBinding去綁定ClusterRole,這樣我們就不用再創建10個Role的複雜流程但是可以實現我們想要的功能。

2 RBAC認證授權

RBAC綁定流程

  1. 定義一個角色role
    operations(對哪個對象進行操作)許可授權,只能允許
    objects
  2. 定義用戶賬號或者服務賬號,綁定(rolebinding
    user account or service account(讓這個用戶)
    role(綁定到這個角色)

2.1 創建Account

2.1.1 創建ServiceAccount(sa)

[root@master1 ~]# kubectl create serviceaccount rsq --dry-run	(幹跑)
serviceaccount/rsq created (dry run)
[root@master1 ~]# kubectl create serviceaccount rsq -o yaml --dry-run   (生成一個框架)
apiVersion: v1
kind: ServiceAccount
metadata:
  creationTimestamp: null
  name: rsq

# 如果我們想要導出一個pod的yaml,有個簡化參數 --export
[root@master1 ~]# kubectl get pods pod-cm-3 -o yaml --export

# 創建一個admin的sa
[root@master1 ~]# kubectl create serviceaccount admin
serviceaccount/admin created
[root@master1 ~]# kubectl get sa
NAME      SECRETS   AGE
admin     1         1s
default   1         44d
[root@master1 ~]# kubectl describe sa admin
Name:                admin
Namespace:           default
Labels:              <none>
Annotations:         <none>
Image pull secrets:  <none>
Mountable secrets:   admin-token-bwrbg
Tokens:              admin-token-bwrbg
Events:              <none>
[root@master1 ~]# kubectl get secret
NAME                    TYPE                                  DATA   AGE
admin-token-bwrbg       kubernetes.io/service-account-token   3      35s

創建一個pod使用此sa

[root@master1 manifests]# vim pod-sa-demo.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-sa-demo
  namespace: default
  labels:
    app: sa-myapp
    tier: frontend
  annotations:
    rsq.com/created-by: "cluster admin"
spec:
  containers:
  - name: myapp
    image: nginx:1.14-alpine
    ports:
    - name: http
      containerPort: 80
  serviceAccountName: admin
[root@master1 manifests]# kubectl apply -f pod-sa-demo.yaml
pod/pod-sa-demo created
[root@master1 manifests]# kubectl describe pod pod-sa-demo
......  #就會使用admin的token
Volumes:
  admin-token-bwrbg:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  admin-token-bwrbg
    Optional:    false
......

2.1.2 創建UserAccount並自簽證書

自籤CA證書

[root@master1 ~]# cd /etc/kubernetes/pki/
[root@master1 pki]# (umask 077; openssl genrsa -out rsq.key 2048)
[root@master1 pki]# openssl req -new -key rsq.key -out rsq.csr -subj "/CN=rsq"
[root@master1 pki]# openssl x509 -req -in rsq.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out rsq.crt -days 9999 
Signature ok
subject=/CN=rsq
Getting CA Private Key

# 輸出證書信息
[root@master1 pki]# openssl x509 -in rsq.crt -text -noout

創建rsq的UserAccount,使用set-credentials寫入kubeconfig中

[root@master1 pki]# kubectl config set-credentials rsq --client-certificate=./rsq.crt --client-key=./rsq.key --embed-certs=true
User "rsq" set.
[root@master1 pki]# kubectl config view
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://10.0.0.100: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
- name: rsq
  user:
    client-certificate-data: REDACTED
    client-key-data: REDACTED

爲rsq配置上下文context

[root@master1 pki]# kubectl config set-context rsq@kubernetes --cluster=kubernetes --user=rsq
Context "rsq@kubernetes" created.
[root@master1 pki]# kubectl config view
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://10.0.0.100:6443
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: kubernetes-admin
  name: kubernetes-admin@kubernetes
- context:   # 生成 rsq上下文環境
    cluster: kubernetes
    user: rsq
  name: rsq@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
  user:
    client-certificate-data: REDACTED
    client-key-data: REDACTED
- name: rsq
  user:
    client-certificate-data: REDACTED
    client-key-data: REDACTED

切換集羣上下文

[root@master1 pki]# kubectl config use-context rsq@kubernetes
Switched to context "rsq@kubernetes".

# 執行get命令會發現沒有權限去訪問,因爲rsq@kubernetes沒有授權
[root@master1 pki]# kubectl get pods
Error from server (Forbidden): pods is forbidden: User "rsq" cannot list resource "pods" in API group "" in the namespace "default"

# 切換爲默認的集羣環境
[root@master1 pki]# kubectl config use-context kubernetes-admin@kubernetes
Switched to context "kubernetes-admin@kubernetes".

創建新Cluster

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

2.2 RBAC認證授權

2.2.1 Role/RoleBinding

1、創建一個只對pod有查看的role

# 1、創建Role
[root@master01 ~]# kubectl create role pods-reader --verb=get,list,watch --resource=pods --dry-run
role.rbac.authorization.k8s.io/pods-reader created (dry run)
[root@master01 ~]# kubectl create role pods-reader --verb=get,list,watch --resource=pods --dry-run -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  creationTimestamp: null
  name: pods-reader
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
  - list
  - watch
[root@master01 rbac]# kubectl apply -f role-demo.yaml
role.rbac.authorization.k8s.io/pods-reader created
[root@master01 rbac]# kubectl get role
NAME          AGE
pods-reader   4s
[root@master01 rbac]# kubectl describe role 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...
PolicyRule:
  Resources  Non-Resource URLs  Resource Names  Verbs
  ---------  -----------------  --------------  -----
  pods       []                 []              [get list watch]

2、創建RoleBinding,綁定我們 2.2.2 目錄中創建的rsq用戶

[root@master01 rbac]# kubectl create rolebinding rsq-read-pods --role=pods-reader --user=rsq
rolebinding.rbac.authorization.k8s.io/rsq-read-pods created
[root@master01 rbac]# kubectl get rolebinding
NAME            AGE
rsq-read-pods   6s
[root@master01 rbac]# kubectl create rolebinding rsq-read-pods --role=pods-reader --user=rsq --dry-run -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  creationTimestamp: null
  name: rsq-read-pods
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: pods-reader
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: rsq

3、追加輸出RoleBinding到文件中保存至yaml文件

[root@master01 rbac]# kubectl create rolebinding rsq-read-pods --role=pods-reader --user=rsq --dry-run -o yaml > rolebinding-demo.yaml

4、切換rsq@kubernetes上下文來測試

[root@master01 rbac]# kubectl config use-context rsq@kubernetes
Switched to context "rsq@kubernetes".
[root@master01 rbac]# kubectl get pods
NAME                             READY   STATUS    RESTARTS   AGE
myapp-0                          1/1     Running   0          4h52m
myapp-1                          1/1     Running   0          4h40m
pod-cm-1                         1/1     Running   0          5h7m
pod-cm-3                         1/1     Running   0          5h3m
pod-sa-demo                      1/1     Running   0          3h28m
tomcat-deploy-67c46fdf58-9qggk   1/1     Running   0          21h
tomcat-deploy-67c46fdf58-qxggk   1/1     Running   0          21h
tomcat-deploy-67c46fdf58-vgcdf   1/1     Running   0          21h
web-0                            1/1     Running   0          26h
web-1                            1/1     Running   0          26h
web-2                            1/1     Running   0          26h

# 但是隻能對default名稱空間生效
[root@master01 rbac]# kubectl get pods -n kube-system
Error from server (Forbidden): pods is forbidden: User "rsq" cannot list resource "pods" in API group "" in the namespace "kube-system"

2.2.2 ClusterRole/RoleBinding

1、創建ClusterRole

[root@master01 rbac]# kubectl create clusterrole cluster-reader --verb=get,list,watch --resource=pods -o yaml --dry-run > clusterrole-demo.yaml
[root@master01 rbac]# vim clusterrole-demo.yaml
[root@master01 rbac]# cat clusterrole-demo.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: cluster-reader
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
  - list
  - watch
[root@master01 rbac]# 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"},"rules":[{"apiGrou...
PolicyRule:
  Resources  Non-Resource URLs  Resource Names  Verbs
  ---------  -----------------  --------------  -----
  pods       []                 []              [get list watch]

2、把之前的rolebinding去掉,把User rsq綁定到ClusterRole中看效果

[root@master01 rbac]# kubectl delete rolebinding rsq-read-pods
[root@master01 rbac]# kubectl create clusterrolebinding rsq-read-all-pods --clusterrole=cluster-reader --user=rsq --dry-run -o yaml > clusterrolebinding-demo.yaml
[root@master01 rbac]# cat clusterrolebinding-demo.yaml
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  creationTimestamp: null
  name: rsq-read-all-pods
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-reader
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: rsq
[root@master01 rbac]# kubectl get clusterrolebinding rsq-read-all-pods
NAME                AGE
rsq-read-all-pods   24s
[root@master01 rbac]# kubectl describe clusterrolebinding rsq-read-all-pods
Name:         rsq-read-all-pods
Labels:       <none>
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"rbac.authorization.k8s.io/v1beta1","kind":"ClusterRoleBinding","metadata":{"annotations":{},"creationTimestamp":null,"name"...
Role:
  Kind:  ClusterRole
  Name:  cluster-reader
Subjects:
  Kind  Name  Namespace
  ----  ----  ---------
  User  rsq   

# 切換rsq@kubernetes看效果
[root@master01 rbac]# kubectl get pods
NAME                             READY   STATUS    RESTARTS   AGE
myapp-0                          1/1     Running   0          5h13m
myapp-1                          1/1     Running   0          5h1m
pod-cm-1                         1/1     Running   0          5h28m
pod-cm-3                         1/1     Running   0          5h23m
pod-sa-demo                      1/1     Running   0          3h49m
tomcat-deploy-67c46fdf58-9qggk   1/1     Running   0          21h
tomcat-deploy-67c46fdf58-qxggk   1/1     Running   0          21h
tomcat-deploy-67c46fdf58-vgcdf   1/1     Running   0          21h
web-0                            1/1     Running   0          26h
web-1                            1/1     Running   0          26h
web-2                            1/1     Running   0          26h
[root@master01 rbac]# kubectl get pods -n kube-system
NAME                               READY   STATUS                 RESTARTS   AGE
coredns-6955765f44-7nsk4           1/1     Running                6          139d
coredns-6955765f44-sr67c           1/1     Running                7          139d
etcd-master01                      1/1     Running                11         139d
etcd-master02                      1/1     Running                3897       139d
# 但是隻具有讀權限

3、把RoleBinding綁定到ClusterRole中

# 先刪掉之前的clusterrolebinding
[root@master01 rbac]# kubectl delete -f clusterrolebinding-demo.yaml

# 使得rolebinding綁定clusterrole
[root@master01 rbac]# kubectl create rolebinding rsq-read-pods --clusterrole=cluster-reader --user=rsq --dry-run -o yaml > rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  creationTimestamp: null
  name: rsq-read-pods
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-reader
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: rsq
[root@master01 rbac]# kubectl apply -f rolebinding.yaml

# 切換rsq用戶看效果,會發現還是隻能訪問default名稱空間下的資源
[root@master01 rbac]# kubectl config use-context rsq@kubernetes
Switched to context "rsq@kubernetes".
[root@master01 rbac]# kubectl get pods
NAME                             READY   STATUS    RESTARTS   AGE
myapp-0                          1/1     Running   0          5h24m
myapp-1                          1/1     Running   0          5h12m
pod-cm-1                         1/1     Running   0          5h39m
pod-cm-3                         1/1     Running   0          5h34m
pod-sa-demo                      1/1     Running   0          4h
tomcat-deploy-67c46fdf58-9qggk   1/1     Running   0          21h
tomcat-deploy-67c46fdf58-qxggk   1/1     Running   0          21h
tomcat-deploy-67c46fdf58-vgcdf   1/1     Running   0          21h
web-0                            1/1     Running   0          26h
web-1                            1/1     Running   0          26h
web-2                            1/1     Running   0          26h
[root@master01 rbac]# kubectl get pods -n kube-system
Error from server (Forbidden): pods is forbidden: User "rsq" cannot list resource "pods" in API group "" in the namespace "kube-system"

4、查看集羣admin clusterrole擁有的權限

[root@master01 rbac]# kubectl get clusterrole admin -o yaml
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章