k8s之RBAC授權模式
2021-01-13 22:30:10 軟體

導讀

上一篇說了k8s的授權管理,這一篇就來詳細看一下RBAC授權模式的使用

RBAC授權模式

基於角色的存取控制,啟用此模式,需要在API Server的啟動引數上新增如下設定,(k8s默然採用此授權模式)。

--authorization-mode=RBAC

  

 

/etc/kubernetes/manifests/kube-apiserver.yaml

  

(1)對叢集中的資源及非資源許可權均有完整的覆蓋

(2)整個RBAC完全由幾個API物件完成,同其他API物件一樣,可以用kubelet或API進行操作。

(3)可在執行時進行調整,無須重啟API Server

1 RBAC資源物件說明

RBAC有四個資源物件,分別是Role、ClusterRole、RoleBinding、ClusterRoleBinding

1.1 Role:角色

一組許可權的集合,在一個名稱空間中,可以用其來定義一個角色,只能對名稱空間內的資源進行授權。如果是叢集級別的資源,則需要使用ClusterRole。例如:定義一個角色用來讀取Pod的許可權

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: rbac
  name: pod-read
rules:
- apiGroups: [""]
  resources: ["pods"]
  resourceNames: []
  verbs: ["get","watch","list"]

  

rules中的引數說明:

1、apiGroups:支援的API組列表,例如:"apiVersion: batch/v1"等

2、resources:支援的資源物件列表,例如pods、deplayments、jobs等

3、resourceNames: 指定resource的名稱

3、verbs:對資源物件的操作方法列表。

建立後檢視:

 

1.2 ClusterRole:叢集角色

具有和角色一致的名稱空間資源的管理能力,還可用於以下特殊元素的授權

1、叢集範圍的資源,例如Node

2、非資源型的路徑,例如:/healthz

3、包含全部名稱空間的資源,例如Pods

例如:定義一個叢集角色可讓使用者存取任意secrets

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: secrets-clusterrole
rules:
- apiGroups: [""]
  resources: ["secrets"]
  verbs: ["get","watch","list"]

  

1.3 RoleBinding:角色系結,ClusterRoleBinding:叢集角色系結

角色系結和叢集角色系結用於把一個角色系結在一個目標上,可以是User,Group,Service Account,使用RoleBinding為某個名稱空間授權,使用ClusterRoleBinding為叢集範圍內授權。

例如:將在rbac名稱空間中把pod-read角色授予使用者es

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: pod-read-bind
  namespace: rbac
subjects:
- kind: User
  name: es
  apiGroup: rbac.authorization.k8s.io
roleRef:
- kind: Role
  name: pod-read
  apiGroup: rbac.authorizatioin.k8s.io

  

建立之後切換到es使用者,看能否檢視相應Pod的資源

 

RoleBinding也可以參照ClusterRole,對屬於同一名稱空間內的ClusterRole定義的資源主體進行授權, 例如:es能獲取到叢集中所有的資源資訊

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: es-allresource
  namespace: rbac
subjects:
- kind: User
  name: es
  apiGroup: rbac.authorization.k8s.io
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin 

  

建立之後檢視:

 

叢集角色系結的角色只能是叢集角色,用於進行叢集級別或對所有名稱空間都生效的授權

例如:允許manager組的使用者讀取所有namaspace的secrets

apiVersion: rabc.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: read-secret-global
subjects:
- kind: Group
  name: manager
  apiGroup: rabc.authorization.k8s.io
ruleRef:
- kind: ClusterRole
  name: secret-read
  apiGroup: rabc.authorization.k8s.io

  

2 資源的參照方式

多數資源可以用其名稱的字串表示,也就是Endpoint中的URL相對路徑,例如pod中的紀錄檔是GET /api/v1/namaspaces/{namespace}/pods/{podname}/log

如果需要在一個RBAC物件中體現上下級資源,就需要使用「/」分割資源和下級資源。

例如:若想授權讓某個主體同時能夠讀取Pod和Pod log,則可以設定 resources為一個陣列

apiVersion: rabc.authorization.k8s.io/v1
kind: Role
metadata: 
  name: logs-reader
  namespace: default
rules:
- apiGroups: [""]
  resources: ["pods","pods/log"]
  verbs: ["get","list"]

  

資源還可以通過名稱(ResourceName)進行參照,在指定ResourceName後,使用get、delete、update、patch請求,就會被限制在這個資源範例範圍內

例如,下面的宣告讓一個主體只能對名為my-configmap的ConFigmap進行get和update操作:

apiVersion: rabc.authorization.k8s.io/v1
kind: Role
metadata:
  namaspace: default
  name: configmap-update
rules:
- apiGroups: [""]
  resources: ["configmap"]
  resourceNames: ["my-configmap"]
  verbs: ["get","update"]

  

3 常見角色範例

(1)允許讀取核心API組的Pod資源

rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get","list","watch"]

  

(2)允許讀寫extensions和apps兩個API組中的deployment資源

rules:
- apiGroups: ["extensions","apps"]
  resources: ["deployments"]
  verbs: ["get","list","watch","create","update","patch","delete"]

  

(3)允許讀取Pod以及讀寫job資訊

rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get","list","watch"]、
- apiVersion: ["batch","extensions"]
  resources: ["jobs"]
  verbs: ["get","list","watch","create","update","patch","delete"]

  

(4)允許讀取一個名為my-config的ConfigMap(必須繫結到一個RoleBinding來限制到一個Namespace下的ConfigMap):

rules:
- apiGroups: [""]
  resources: ["configmap"]
  resourceNames: ["my-configmap"]
  verbs: ["get"]

  

(5)讀取核心組的Node資源(Node屬於叢集級的資源,所以必須存在於ClusterRole中,並使用ClusterRoleBinding進行繫結):

rules:
- apiGroups: [""]
  resources: ["nodes"]
  verbs: ["get","list","watch"]

  

(6)允許對非資源端點「/healthz」及其所有子路徑進行GET和POST操作(必須使用ClusterRole和ClusterRoleBinding):

rules:
- nonResourceURLs: ["/healthz","/healthz/*"]
  verbs: ["get","post"]

  

4 常見的角色系結範例

(1)使用者名稱alice

subjects:
- kind: User
  name: alice
  apiGroup: rbac.authorization.k8s.io

  

(2)組名alice

subjects:
- kind: Group
  name: alice
  apiGroup: rbac.authorization.k8s.io

  

(3)kube-system名稱空間中預設Service Account

subjects:
- kind: ServiceAccount
  name: default
  namespace: kube-system

  

(4)qa名稱空間中的所有Service Account:

subjects:
- kind: Group
  name: systeml:serviceaccounts:qa
  apiGroup: rbac.authorization.k8s.io

  

(5)所有Service Account

subjects:
- kind: Group
  name: system:serviceaccounts
  apiGroup: rbac.authorization.k8s.io

  

(6)所有認證使用者

subjects:
- kind: Group
  name: system:authenticated
  apiGroup: rbac.authorization.k8s.io

  

(7)所有未認證使用者

subjects:
- kind: Group
  name: system:unauthenticated
  apiGroup: rbac.authorization.k8s.io

  

(8)全部使用者

subjects:
- kind: Group
  name: system:authenticated
  apiGroup: rbac.authorization.k8s.io
- kind: Group
  name: system:unauthenticated
  apiGroup: rbac.authorization.k8s.io

  

5 預設的角色和角色系結

API Server會建立一套預設的ClusterRole和ClusterRoleBinding物件,其中很多是以「system:」為字首的,以表明這些資源屬於基礎架構,對這些物件的改動可能造成叢集故障。所有預設的ClusterRole和RoleBinding都會用標籤kubernetes.io/boostrapping=rbac-default進行標記。

6 對Service Account的授權管理

Service Account也是一種賬號,是給執行在Pod裡的程序提供了必要的身份證明。需要在Pod定義中指明參照的Service Account,這樣就可以對Pod的進行賦權操作。例如:pod內可獲取rbac名稱空間的所有Pod資源,pod-reader-sc的Service Account是繫結了名為pod-read的Role

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  namespace: rbac
spec:
  serviceAccountName: pod-reader-sc
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 80

  

預設的RBAC策略為控制平臺元件、節點和控制器授予有限範圍的許可權,但是除kube-system外的Service Account是沒有任何許可權的。

(1)為一個應用專屬的Service Account賦權

此應用需要在Pod的spec中指定一個serviceAccountName,用於API、Application Manifest、kubectl create serviceaccount等建立Service Account的命令。

例如為my-namespace中的my-sa Service Account授予唯讀許可權

kubectl create rolebinding my-sa-view --clusterrole=view --serviceaccount=my-namespace:my-sa --namespace=my-namespace

  

(2)為一個名稱空間中名為default的Service Account授權

如果一個應用沒有指定 serviceAccountName,則會使用名為default的Service Account。注意,賦予Service Account 「default」的許可權會讓所有沒有指定serviceAccountName的Pod都具有這些許可權

例如,在my-namespace名稱空間中為Service Account「default」授予唯讀許可權:

kubectl create rolebinding default-view --clusterrole=view --serviceaccount=my-namespace:default --namespace=my-namespace

  

另外,許多系統級Add-Ons都需要在kube-system名稱空間中執行,要讓這些Add-Ons能夠使用超級使用者許可權,則可以把cluster-admin許可權賦予kube-system名稱空間中名為default的Service Account,這一操 作意味著kube-system名稱空間包含了通向API超級使用者的捷徑。

kubectl create clusterrolebinding add-ons-add-admin --clusterrole=cluster-admin --serviceaccount=kube-system:default

  

(3)為名稱空間中所有Service Account都授予一個角色

如果希望在一個名稱空間中,任何Service Account應用都具有一個角色,則可以為這一名稱空間的Service Account群組進行授權

kubectl create rolebinding serviceaccounts-view --clusterrole=view --group=system:serviceaccounts:my-namespace --namespace=my-namespace

  

(4)為叢集範圍內所有Service Account都授予一個低許可權角色

如果不想為每個名稱空間管理授權,則可以把一個叢集級別的角色賦給所有Service Account。

kubectl create clusterrolebinding serviceaccounts-view --clusterrole=view --group=system:serviceaccounts

  

(5)為所有Service Account授予超級使用者許可權

kubectl create clusterrolebinding serviceaccounts-view --clusterrole=cluster-admin --group=system:serviceaccounts

  

7 使用kubectl命令列工具建立資源物件

(1)在名稱空間rbac中為使用者es授權admin ClusterRole:

kubectl create rolebinding bob-admin-binding --clusterrole=admin --user=es --namespace=rbac

  

(2)在名稱空間rbac中為名為myapp的Service Account授予view ClusterRole:

kubctl create rolebinding myapp-role-binding --clusterrole=view --serviceaccount=acme:myapp --namespace=rbac

  

(3)在全叢集範圍內為使用者root授予cluster-admin ClusterRole:

kubectl create clusterrolebinding cluster-binding --clusterrole=cluster-admin --user=root

  

(4)在全叢集範圍內為名為myapp的Service Account授予view ClusterRole:

kubectl create clusterrolebinding service-account-binding --clusterrole=view --serviceaccount=acme:myapp