RBAC
在互聯(lián)網(wǎng)級別的大規(guī)模集群中芳肌,Kubernetes內(nèi)置的編排對象,很難做到滿足所有需求味咳。所以庇勃,很多實(shí)際的容器化工作,都會要求你設(shè)計(jì)一個自己的編排對象槽驶,事先自己的控制器模式责嚷。在Kubernetes中,我們可以通過CRD機(jī)制來完成這種工作掂铐,但是罕拂,在Kubernetes里新增和操作API對象,就必須了解RBAC全陨。Kubernetes中所有的API對象都是保存在etcd中爆班,對這些API對象的操作都是通過訪問api-server實(shí)現(xiàn)的。你需要API Server來幫助你做授權(quán)操作辱姨。
在Kubernetes中柿菩,負(fù)責(zé)完成授權(quán)工作的機(jī)制,就是RBAC:基于角色的訪問控制雨涛。
RBAC中的三個基本概念:
- Role:角色枢舶,就是一組規(guī)則懦胞,定義了一組對Kubernetes API對象的操作權(quán)限
- Subject:被作用者,既可以是人凉泄,也可以是機(jī)器躏尉,也可以是你在Kubernetes中定義的用戶
- RoleBinding:定義了“被作用者”和“角色”的綁定關(guān)系
Role
Role本身就是一個Kubernetes的API對象,定義如下:
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: mynamespace
name: example-role
rules:
- apiGroups: [""]
resources: ["pod"]
verbs: ["get","watch","list"]
這個Role對象指定了它能產(chǎn)生作用的Namespace是mynamespace
rules字段就是它所定義的規(guī)則后众,上面的例子中胀糜,就是允許被作用者對mynamespace下的Pod對象,進(jìn)行Get蒂誉、WATCH和LIST操作
RoleBinding
RoleBinding本身也是一個Kubernetes的API對象教藻,定義如下:
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: example-rolebinding
namespace: mynamespace
subjects:
- kind: User
name: example-user
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: example-role
apiGroup: rbac.authorization.k8s.io
RoleBinding對象可以直接通過名字,來引用前面定義的Role對象拗盒,從而定義了被作用者和角色之間的關(guān)系
RoleBinding和Role對象都是Namespaced對象怖竭,它們對權(quán)限的限制規(guī)則僅在它們自己的Namespace內(nèi)有效,roleRef也只能引用當(dāng)前Namespace里的Role對象
ClusterRole和ClusterRoleBinding
對于非Namespaced對象(比如Node)或者一個Role想作用于所有的Namespace的時候陡蝇,我們可以使用ClusterRole和ClusterRoleBinding做授權(quán)。這兩個API對象的用法跟Role和RoleBinding完全相同哮肚,只不過沒有了namespace字段
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: example-cluster
rule:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get","watch","list"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: cluster-rolebinding
subjects:
- kind: User
name: example-user
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: example-clusterrole
apiGroup: rbac.authorization.k8s.io
上面的例子中ClusterRole和ClusterRoleBinding的組合登夫,意味著名叫example-role的用戶,擁有對所有Namespace的Pod進(jìn)行g(shù)et允趟、watch恼策、list操作的權(quán)限。
如果在Role或者ClusterRole中潮剪,如果要賦予用戶example-user所有權(quán)限涣楷,那可以給它指定一個verbs字段的全集
verbs: ["get","watch","list","update","create","patch","delete"]
ServiceAccount
在大多數(shù)時候,我們都不太使用“用戶”這個功能抗碰,而是使用Kubernetes里的“內(nèi)置用戶”
首先狮斗,我們定義一個ServiceAccount。
apiVersion: v1
kind: ServiceAccount
metadata:
namespace: mynamespace
name: example-sa
然后我們通過Role和RoleBinding的YAML文件弧蝇,為這個ServiceAccount分配權(quán)限:
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: example-role
namespace: mynamespace
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get","watch","list"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: example-rolebinding
namespace: mynamespace
subjects:
- kind: ServiceAccount
name: example-sa
namespace: mynamespace
roleRef:
kind: Role
name: example-role
apiGroup: rbac.authorization.k8s.io
操作演示
我們先創(chuàng)建上面三個對象
[root@host1 rbac]# kubectl create namespace mynamespace
namespace/mynamespace created
[root@host1 rbac]# kubectl get namespace
NAME STATUS AGE
default Active 2d19h
kube-public Active 2d19h
kube-system Active 2d19h
mynamespace Active 5s
rook-ceph Active 42h
[root@host1 rbac]# kubectl create -f svc-account.yaml
serviceaccount/example-sa created
[root@host1 rbac]# kubectl create -f role-binding.yaml
role.rbac.authorization.k8s.io/example-role created
rolebinding.rbac.authorization.k8s.io/example-rolebinding created
然后碳褒,我們查看一下這個ServiceAccount的詳細(xì)信息
[root@host1 rbac]# kubectl get sa -n mynamespace -o yaml
apiVersion: v1
items:
- apiVersion: v1
kind: ServiceAccount
metadata:
creationTimestamp: "2019-10-25T02:15:24Z"
name: default
namespace: mynamespace
resourceVersion: "474819"
selfLink: /api/v1/namespaces/mynamespace/serviceaccounts/default
uid: 4da5a943-f6cd-11e9-928f-000c296c79f3
secrets:
- name: default-token-ncwxl
- apiVersion: v1
kind: ServiceAccount
metadata:
creationTimestamp: "2019-10-25T02:15:46Z"
name: example-sa
namespace: mynamespace
resourceVersion: "474876"
selfLink: /api/v1/namespaces/mynamespace/serviceaccounts/example-sa
uid: 5aeef1d2-f6cd-11e9-928f-000c296c79f3
secrets:
- name: example-sa-token-vg2sk
kind: List
metadata:
resourceVersion: ""
selfLink: ""
Kubernetes會為每一個ServiceAccount自動創(chuàng)建并分配一個Secret對象,即Secrets字段
這個Secret看疗,就是這個ServiceAccount用來和API Server進(jìn)行交互的授權(quán)文件沙峻,我們稱它為:ServiceAccount Token.
這時候,用戶的Pod两芳,就可以聲明使用這個ServiceAccount了摔寨,比如下面這個例子:
apiVersion: v1
kind: Pod
metadata:
namespace: mynamespace
name: sa-token-test
spec:
containers:
- name: nginx
image: nginx:1.7.9
serviceAcccountName: example-sa
在Pod中,我們指定了ServiceAccountName為example-sa
這個Pod運(yùn)行起來之后怖辆,該ServiceAccount的token就會被自動掛載到容器的/var/run/secrets/kubernetes.io/serviceaccount目錄下是复。
如果一個Pod沒有聲明ServiceAccountName沉填,Kubernetes會自動在它的Namespace下創(chuàng)建一個名叫default的默認(rèn)ServiceAccount,然后分配給這個Pod佑笋。這個默認(rèn)的ServiceAccount沒有關(guān)聯(lián)任何Role翼闹。也就是說,此時它有訪問API Server的絕大多數(shù)權(quán)限蒋纬。
Kubernetes中的用戶組
除了前面使用的“用戶”猎荠,Kubernetes還有用戶組的概念,也就是一組用戶的意思蜀备。如果你為Kubernetes配置了外部認(rèn)證服務(wù)的話关摇,這個用戶組的概念由外部認(rèn)證服務(wù)提供。
但是對于Kubernetes內(nèi)置用戶ServiceAccount來說碾阁,上述用戶組也同樣使用输虱。
實(shí)際上,一個ServiceAccount脂凶,在Kubernetes里對應(yīng)的“用戶”名字是:
system:serviceaccount:<ServiceAccount Name>
而它對應(yīng)的內(nèi)置“用戶組”的名字就是:
system:serviceaccounts:<Namespace Name>
比如宪睹,我們可以在RoleBinding定義如下的subjects:
subjects:
- kind: Group
name: system:serviceaccounts:mynamespace
apiGroup: rbac.authorization.k8s.io
這就意味著這個Role的權(quán)限規(guī)則,作用于mynamespace里的所有ServiceAccount蚕钦。
再比如下面的例子
subjects:
- kind: Group
name: system:serviceaccounts
apiGroup: rbac.authorization.k8s.io
這意味著這個Role的權(quán)限規(guī)則亭病,作用于整個系統(tǒng)里的所有ServiceAccount
Kubernetes提供了四個預(yù)先定義好的ClusterRole來供用戶直接使用:
- cluster-admin(Kubernetes中的最高權(quán)限)
- admin
- edit
- view