k8s(十四)、RBAC权限控制

前言

kubernetes 集群相关所有的交互都通过apiserver来完成,对于这样集中式管理的系统来说,权限管理尤其重要,在1.5版的时候引入了RBAC(Role Base Access Control)的权限控制机制.

RBAC也是初接触k8s的用户较难理解的一部分,同时RBAC作为集群管理的基础组件之一,本该放在最前面几篇,但是最近才想起来这个方面的知识点,赶紧梳理总结输出了本篇

工作流程

流程图

在这里插入图片描述

流程拆解

一、基于资源申明和管理方法申明组成rule规则,和Role(命名空间范围))或ClusterRole(集群范围)对象进行绑定,Role类的对象将拥有所申明资源及的指定方法的权限。
二、将Role权限落到实际用户或程序上,即RoleBinding(命名空间范围)或CLusterRoleBinding(集群范围)

有两种方式:
1.用户使用:如果是用户需求权限,则将Role与User(或Group)绑定(这需要创建User/Group);
2.程序使用:如果是程序需求权限,将Role与ServiceAccount指定(这需要创建ServiceAccount并且在deployment中指定ServiceAccount)。
相当于Role是一个类,用作权限申明,User/Group/ServiceAccount将成为类的实例

实战

一、用户使用

安装cfssl工具,生成ca-config.json文件。这一步骤在安装集群的时候已经做过,这里不再复述,参考:
k8s(一)、 1.9.0高可用集群本地离线部署记录

准备ca配置json文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
cat >  ca-config.json <<EOF
{
"signing": {
"default": {
"expiry": "8760h"
},
"profiles": {
"kubernetes": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "8760h"
}
}
}
}
EOF

安装好的k8s集群,默认在ca文件在如下路径:

1
2
/rbac-test# ls /etc/kubernetes/pki/ca*
/etc/kubernetes/pki/ca.crt /etc/kubernetes/pki/ca.key

创建用户的证书签署请求配置json文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
~/rbac-test# cat opsuser-csr.json
{
"CN": "opsuser",
"hosts": [],
"key": {
"algo": "rsa",
"size": 2048
},
"names": [
{
"C": "CN",
"ST": "BeiJing",
"L": "BeiJing",
"O": "k8s",
"OU": "System"
}
]
}

CN即comman name,后面用户证书认证时使用的用户名

生成opsuser的证书:

1
cfssl gencert -ca=/etc/kubernetes/pki/ca.crt -ca-key=/etc/kubernetes/pki/ca.key -config=./ca-config.json -profile=kubernetes ./opsuser-csr.json | cfssljson -bare opsuser

会生成下面3个文件:

1
opsuser-key.pem  opsuser.pem  opsuser.csr

生成用户的专属配置文件
完整的配置文件包含3块,分别是cluster/context/user部分,包含相应的内容,分3个步骤生成,后方详解

1.cluster部分:
生成此部分需要有集群的ca.pem文件,此文件在/etc/kubernetes/pki目录下默认没有,可以使用openssl命令基于ca.key文件去生成ca.pem文件;也可以直接使用已有的/etc/kubernetes/admin.conf文件中cluster部分:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 只取cluster的上下文
~/rbac-test# cat /etc/kubernetes/admin.conf
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: [CERT DATA]
server: https://10.90.1.238:6443
name: kubernetes

# 将cluster部分写入opsuser的配置文件内
cat > opsuser.kubeconfig <<EOF
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: [CERT DATA]
server: https://10.90.1.238:6443
name: kubernetes
EOF

2.context部分

1
2
3
4
5
kubectl config set-context kubernetes \
--cluster=kubernetes \
--user=opsuser \
--namespace=default \
--kubeconfig=opsuser.kubeconfig

3.user认证部分

1
2
3
4
5
kubectl config set-credentials opsuser \
--client-certificate=./opsuser.pem \
--client-key=./opsuser-key.pem \
--embed-certs=true \
--kubeconfig=opsuser.kubeconfig

查看最终生成的配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# cat opsuser.kubeconfig 
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: [CRET DATA]
server: https://10.90.1.238:6443
name: kubernetes
contexts:
- context:
cluster: kubernetes
namespace: default
user: opsuser
name: kubernetes
current-context: kubernetes
kind: Config
preferences: {}
users:
- name: opsuser
user:
as-user-extra: {}
client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURZekNDQWt1Z0F3SUJBZ0lVV2ZKMlNLb1NJWWhBMHFJdzRaVUZERnlWY1pzd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0ZURVRNQkVHQTFVRUF4TUthM1ZpWlhKdVpYUmxjekFlRncweE9ERXlNRFV3T0RNek1EQmFGdzB4T1RFeQpNRFV3T0RNek1EQmFNR0l4Q3pBSkJnTlZCQVlUQWtOT01SQXdEZ1lEVlFRSUV3ZENaV2xLYVc1bk1SQXdEZ1lEClZRUUhFd2RDWldsS2FXNW5NUXd3Q2dZRFZRUUtFd05yT0hNeER6QU5CZ05WQkFzVEJsTjVjM1JsYlRFUU1BNEcKQTFVRUF4TUhiM0J6ZFhObGNqQ0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQU93Wgo4d1hpdFhrOGtKNk9PSkFvUHZGaWw2ZkdKUDFWT3VyYWFqTWMyZ2ROSkV0Q3o2Mzk2eTNIZGw1T2NXdlBNNURvCjJ3a0NGKzlJd09jVzljVHhTZFZMUEg3OVEvQVhHcm9Nd2ltZk9WRUNlYm9aVkswRUx3azk1K2piRUpVVHY4eTYKMForM2JvMGtwL2p2Q2pzdmwxWUR3RGtGeGtwckZ3SXliOGt0cVBLMVFkb2ZrOE16Z3NTMnNZYTR1MWFydHd0dQozSTZZbEViUFNIOXhGbmx1UUFvbjZnSmkrM0c1YTdVRGxvRm9MSHlqL00wMStPRi9YWVpEcWgwK3hoZTlVRWdHClZBZkNSQkYyZlg2WjdCaFkybnpsblZOejV5SXhmSlpJclNIYnFhUlAxZXY1Tk1ndVNRcnl3UGQ5OG5jM201RnkKMkVXa28xeEJmQ1FXSHJKd04vMENBd0VBQWFOZU1Gd3dEZ1lEVlIwUEFRSC9CQVFEQWdXZ01CMEdBMVVkSlFRVwpNQlFHQ0NzR0FRVUZCd01CQmdnckJnRUZCUWNEQWpBTUJnTlZIUk1CQWY4RUFqQUFNQjBHQTFVZERnUVdCQlFXCmpDR2NYVjRPOTRqZlV1Mk9Kd2hqTC9xMVZEQU5CZ2txaGtpRzl3MEJBUXNGQUFPQ0FRRUFBeXdlZk5uckNKU0MKdDdrT2tHL1RUSHA1NG1tT0QxS2FPZW82TnpycFRuNVQwa0h3VEdrYmNHcWxvcDIvM1lhQXJDUHo2Q1J4VDd0QQpaTUNiOXhRZkJ0cllpeHJUdGF0TTZ4YlJuQTBqaC96Y2tvRHVuYjFEYkhxbG1JQW5jLzdaTEthQklKSnA5L0IwCjB2NnJXTEd2N0F1YmZJT1ZZVTdBVTVnZmh1LzJoWC93MzFJWlgwaXZ0WEtDR0lJb1Bya2hsL3NvUTEwdVFhUmgKeFFBdzhUbTc0dTBJTDE3OFFsRlhSYm1JQXpuWk42Skh1YW5QZE82TVI1Z0dobVMzRDRaUDg2RE5DenZCOVZFcQpWa0w4R0E2bHJHNm1sem5MN0pxODlQajdOdElwZnRaeDBsdTBYRmsxTm9DWk9VMFl5Yk9peWlPS2N0NVNia3VKClVLUjVYMC9GTUE9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcFFJQkFBS0NBUUVBN0JuekJlSzFlVHlRbm80NGtDZys4V0tYcDhZay9WVTY2dHBxTXh6YUIwMGtTMExQCnJmM3JMY2QyWGs1eGE4OHprT2piQ1FJWDcwakE1eGIxeFBGSjFVczhmdjFEOEJjYXVnekNLWjg1VVFKNXVobFUKclFRdkNUM242TnNRbFJPL3pMclJuN2R1alNTbitPOEtPeStYVmdQQU9RWEdTbXNYQWpKdnlTMm84clZCMmgrVAp3ek9DeExheGhyaTdWcXUzQzI3Y2pwaVVSczlJZjNFV2VXNUFDaWZxQW1MN2NibHJ0UU9XZ1dnc2ZLUDh6VFg0CjRYOWRoa09xSFQ3R0Y3MVFTQVpVQjhKRUVYWjlmcG5zR0ZqYWZPV2RVM1BuSWpGOGxraXRJZHVwcEUvVjYvazAKeUM1SkN2TEE5MzN5ZHplYmtYTFlSYVNqWEVGOEpCWWVzbkEzL1FJREFRQUJBb0lCQVFEQ0F6amUxME5FMHU0TQpQTlppTDVBNWowa01CeGtTUzkxVWJCTGsyWXFZZ1YyWHN0a3lJdndFN0dscWFZOXVoaC9icmwxL2M0YnpqSmRuCnprZzdoQU9tRUdNdi96SzZzbUcyRFJIb1hmMGRncWxBc2R3UktPVDE5VGNDOURFV0w5cG1oQVlKOXhRVFM5SDAKRDRvYXhLclpkYytaakJNN3gvQnFUOFBvVDJzTHRTN1FuTjhpNGNpTjVSeTl1TUsrOFZJcitPUVJqNWlVSHpDLwoyWXRBT0daYlJHekhZaXR1a2xtZG45RmhYV1NreGFBY0p0RkdWcGlMS2FWdjdoYVZsZm40SUJaSkZrdkJNQkxCClR4N2JCb25MYkF1K2Ezd0ZzYzlMd1NTNUJXK296eUZJYlJoWVV0SmhTdmZLUjZxTVJFMHRMV2IwUFJoRDVjZEUKenR5dWRoWEpBb0dCQVBYanVOYXA1TGNSSnUwaDhvVWxLTE9SZ1psYXFKSlpCUThrQ3A4ZTBJNXNpdFlxMEZlRwpOMnJibGdPV0RKSW5TR0pCc0I2VzFhOHI2S1F5L3dlcG9wTHJSQUE1VFo2YVMzMDBQeEgyY1paUE1aMHJpTmVXCnpLZGdIalczM0FORWtGQm5nVlA3Y3M2UENXSVlkajhyRElDUGowbWhkZEhWckd4elNycXNwWFczQW9HQkFQWFAKTWZjcEVQdVA1dGNvS0tnSXF5ZzVrNzRlZ0J0M2JUT2NHR05TellDeGV0bjJseHJWRW1nMktlOWNrMElGT0hFaAovUnFqNnJtY1VNV0JnRWExS0pNajlCRW56NWo4S2pGN3l2Z3o5ZDJPNHVkTlMyeG50R2MrZVJ1T0NpU0JNejRhCkFVZ2xSdGRJZXhkeWdoVWJsNVhMaitTeFRYVXRmWDgzZENMZEZCL3JBb0dCQUlsOU5LeHJRT1VRSlNqeEUyOVoKa01HZmVjenJBVmtiaDVXb3ZIdXV1a1Q0OGtUQW1kQm16dlBrSnFTSXNTekQ1RmgwakdyK1FpdDVyTktyWlNpKwp0SlhjRVNEaTZjRG1XNUY5dGtwdjk2RnBWTCtpU1JqclRESEdyLzJ2ZWNrbC9GL0pFR3FLTGU3TDBoNVV1VUdtCjY0MnpPQmFldm9kL0o3TllZQSt6VzYxUEFvR0JBUEFWQU01UTg5OWdlNnlsOHArOFo3K1FEUGRpUHVtVXlibmcKdWdrNHRMTC9wZWdCYXpDdjc1eU5Xb1FKUFdMOFNsWmxSaHFoQXY5cTU1RWduVE55ZVVETm12S3VtWnJvb0NWWQpyYk9pdkg4N3NlOE1sYUE1NGYvOUNyaVpFTnI2dmh2bnRseksyOWdsV09SYjJTWFluME9WWU9PVE1QNUVBaEVoCkRuT0d6c01sQW9HQUtrSXJ3Z2Y5dnVubnBTeGJCMU9UeCtUR2pkUEN3RThDUWNxWTBBeUhXZnk2eTBNaTNTSXMKTXBKZmpmbXN3NlRDSHZ1VFUvOXBkL3dYWEZ6ZU03OHBwWU5wcHZBVjQzVEVQNTdHRXZRV3VBSkNFQklvekZhdQpXZWVrRGd6bzBCc3NCMFFOUnRnUS9HdTBnaDRCWjFMdDB4QmJmWHhrMjRMTmJpSFBHTHRQL3pjPQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=

最后,加载启用此配置文件

1
kubectl config use-context kubernetes --kubeconfig=opsuser.kubeconfig

此时,用户已经创建完成,下面开始进行RoleBinding步骤赋予权限。

RoleBinding绑定
创建Role:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
~/rbac-test# cat pod-reader.yaml 
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: kube-system
name: pod-reader
rules:
- apiGroups: [""] # ""代表核心api组
resources: ["pods"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

~/rbac-test# cat opsuser-role-bind.yaml
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: read-pods
namespace: kube-system
subjects:
- kind: User
name: opsuser # 目标用户
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader # 角色信息
apiGroup: rbac.authorization.k8s.io

kubectl apply -f pod-reader.yaml
kubectl apply -f opsuser-role-bind.yaml

RoleBinding步骤已完成
检验

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 将此配置文件作为当前kubectl配置文件使用
~/rbac-test# mv /root/.kube/config /root/.kube/config.bak
~/rbac-test# cp opsuser.kubeconfig /root/.kube/config

# 查看资源
:~/rbac-test# kubectl get pods
NAME READY STATUS RESTARTS AGE
appdev-5c4b65bbbb-t4lvr 1/1 Running 2 44d
deptest13dev-fb79d9957-d55vb 0/1 Pending 0 35d
deptest13test-8687769d58-lzm2r 0/1 Pending 0 41d
deptest14dbtm-ffbd5c56c-ph68l 0/2 Pending 0 41d
deptest14test-7cb7bf6cc-xnrxw 0/1 Pending 0 41d

:~/rbac-test# kubectl get nodes
Error from server (Forbidden): nodes is forbidden: User "opsuser" cannot list nodes at the cluster scope

可以看到,基于生成的用户配置文件,已经可以管理申明的pod资源,无法管理申明以外的资源类型。测试成功

二、程序使用

与用户使用User不同的是,程序的权限赋予是通过ServiceAccount来作为权限载体的,因此,首先要拥有程序/deployment/ServiceAccount等资源,这里以前面文章里没有讲的kube dashboard为例进行说明。

首先我们来看官方最新版本的kube dashboard的yaml文件(服务暴露方式稍作修改成了NodePort):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
~/dashboard# cat kubernetes-dashboard.yaml
# ------------------- Dashboard Secret ------------------- #

apiVersion: v1
kind: Secret
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard-certs
namespace: kube-system
type: Opaque

---
# ------------------- Dashboard Service Account ------------------- #

apiVersion: v1
kind: ServiceAccount
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kube-system

---
# ------------------- Dashboard Role & Role Binding ------------------- #

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: kubernetes-dashboard-minimal
namespace: kube-system
rules:
# Allow Dashboard to create 'kubernetes-dashboard-key-holder' secret.
- apiGroups: [""]
resources: ["secrets"]
verbs: ["create"]
# Allow Dashboard to create 'kubernetes-dashboard-settings' config map.
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["create"]
# Allow Dashboard to get, update and delete Dashboard exclusive secrets.
- apiGroups: [""]
resources: ["secrets"]
resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs"]
verbs: ["get", "update", "delete"]
# Allow Dashboard to get and update 'kubernetes-dashboard-settings' config map.
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["kubernetes-dashboard-settings"]
verbs: ["get", "update"]
# Allow Dashboard to get metrics from heapster.
- apiGroups: [""]
resources: ["services"]
resourceNames: ["heapster"]
verbs: ["proxy"]
- apiGroups: [""]
resources: ["services/proxy"]
resourceNames: ["heapster", "http:heapster:", "https:heapster:"]
verbs: ["get"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: kubernetes-dashboard-minimal
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: kubernetes-dashboard-minimal
subjects:
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kube-system

---
# ------------------- Dashboard Deployment ------------------- #

kind: Deployment
apiVersion: apps/v1beta2
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kube-system
spec:
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
k8s-app: kubernetes-dashboard
template:
metadata:
labels:
k8s-app: kubernetes-dashboard
spec:
containers:
- name: kubernetes-dashboard
image: k8s.gcr.io/kubernetes-dashboard-amd64:v1.10.0
ports:
- containerPort: 8443
protocol: TCP
args:
- --auto-generate-certificates
# Uncomment the following line to manually specify Kubernetes API server Host
# If not specified, Dashboard will attempt to auto discover the API server and connect
# to it. Uncomment only if the default does not work.
# - --apiserver-host=http://my-address:port
volumeMounts:
- name: kubernetes-dashboard-certs
mountPath: /certs
# Create on-disk volume to store exec logs
- mountPath: /tmp
name: tmp-volume
livenessProbe:
httpGet:
scheme: HTTPS
path: /
port: 8443
initialDelaySeconds: 30
timeoutSeconds: 30
volumes:
- name: kubernetes-dashboard-certs
secret:
secretName: kubernetes-dashboard-certs
- name: tmp-volume
emptyDir: {}
serviceAccountName: kubernetes-dashboard
# Comment the following tolerations if Dashboard must not be deployed on master
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule

---
# ------------------- Dashboard Service ------------------- #

kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kube-system
spec:
type: NodePort
ports:
- port: 443
targetPort: 8443
nodePort: 30001
selector:
k8s-app: kubernetes-dashboard
:~/dashboard# ls
admin-token.yaml kubernetes-dashboard.yaml
:~/dashboard# vim kubernetes-dashboard.yaml
:~/dashboard# cat kubernetes-dashboard.yaml
# Copyright 2017 The Kubernetes Authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# ------------------- Dashboard Secret ------------------- #

apiVersion: v1
kind: Secret
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard-certs
namespace: kube-system
type: Opaque

---
# ------------------- Dashboard Service Account ------------------- #

apiVersion: v1
kind: ServiceAccount
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kube-system

---
# ------------------- Dashboard Role & Role Binding ------------------- #

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: kubernetes-dashboard-minimal
namespace: kube-system
rules:
# Allow Dashboard to create 'kubernetes-dashboard-key-holder' secret.
- apiGroups: [""]
resources: ["secrets"]
verbs: ["create"]
# Allow Dashboard to create 'kubernetes-dashboard-settings' config map.
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["create"]
# Allow Dashboard to get, update and delete Dashboard exclusive secrets.
- apiGroups: [""]
resources: ["secrets"]
resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs"]
verbs: ["get", "update", "delete"]
# Allow Dashboard to get and update 'kubernetes-dashboard-settings' config map.
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["kubernetes-dashboard-settings"]
verbs: ["get", "update"]
# Allow Dashboard to get metrics from heapster.
- apiGroups: [""]
resources: ["services"]
resourceNames: ["heapster"]
verbs: ["proxy"]
- apiGroups: [""]
resources: ["services/proxy"]
resourceNames: ["heapster", "http:heapster:", "https:heapster:"]
verbs: ["get"]

---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: kubernetes-dashboard-minimal
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: kubernetes-dashboard-minimal
subjects:
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kube-system

---
# ------------------- Dashboard Deployment ------------------- #

kind: Deployment
apiVersion: apps/v1beta2
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kube-system
spec:
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
k8s-app: kubernetes-dashboard
template:
metadata:
labels:
k8s-app: kubernetes-dashboard
spec:
containers:
- name: kubernetes-dashboard
image: k8s.gcr.io/kubernetes-dashboard-amd64:v1.10.0
ports:
- containerPort: 8443
protocol: TCP
args:
- --auto-generate-certificates
# Uncomment the following line to manually specify Kubernetes API server Host
# If not specified, Dashboard will attempt to auto discover the API server and connect
# to it. Uncomment only if the default does not work.
# - --apiserver-host=http://my-address:port
volumeMounts:
- name: kubernetes-dashboard-certs
mountPath: /certs
# Create on-disk volume to store exec logs
- mountPath: /tmp
name: tmp-volume
livenessProbe:
httpGet:
scheme: HTTPS
path: /
port: 8443
initialDelaySeconds: 30
timeoutSeconds: 30
volumes:
- name: kubernetes-dashboard-certs
secret:
secretName: kubernetes-dashboard-certs
- name: tmp-volume
emptyDir: {}
serviceAccountName: kubernetes-dashboard
# Comment the following tolerations if Dashboard must not be deployed on master
tolerations:
- key: node-role.kubernetes.io/master
effect: NoSchedule

---
# ------------------- Dashboard Service ------------------- #

kind: Service
apiVersion: v1
metadata:
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kube-system
spec:
type: NodePort
ports:
- port: 443
targetPort: 8443
nodePort: 30001
selector:
k8s-app: kubernetes-dashboard

部署dashboard:

1
kubectl apply -f kubernetes-dashboard.yaml

浏览器访问dashboard需要token,或者kube-config文件,这里使用token,在创建好ServiceAccount且和role进行bind绑定之后,会自动创建一个名为${ServiceAccountName}-token-xxx 的Secret,其内包含token,为base64编码,可以使用kubectl describe直接查看:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
:~/dashboard# kubectl get secret -o wide -n kube-system | grep kubernetes-dashboard
istio.kubernetes-dashboard istio.io/key-and-cert 3 2d
kubernetes-dashboard-certs Opaque 0 2d
kubernetes-dashboard-key-holder Opaque 2 2d
kubernetes-dashboard-token-t2mmr kubernetes.io/service-account-token 3 2d


:~/dashboard# kubectl describe secret -n kube-system kubernetes-dashboard-token-t2mmr
Name: kubernetes-dashboard-token-t2mmr
Namespace: kube-system
Labels: <none>
Annotations: kubernetes.io/service-account.name=kubernetes-dashboard
kubernetes.io/service-account.uid=4f237c6c-f7ad-11e8-9859-0050569da8f2

Type: kubernetes.io/service-account-token

Data
====
ca.crt: 1025 bytes
namespace: 11 bytes
token: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJrdWJlcm5ldGVzLWRhc2hib2FyZC10b2tlbi10Mm1tciIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjRmMjM3YzZjLWY3YWQtMTFlOC05ODU5LTAwNTA1NjlkYThmMiIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDprdWJlLXN5c3RlbTprdWJlcm5ldGVzLWRhc2hib2FyZCJ9.UEJ0MBO9RhSF_fzZHPKezWqkZsWG3atFQQgoPGlyyIDXtQN-ZYlZPEScjunwp4FVgX5uRMpxHGyexJN5e8zYouMTRrGaDaIu7cGj5ICP80iabi8wyMCnJrR5_p0Tmy2PkNZDCyh0MbDCJE6lbOv7Lu7CldivEMtr4BAvxvMmBdmoT0CixQexfw2tioeeoYBwEKgxjL6mMBIGKE0spGZQova7bzTN8f2ZGpNn8jFI_EW9Y7Et5sitw3rCRwxxMSDwUwwCOv26NXPnPVA7cWJeuzPRTS0BHE0euRYojQN7F77NkfwCynx8iWGpM2MEuHIj6coCUcTuCyN5yMD1Zag2zg

使用此token登录dashboard:
在这里插入图片描述

在这里插入图片描述

第二张截图可以发现,dashboard无多种资源类型的list权限,这是因为在上面的yaml文件中,定义的role权限是限定的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# ------------------- Dashboard Role & Role Binding ------------------- #

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: kubernetes-dashboard-minimal
namespace: kube-system
rules:
# Allow Dashboard to create 'kubernetes-dashboard-key-holder' secret.
- apiGroups: [""]
resources: ["secrets"]
verbs: ["create"]
# Allow Dashboard to create 'kubernetes-dashboard-settings' config map.
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["create"]
# Allow Dashboard to get, update and delete Dashboard exclusive secrets.
- apiGroups: [""]
resources: ["secrets"]
resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs"]
verbs: ["get", "update", "delete"]
# Allow Dashboard to get and update 'kubernetes-dashboard-settings' config map.
- apiGroups: [""]
resources: ["configmaps"]
resourceNames: ["kubernetes-dashboard-settings"]
verbs: ["get", "update"]
# Allow Dashboard to get metrics from heapster.
- apiGroups: [""]
resources: ["services"]
resourceNames: ["heapster"]
verbs: ["proxy"]
- apiGroups: [""]
resources: ["services/proxy"]
resourceNames: ["heapster", "http:heapster:", "https:heapster:"]
verbs: ["get"]

可以修改这里的Role内部的权限,也可以自行配置更高级的权限,我这里为了方便,直接配置了一个admin的ServiceAccount:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
~/dashboard# cat admin-token.yaml

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: admin
annotations:
rbac.authorization.kubernetes.io/autoupdate: "true"
roleRef:
kind: ClusterRole # ClusterRole拥有集群级别权限,于此同时绑定时不能再使用RoleBinding而应该使用ClusterRoleBinding
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
name: admin
namespace: kube-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin
namespace: kube-system
labels:
kubernetes.io/cluster-service: "true"
addonmanager.kubernetes.io/mode: Reconcile

创建:

1
~/dashboard# kubectl apply -f admin-token.yaml

查看token:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
:~/dashboard# kubectl get secret -n kube-system | grep admin
admin-token-b9r26 kubernetes.io/service-account-token 3 1d

~/dashboard# kubectl describe secret -n kube-system admin-token-b9r26
Name: admin-token-b9r26
Namespace: kube-system
Labels: <none>
Annotations: kubernetes.io/service-account.name=admin
kubernetes.io/service-account.uid=d471a78c-f833-11e8-9859-0050569da8f2

Type: kubernetes.io/service-account-token

Data
====
ca.crt: 1025 bytes
namespace: 11 bytes
token: eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJhZG1pbi10b2tlbi1iOXIyNiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJhZG1pbiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6ImQ0NzFhNzhjLWY4MzMtMTFlOC05ODU5LTAwNTA1NjlkYThmMiIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDprdWJlLXN5c3RlbTphZG1pbiJ9.euwxJkmtt7mjbpzHdMzJWmxO0swuVRjYFGkEwzX1E6caXrUj1XXrSQO4J3mttJvMOVQaGEztInI-cKMiTDzLYHE_85VISHbZTUA8dcSFDIuGOt4SRI_XoA11pIlUAmH4b_4kxgaA3DA5TdUX6O2mo93QEvLOOngBkLO55Z9y980H_J5JiBgbndnycOGXVIW-gEgEjBewtiH1ZCiha-lwUlTvSNJkLrTPlm5Rjoao8lONn4vcD1sgzrSrW8VMxxclw8Cu3C79zyujHo0F_YuwHteIlBwOPSTaiokbuyQr-IS2UTpwUxlzf__wXgidc_SXqTC9vecM7hcRVhEi_d_hnw

dashboard退出之前的账号,使用admin-token重新登录,可以发现已经拥有全部权限:
在这里插入图片描述

总结

k8s角色授权使用的流程有多个环节多种资源类型搭配完成,权限粒度明确、用户与进程分工有序,理解了顶部的流程图,相信你将不再为RBAC疑惑。

赏一瓶快乐回宅水吧~
-------------本文结束感谢您的阅读-------------