k8s之RBAC授權模式

導讀

上一篇說了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