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文件如下:
cat > ca-config.json <<EOF
{
"signing": {
"default": {
"expiry": "8760h"
},
"profiles": {
"kubernetes": {
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
],
"expiry": "8760h"
}
}
}
}
EOF
安装好的k8s集群,默认在ca文件在如下路径:
~ /rbac-test# ls /etc/kubernetes/pki/ca*
/etc/kubernetes/pki/ca.crt /etc/kubernetes/pki/ca.key
创建用户的证书签署请求配置json文件:
~/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的证书:
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个文件:
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部分:
# 只取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 <apiVersion: v1
clusters:
- cluster:
certificate-authority-data: [CERT DATA]
server: https://10.90.1.238:6443
name: kubernetes
EOF
2.context部分
kubectl config set-context kubernetes \
--cluster=kubernetes \
--user=opsuser \
--namespace=default \
--kubeconfig=opsuser.kubeconfig
3.user认证部分
kubectl config set-credentials opsuser \
--client-certificate=./opsuser.pem \
--client-key=./opsuser-key.pem \
--embed-certs=true \
--kubeconfig=opsuser.kubeconfig
查看最终生成的配置文件:
# 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=
最后,加载启用此配置文件
kubectl config use-context kubernetes --kubeconfig=opsuser.kubeconfig
此时,用户已经创建完成,下面开始进行RoleBinding步骤赋予权限。
RoleBinding绑定
创建Role:
~/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步骤已完成
检验
# 将此配置文件作为当前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):
~/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:
kubectl apply -f kubernetes-dashboard.yaml
浏览器访问dashboard需要token,或者kube-config文件,这里使用token,在创建好ServiceAccount且和role进行bind绑定之后,会自动创建一个名为${ServiceAccountName}-token-xxx 的Secret,其内包含token,为base64编码,可以使用kubectl describe直接查看:
:~/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
第二张截图可以发现,dashboard无多种资源类型的list权限,这是因为在上面的yaml文件中,定义的role权限是限定的:
# ------------------- 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:
~/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
创建:
~/dashboard# kubectl apply -f admin-token.yaml
查看token:
:~/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疑惑。