Fork me on GitHub
Fork me on GitHub

Kubernetes dashboard认证及分级授权

dashboard

Kubernetes的子项目之一,是Kubernetes核心附件之一。作为Kubernetes的Web用户界面,用户可以通过Dashboard在Kubernetes集群中部署容器化的应用,对应用进行问题处理和管理,并对集群本身进行管理。通过Dashboard,用户可以查看集群中应用的运行情况,同时也能够基于Dashboard创建或修改部署、任务、服务等Kubernetes的资源。通过部署向导,用户能够对部署进行扩缩容,进行滚动更新、重启Pod和部署新应用。在Kubernetes 1.8之后,在部署dashboard时,有着更复杂的权限检查了。传统的在互联网上看到的开放访问的方式不一定支持了。

安装部署dashboard

打开 dashboard github地址

我这里把这个yaml文件下载下来,这样可以看看里面的内容,然后进行安装。

1
2
3
4
5
6
7
8
9
10
11
[root@spark32 manifests]# mkdir dashboard
[root@spark32 manifests]# cd dashboard/
[root@spark32 dashboard]# ls
[root@spark32 dashboard]# wget https://raw.githubusercontent.com/kubernetes/dashboard/v1.10.1/src/deploy/recommended/kubernetes-dashboard.yaml
[root@spark32 dashboard]# kubectl apply -f kubernetes-dashboard.yaml
secret/kubernetes-dashboard-certs created
serviceaccount/kubernetes-dashboard created
role.rbac.authorization.k8s.io/kubernetes-dashboard-minimal created
rolebinding.rbac.authorization.k8s.io/kubernetes-dashboard-minimal created
deployment.apps/kubernetes-dashboard created
service/kubernetes-dashboard created

如果dashboard镜像拉取不下来,可以如下操作:

1
2
[root@spark32 dashboard]# docker pull mirrorgooglecontainers/kubernetes-dashboard-amd64:v1.10.1
[root@spark32 dashboard]# docker tag mirrorgooglecontainers/kubernetes-dashboard-amd64:v1.10.1 k8s.gcr.io/kubernetes-dashboard-amd64:v1.10.1

dashboard自身是https的,可以查看yaml中定义的Service:

并且这个Service的类型是默认的cluserIP类型的,可以改为NodePort类型的:

1
2
3
4
5
6
7
8
9
10
[root@spark32 dashboard]# kubectl get svc -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 156d
kubernetes-dashboard ClusterIP 10.108.56.150 <none> 443/TCP 73s
[root@spark32 dashboard]# kubectl patch svc kubernetes-dashboard -p '{"spec":{"type":"NodePort"}}' -n kube-system
service/kubernetes-dashboard patched
[root@spark32 dashboard]# kubectl get svc -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 156d
kubernetes-dashboard NodePort 10.108.56.150 <none> 443:30763/TCP 4m3s

浏览器输入:https://172.16.206.32:30763

  • 令牌认证可以直接输入令牌。
  • Kubeconfig:kubectl就能使用kubeconfig,但是注意认证时必须使用serviceaccount账号认证。dashboard自己是个Pod,我们所提供的信息是让dashboard Pod认证到k8s集群上去的。不是让我们自己认证,是让dashboard Pod认证k8s,因为我们是通过这个Pod去访问管理集群上的Pod的。因此我们是为dashboard这个pod提供一个kubeconfig,所以主体必须是一个serviceaccount。

token认证

token认证也需要先定义一个serviceaccount。

1
2
[root@spark32 dashboard]# kubectl create serviceaccount dashboard-admin -n kube-system
serviceaccount/dashboard-admin created

接下来需要通过RoleBinding把dashboard-admin这个serviceaccount和集群管理员绑定起来。不然这个serviceaccount不能通过RBAC的检查。dashboard部署完后,登录进来期望借助于dashboard做什么事情,假如要做整个集群的管理,也就是说该serviceaccount应该具有整个集群的访问权限,那么就应该通过ClusterRoleBinding把这个serviceaccount和cluster-admin角色绑定在一起。

1
2
[root@spark32 dashboard]# kubectl create clusterrolebinding dashboard-cluster-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin
clusterrolebinding.rbac.authorization.k8s.io/dashboard-cluster-admin created

绑定完成后,我们去获取对应的serviceaccount的secret信息。并且通过这个secret就可以访问集群了。

1
2
3
4
5
[root@spark32 dashboard]# kubectl get secret -n kube-system
NAME TYPE DATA AGE
...
dashboard-admin-token-9sbkc kubernetes.io/service-account-token 3 98s
...

这个 dashboard-admin-token-9sbkc 是上面创建serviceaccount时自动生成的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@spark32 dashboard]# kubectl describe secret dashboard-admin-token-9sbkc -n kube-system
Name: dashboard-admin-token-9sbkc
Namespace: kube-system
Labels: <none>
Annotations: kubernetes.io/service-account.name: dashboard-admin
kubernetes.io/service-account.uid: 1531c9c1-d84c-11e9-9e1c-60a44c223099
Type: kubernetes.io/service-account-token
Data
====
ca.crt: 1025 bytes
namespace: 11 bytes
token: eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJkYXNoYm9hcmQtYWRtaW4tdG9rZW4tOXNia2MiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGFzaGJvYXJkLWFkbWluIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZXJ2aWNlLWFjY291bnQudWlkIjoiMTUzMWM5YzEtZDg0Yy0xMWU5LTllMWMtNjBhNDRjMjIzMDk5Iiwic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Omt1YmUtc3lzdGVtOmRhc2hib2FyZC1hZG1pbiJ9.P4EXyMjsqbWEVu5aDD0LYhBteFIpvlj1AxNIH2eNAweqQyzeePqSmAUVQ825wUItIlhD0H-OLgoxuQOozYy-XNxonH-ixhe5S3o5uhAOzgxIydPAxZqle9b-SKjJHtnWPh48RMy1uVtAk7zTwXftvCjr8QNSWUDN60CKjoaOGLLuo1UPh2UQBuC5KcMg_FkROvXmiBoaw-EjECq_gV6_6f3FnveJGj0pSFITXXayux9tv3lRFjQiE7-wd-0OKfOlNnEPDkkrrSzaLbg5536AL_mdjI3ZjuA93ybavtH_so40K19TXy6sOTQwT38nArGdWikcZra-g8HYTN4CVYFYxA

这个token信息就是当前 dashboard-admin 这个serviceaccount的认证令牌。

在浏览器dashboard的登录界面,选择”令牌”,然后将上面的token信息复制上去,点击”登录”。



登录进来了,可以查看所有的名称空间。

Kubeconfig认证

这里创建个权限小一点的,只让它对默认名称空间有权限的管理员。还得在创建个serviceaccount。仅能够通过dashboard访问default一个名称空间,不让他做分级管理。所以需要把这个serviceaccount绑定在admin上,admin也是ClusterRole。但是可以使用RoleBinding去绑定。

1
2
3
4
[root@spark32 dashboard]# kubectl create sa def-ns-admin
serviceaccount/def-ns-admin created
[root@spark32 dashboard]# kubectl create rolebinding def-ns-admin --clusterrole=admin --serviceaccount=default:def-ns-admin
rolebinding.rbac.authorization.k8s.io/def-ns-admin created

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[root@spark32 dashboard]# kubectl get secret
NAME TYPE DATA AGE
admin-token-th7zd kubernetes.io/service-account-token 3 4d3h
def-ns-admin-token-b9s8n kubernetes.io/service-account-token 3 100s
default-token-wb7fl kubernetes.io/service-account-token 3 156d
mysql-root-passwd Opaque 1 18d
tomcat-ingress-secret kubernetes.io/tls 2 25d
[root@spark32 dashboard]# kubectl describe secret def-ns-admin-token-b9s8n
Name: def-ns-admin-token-b9s8n
Namespace: default
Labels: <none>
Annotations: kubernetes.io/service-account.name: def-ns-admin
kubernetes.io/service-account.uid: e1497fb6-d84d-11e9-9e1c-60a44c223099
Type: kubernetes.io/service-account-token
Data
====
ca.crt: 1025 bytes
namespace: 7 bytes
token: eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImRlZi1ucy1hZG1pbi10b2tlbi1iOXM4biIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJkZWYtbnMtYWRtaW4iLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJlMTQ5N2ZiNi1kODRkLTExZTktOWUxYy02MGE0NGMyMjMwOTkiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZGVmYXVsdDpkZWYtbnMtYWRtaW4ifQ.MaWQQSVdVzC67wHFqbFRaAEoC_KBtijs9lmcfV1GbUboJ3k-BswmWmHozSnREY1G2kpFWrnR3gETuodDLujeE4hUyix8vLh473iQ5TciP7Uw0FTdxKXqMkn9a_pb_dz5RUQn3tt2JGqd_v44nXRjgUuUnJIifyUv23U7iwmSN4riREhfYLvrNBbTBNIApaahn-9REWePXNllH93MLJSpGsbzpvDQcVCbUhgVxHUWsfAeNa9xAqOoUqJqbfe7QivKFXoEntU1BwTNOTl8j7YwQt_JQt2LpMkFg7R-T1CuZzohePas8tNmNfrEDGSavamQ56SDtlW7HVeGiM2IANX2eQ

使用这个token去登录dashboard,只能管理default名称空间的资源。

但是我们希望使用装载一个kubeconfig配置文件来认证,所以接下来不得不为这个serviceaccount创建一个配置文件。配置文件和之前kubectl配置文件基本一致。注意去设置的时候要放上面看到的token,不要放证书进去,证书只是为了做k8s系统认证的。

1
2
[root@spark32 dashboard]# kubectl config set-cluster kubernetes --certificate-authority=/etc/kubernetes/pki/ca.crt --server="https://172.16.206.32:6443" --embed-certs=true --kubeconfig=/root/def-ns-admin.conf
Cluster "kubernetes" set.

需要把 token 写到kubeconfig中。使用token进行认证。注意在设置认证token时不要把加密后的token设置进去,直接写入上面看到的那个token。

1
2
3
4
5
6
7
[root@spark32 dashboard]# kubectl config set-cluster kubernetes --certificate-authority=/etc/kubernetes/pki/ca.crt --server="https://172.16.206.32:6443" --embed-certs=true --kubeconfig=/root/def-ns-admin.conf
Cluster "kubernetes" set.
[root@spark32 dashboard]# kubectl config set-credentials def-ns-admin --token="ZXlKaGJHY2lPaUpTVXpJMU5pSXNJbXRwWkNJNklpSjkuZXlKcGMzTWlPaUpyZFdKbGNtNWxkR1Z6TDNObGNuWnBZMlZoWTJOdmRXNTBJaXdpYTNWaVpYSnVaWFJsY3k1cGJ5OXpaWEoyYVdObFlXTmpiM1Z1ZEM5dVlXMWxjM0JoWTJVaU9pSmtaV1poZFd4MElpd2lhM1ZpWlhKdVpYUmxjeTVwYnk5elpYSjJhV05sWVdOamIzVnVkQzl6WldOeVpYUXVibUZ0WlNJNkltUmxaaTF1Y3kxaFpHMXBiaTEwYjJ0bGJpMWlPWE00YmlJc0ltdDFZbVZ5Ym1WMFpYTXVhVzh2YzJWeWRtbGpaV0ZqWTI5MWJuUXZjMlZ5ZG1salpTMWhZMk52ZFc1MExtNWhiV1VpT2lKa1pXWXRibk10WVdSdGFXNGlMQ0pyZFdKbGNtNWxkR1Z6TG1sdkwzTmxjblpwWTJWaFkyTnZkVzUwTDNObGNuWnBZMlV0WVdOamIzVnVkQzUxYVdRaU9pSmxNVFE1TjJaaU5pMWtPRFJrTFRFeFpUa3RPV1V4WXkwMk1HRTBOR015TWpNd09Ua2lMQ0p6ZFdJaU9pSnplWE4wWlcwNmMyVnlkbWxqWldGalkyOTFiblE2WkdWbVlYVnNkRHBrWldZdGJuTXRZV1J0YVc0aWZRLk1hV1FRU1ZkVnpDNjd3SEZxYkZSYUFFb0NfS0J0aWpzOWxtY2ZWMUdiVWJvSjNrLUJzd21XbUhvelNuUkVZMUcya3BGV3JuUjNnRVR1b2RETHVqZUU0aFV5aXg4dkxoNDczaVE1VGNpUDdVdzBGVGR4S1hxTWtuOWFfcGJfZHo1UlVRbjN0dDJKR3FkX3Y0NG5YUmpnVXVVbkpJaWZ5VXYyM1U3aXdtU040cmlSRWhmWUx2ck5CYlRCTklBcGFhaG4tOVJFV2VQWE5sbEg5M01MSlNwR3NienB2RFFjVkNiVWhnVnhIVVdzZkFlTmE5eEFxT29VcUpxYmZlN1FpdktGWG9FbnRVMUJ3VE5PVGw4ajdZd1F0X0pRdDJMcE1rRmc3Ui1UMUN1WnpvaGVQYXM4dE5tTmZyRURHU2F2YW1RNTZTRHRsVzdIVmVHaU0ySUFOWDJlUQ==" --kubeconfig=/root/def-ns-admin.conf
[root@spark32 dashboard]# kubectl config set-context def-ns-admin@kubernetes --cluster=kubernetes --user=def-ns-admin --kubeconfig=/root/def-ns-admin.conf
Context "def-ns-admin@kubernetes" created.
[root@spark32 dashboard]# kubectl config use-context def-ns-admin@kubernetes --kubeconfig=/root/def-ns-admin.conf
Switched to context "def-ns-admin@kubernetes".

查看生成的配置文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@spark32 ~]# kubectl config view --kubeconfig=/root/def-ns-admin.conf
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://172.16.206.32:6443
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: def-ns-admin
name: def-ns-admin@kubernetes
current-context: def-ns-admin@kubernetes
kind: Config
preferences: {}
users:
- name: def-ns-admin
user:
token: eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImRlZi1ucy1hZG1pbi10b2tlbi1iOXM4biIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50Lm5hbWUiOiJkZWYtbnMtYWRtaW4iLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC51aWQiOiJlMTQ5N2ZiNi1kODRkLTExZTktOWUxYy02MGE0NGMyMjMwOTkiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZGVmYXVsdDpkZWYtbnMtYWRtaW4ifQ.MaWQQSVdVzC67wHFqbFRaAEoC_KBtijs9lmcfV1GbUboJ3k-BswmWmHozSnREY1G2kpFWrnR3gETuodDLujeE4hUyix8vLh473iQ5TciP7Uw0FTdxKXqMkn9a_pb_dz5RUQn3tt2JGqd_v44nXRjgUuUnJIifyUv23U7iwmSN4riREhfYLvrNBbTBNIApaahn-9REWePXNllH93MLJSpGsbzpvDQcVCbUhgVxHUWsfAeNa9xAqOoUqJqbfe7QivKFXoEntU1BwTNOTl8j7YwQt_JQt2LpMkFg7R-T1CuZzohePas8tNmNfrEDGSavamQ56SDtlW7HVeGiM2IANX2eQ

将配置文件传到自己本地,然后在dashboard界面选择kubeconfig认证,使用该配置文件认证:

以后可以使用dashboard来管理资源了,比如创建资源:

【总结】:
认证时的账号必须为ServiceAccount: 被dashboard pod拿来由kubernetes进行认证;
token认证:
(1)创建ServiceAccount,根据其管理目标,使用rolebinding或clusterrolebinding绑定至合理role或
clusterrole;
(2)获取到此ServiceAccount的secret, 这个secret是创建serviceaccount自动生成的。作为此serviceaccount去k8s认证的信息。查看secret的详细信息, 其中就有token;

kubeconfig认证: 把ServiceAccount的token封装为kubeconfig文件
(1)创建ServiceAccount,根据其管理目标,使用rolebinding或clusterrolebinding绑定至合理role或clusterrole;
(2)kubectl get secret | awk ‘/^ServiceAccount/{print $1}’ ##这里的ServiceAccount指的是你创建的serviceaccount的名字
KUBE_TOKEN=$(kubectl get secret SERVCIEACCOUNT_SERRET_NAME -o jsonpath={.data.token} | base64 -d)
(3)生成kubeconfig文件

1
2
3
4
kubectl config set-cluster --kubeconfig=/PATH/TO/SOMEFILE
kubectl config set-credentials NAME --token=$KUBE_TOKEN --kubeconfig=/PATH/TO/SOMEFILE #这里的NAME只是个自定义的名字,认证时k8s识别的此名字是你第一步创建的serviceaccount。
kubectl config set-context
kubectl config use-context