k8s部署dashboard与踩坑

1 简介

使用kube-dashboard来完成日常的一些k8s集群运维工作。

Dashboard是Kubernetes社区官方开发的仪表板,有了仪表板后管理者就能够透过 Web-based 方式来管理 Kubernetes 集群,除了提升管理方便,也让资源可视化,让人更直觉看见系统信息的呈现结果。

下面我们就来看如何基于部署kube-dashboard。

2 安装kube-dashboard组件

在安装之前,先通过删除namespace来清除之前版本的内容,通过命令

kubectl delete ns kubernetes-dashboard

下载yaml文件,使用目前最新的v2.0.0-beta2版本,很好的适应k8s-1.15.0版本。 需要修改两处地方: * 修改镜像地址 sed命令中第一个匹配 * 默认配置文件中ClusterRole为kubernetes-dashboard权限过低,修改成cluster-admin sed命令中第二个匹配,上一行满足替换下一行的模式。 为何更改,下文将详细介绍。

#官网下载yaml
curl -o dashboard-v2.0.0-beta2.yaml https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.0-beta2/aio/deploy/recommended.yaml
#更改镜像地址,改成私仓的地址;并将clusterrolebinding附近name: kubernetes-dashboard改成name: cluster-admin以获得管理员权限
sed -i "s/kubernetesui/10.57.26.15:4000/g;/kind: ClusterRole/{n;s/name: kubernetes-dashboard/name: cluster-admin/g}" dashboard-v2.0.0-beta2.yaml
#安装
kubectl create -f dashboard-v2.0.0-beta2.yaml

然后可以通过查看安装组件,以及部署状态。

3 dashboard访问

这是我认为dashboard部署的重点,也是坑比较多的地方,我在里面陷了很久,在此分享一下。 我尝试了4种访问dashboard服务的方式,其他服务都可以借鉴。

3.1 kubectl proxy

kubectl proxy 的原理是将机器与kubernetes API Server之间做一个代理,默认情况下,只能从本机访问。 可以使用kubectl cluster-info命令检查配置是否正确,集群是否可以访问。

启动代理只需执行如下命令即可:

$ kubectl proxy
Starting to serve on 127.0.0.1:8001

也可以使用--addressaccept-hosts参数来允许外部访问:

$ kubectl proxy --address='0.0.0.0'  --accept-hosts='^*$'
Starting to serve on [::]:8001

然后在外网访问http://<master-ip>:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/就可以访问到登陆界面,但是却无法登陆,这是因为Dashboard只允许localhost和127.0.0.1使用HTTP连接进行访问,而其它地址只允许使用HTTPS。因此,如果需要在非本机访问Dashboard的话,只能选择其他访问方式。 写法的补充: 如下图所示是dashboard的endpoints输出,endpoints输出中的部分信息填入,并添加http或https的信息,还需要添加端口号,因为dashboard是443默认,所以:后面可以不加任何东西 换个例子,tomcat的service,暴露8080端口号的访问路径如下: http://<master-ip>:8001/api/v1/namespaces/default/services/http:tomcat:8080/proxy/ 对应endpoint如下

3.2 NodePort

NodePort是将节点直接暴露在外网的一种方式,只建议在开发环境,单节点的安装方式中使用。

启用NodePort很简单,只需执行在yaml配置文件中定义service时显视的定义NodePort即可,如下所示: 添加type: NodePort即可(默认是ClusterIP)

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

然后执行kubectl apply -f dashboard-v2.0.0-beta2.yaml即可,输出如下:

NAME                   TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)         AGE
kubernetes-dashboard   NodePort   10.103.5.139   <none>        443:31795/TCP   4h

如上所示,Dashboard已经在31795端口上公开,现在可以在外部使用https://:31795进行访问。需要注意的是,在多节点的集群中,必须找到运行Dashboard节点的IP来访问,而不是Master节点的IP。 但是,访问后显示如下:

由于证书问题,我们无法访问,需要在部署Dashboard时指定有效的证书,才可以访问。由于在正式环境中,并不推荐使用NodePort的方式来访问Dashboard。 证书的配置后续再研究。。。

3.3 API Server

API Server访问方式和proxy方式最大的区别在于,路径开头是https的。 如果Kubernetes API服务器是公开的,并可以从外部访问,那我们可以直接使用API Server的方式来访问,也是比较推荐的方式。

Dashboard的访问地址为: https://<master-ip>:<apiserver-port>/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/ 返回结果如下:

{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {
    
  },
  "status": "Failure",
  "message": "services \"https:kubernetes-dashboard:\" is forbidden: User \"system:anonymous\" cannot get services/proxy in the namespace \"kube-system\"",
  "reason": "Forbidden",
  "details": {
    "name": "https:kubernetes-dashboard:",
    "kind": "services"
  },
  "code": 403
}

这是因为最新版的k8s默认启用了RBAC,并为未认证用户赋予了一个默认的身份:anonymous。 对于API Server来说,它是使用证书进行认证的,我们需要先创建一个证书:

  1. 首先找到kubectl命令的配置文件,默认情况下为/etc/kubernetes/admin.conf,确保已经复制到了$HOME/.kube/config中。
  2. 使用client-certificate-data和client-key-data生成一个p12文件,可使用下列命令
    生成client-certificate-data
    grep 'client-certificate-data' ~/.kube/config | head -n 1 | awk '{print $2}' | base64 -d >> kubecfg.crt
    生成client-key-data
    grep 'client-key-data' ~/.kube/config | head -n 1 | awk '{print $2}' | base64 -d >> kubecfg.key
    生成p12
    openssl pkcs12 -export -clcerts -inkey kubecfg.key -in kubecfg.crt -out kubecfg.p12 -name "kubernetes-client"
  3. 导入上面生成的p12文件,这一步自行到网上参考。最后好像还需要对浏览器清理缓存。
  4. 最后导入上面生成的p12文件,重新打开浏览器,显示如下:
  5. 点击确定,便可以看到熟悉的登录界面了:

token的获取将在用户令牌中描述。

注:对于生产系统,我们应该为每个用户应该生成自己的证书,因为不同的用户会有不同的命名空间访问权限。

3.4 Ingress

Ingress将开源的反向代理负载均衡器(如 Nginx、Apache、Haproxy等)与k8s进行集成,并可以动态的更新Nginx配置等,是比较灵活,更为推荐的暴露服务的方式。 对于ingress的方式,由于篇幅较长,将在[《Nginx+Ingress-controller解决L7外网Web服务暴露和负载均衡》]()中详细介绍。

3.5 服务暴露小结

简单说几句四个暴露方式的差异点: 1. NodePort需要寄主机也开端口来对pod中服务的端口做映射。 2. clusterip方式不需要寄主机开端口,是比较好的适应生产模式的方式。 3. clusterip的发现主要有三种,分别是proxy,开放api server以及ingress。 4. proxy方式是http方式暴露,apiserver方式是https方式暴露。 5. ingress可以通过域名的方式访问service ip。根据不同实现,有nginx,traefik等。

4 用户令牌

经过服务发现暴露ip后,登陆dashboard可以看到如下界面,我们使用kubernetes-dashboard账号作为管理员登陆,那么这个账号令牌又是什么呢,从哪可以获取到呢? 我们可以通过命令查看这个账户的令牌是什么内容,命令是kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep admin-user | awk '{print $1}')

5 dashboard 管理员权限

Dashboard Role只给了kubernetes-dashboard比较小的权限 创建role后,可以通过kubectl get role -nkubernetes-dashboard查看


还可以通过kubectl get secret来查看Secret-token列表:

用户登陆后,在dashboard界面将看到很多权限不足的报错,类似如下图所示:

所以通过将kubernetes-dashboard账号权限改成cluster-admin就可以获得无比大的管理员权限,创建完之前所示的yaml后,可以来查看一下kubernetes-dashboard命名空间下的ClusterRoleBinding列表:

再次使用kubernetes-dashboard用户登录dashboard管理界面,我们发现不在有警告提示,而且权限超级大:

6 多用户权限隔离

http://wiki.tongdun.me/pages/viewpage.action?pageId=20166021

7 Kubernetes-Dashboard的官方介绍

http://wiki.tongdun.me/pages/viewpage.action?pageId=20166049 https://kubernetes.io/docs/tasks/access-application-cluster/web-ui-dashboard/