「Kubernetes」- 部署 Dashboard 服务(Kubernetes v1.18.9)

问题描述

虽然很多复杂的操作还是要通过命令行来完成,但是通过图形化界面能够快速完成简单操作,而且操作更加友好、数据显示更加直观,这是命令行所无法相提并论的;

鉴于此,我们将在集群中部署 Dashboard 界面,实现对集群的资源的简单管理、显示正在运行的应用、查看资源状态、查看集群信息等等。但是 kubernetes/dashboard: General-purpose web UI for Kubernetes clusters 表示 Dashboard 只是用于完成简单通用的管理任务,更加复杂的操作还要通过其他组件来完成;

该笔记将记录:在 Kubernetes Cluster 中,如何安装部署 Dashboard 服务,并提供 HTTPS 访问,以及常见问题的处理方法;

解决方案

完成 Kubernetes 基本管理的图形化管理
GitHub – kubernetes/dashboard: General-purpose web UI for Kubernetes clusters

系统环境:Kubernetes Cluster v1.18.9

第一步、下载部署文件

根据 Releases · kubernetes/dashboard 描述,针对 Kubernetes 1.18 我们使用最新、最适合的 v2.0.3 版本;

下载 recommended.yaml 文件(如果无法下载,使用 ./recommended.yaml 文件)

wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.3/aio/deploy/recommended.yaml

第二步、调整部署文件(可选)

结合自身需求与环境,修改部署文件:
1)修改镜像地址,以使用私有镜像仓库中的镜像:这需要我们拉取目标镜像,创建镜像标签并推送似有仓库;然后,修改 YAML 文件以使用私有镜像;
2)修改命名空间位置,将其部署到自定义的命名空间;

第三步、应用部署文件

# kubectl apply -f dashboard.yaml
namespace/kubernetes-dashboard created
serviceaccount/kubernetes-dashboard created
service/kubernetes-dashboard created
secret/kubernetes-dashboard-certs created
secret/kubernetes-dashboard-csrf created
secret/kubernetes-dashboard-key-holder created
configmap/kubernetes-dashboard-settings created
role.rbac.authorization.k8s.io/kubernetes-dashboard created
clusterrole.rbac.authorization.k8s.io/kubernetes-dashboard created
rolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
clusterrolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created
deployment.apps/kubernetes-dashboard created
service/dashboard-metrics-scraper created
deployment.apps/dashboard-metrics-scraper created

默认使用 kubernetes-dashboard 命令空间

第四步、登录仪表盘

在新版本的 Kubernetes Dashboard 中,出于安全考虑,从 Dashboard 1.10.1 开始不再提供 SKIP 按钮,所以通过 Dashboard 集群操作时,需要先创建 TOKEN。或为 Dashboard 指定 –enable-skip-login 选项。我们选择 TOKEN 登录,而不再使用 SKIP 按钮;

获取访问使用的 TOKEN 参数:

secret=$(kubectl get -n kube-system serviceaccounts deployment-controller -o jsonpath='{.secrets[0].name}')
kubectl get -n kube-system secrets $secret -o jsonpath='{.data.token}' | base64 -d

我们使用 kubectl port-forward 转发 dashboard 的 Service 端口,以快速测试(后面将使用 Ingress 来暴露服务):

# kubectl port-forward -n kubernetes-dashboard service/kubernetes-dashboard --address 0.0.0.0 50443:443
Forwarding from 0.0.0.0:50443 -> 8443

使用 Firefox 访问 https://<hostname>:50443 并输入 TOKEN 参数,以进入 Dashboard 界面。因为证书是自签名的,而 Chrome 的安全策略又不同,因此使用 Chrome 可能无法访问 Dashboard 界面(甚至没有继续访问按钮)。不过,这里仅是测试,后面将介绍如何处理这些问题;

通过 Ingress 暴露 Dashboard 服务

为了允许外部访问,我们需要通过 Ingress 暴露 Dashboard 服务,以允许外部访问。鉴于我们使用 Nginx Ingress Controller 组件,因此后面的特殊配置也将基于此(因为可能有些配置与 Nginx Ingress Controller 相关);

默认情况 Dashboard 监听 HTTPS 协议,而默认 Ingress 使用 HTTP 协议来请求 Dashboard 服务,这就导致连接失败;

针对该问题,有以下解决方案:
1)使 Dashboard 监听 HTTP 80 端口,这样 Ingress 便能够使用 HTTP 请求 Dashboard 服务;
2)将 HTTPS 连接直通 Dashboard 容器(即使用 SSL Passthrough 特性,这也需要进行更多的配置);

方法一、使 Dashboard 监听 HTTP 80 端口(废弃)

该方法虽然简单,但也许会降低安全性,请根据自身的需求进行取舍。我们未采用该方案,该方案会降低安全性(其实问题不大),也非官方推荐做法,此外我们想试试更加复杂的做法(有的时候技术选型完全是按照负责人的个人喜好,我们总是能找到这样做的其他借口);

官方已经提供 alternative.yaml 配置来监听 HTTP 协议(如果无法下载,使用 ./alternative.yaml 文件):

wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.0.3/aio/deploy/alternative.yaml
kubectl apply -f alternative.yaml

定义 Ingress 资源(这里我们仅演示监听 HTTP 的 Ingress 资源):

cat > dashboard-ingress.yaml <<EOF
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: kubernetes-dashboard
spec:
  rules:
  - host: k8s-dashboard.example.com
    http:
      paths:
      - path: /
        backend:
          serviceName: kubernetes-dashboard
          servicePort: 80
EOF

kubectl apply -f dashboard-ingress.yaml

使用浏览器访问 http://k8s-dashboard.example.com 并输入 TOKEN 参数,以进入 Dashboard 界面;

方法二、将 HTTPS 连接直通 Dashboard 容器(废弃)

这是我们采用的方法,但是该方法更加复杂,需要添加的配置也比较多:
1)部署 Nginx Ingress Controller 组件;
1)需要配置 Nginx Ingress Controller 的 SSL Passthrough 特性;
2)需要修改 Dashboard 的 SSL 证书,而不是使用自签名证书;

这是我们目前采用的方法,需要进行以下操作:

1)目前(05/26/2019),由于 Nginx Ingress Controller 默认禁用 SSL 直通,所以要修改它的资源定义(Daemonset 或 Deployment),在容器启动参数中添加 --enable-ssl-passthrough 选项,以启用 SSL 直通。但是,这只是启用 SSL 直通功能,而进行 SSL 直通需要单独配置;
2)在 Dashboard 的 Ingress 定义中,添加 nginx.ingress.kubernetes.io/ssl-passthrough: true 注解,以允许 SSL 直通;
3)最后,配置 Dashboard 的 TLS 证书,否则浏览器访问时将提示证书不安全。修改 kubernetes-dashboard-certs 密钥;

方法三、通过 HTTPS 代理(折中方案)

这是我们目前(05/08/2021)正在使用的方案:

cat > dashboard-ingress.yaml <<EOF
---
apiVersion: extensions/v1beta1kind: Ingressmetadata:
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
spec:
  rules:
  - host: kube-dashboard.example.com
    http:
      paths:
      - backend:
          serviceName: kubernetes-dashboard
          servicePort: 443
        path: /
  tls:
  - hosts:
    - kube-dashboard.example.com
    secretName: dashboard-ingress-cert
EOF

kubectl apply -f dashboard-ingress.yaml

“折中”是因为后端的 Dashboard 仍然使用自签名证书,但是 Nginx Ingress 默认 nginx.ingress.kubernetes.io/proxy-ssl-verify 为 off,因此不会检查后端的 TLS 证书,所以也未出现任何错误;

注意事项:我们使用 Certificate Manager (TLS, SSL):cert-manager 进行证书 TLS 签发,所以这里需要根据需要进行修改。参考 Securing Ingress Resources 笔记,以获取 Ingress 配置 TLS 的方法;

问题:Forbidden(403)

当激活 RBAC 鉴权后,在很多环境中,访问 Dashboard 会看到 Forbidden(403) 状态码;

如果想要访问仪表盘,必须要赋予 kube-system:default 帐号必要的权限:

# kubectl create clusterrolebinding admin:kubesystem --clusterrole=cluster=admin --serviceaccount=kube-system:default

该命令会赋予帐号非常多的权限,不建议在生产环境中进行该操作;

问题:通过 Chrome 访问出现 NET::ERR_CERT_INVALID 错误

i can access dashboard in Linux with https://masternodeIP:port with googlechrome, but can’t do that in Windows. #2954

某一天,使用 Chrome 访问 Dashboard 时,产生 NET::ERR_CERT_INVALID 错误;
以前出现 NET::ERR_CERT_AUTHORITY_INVALID 错误,还能通过浏览器 AdvancedProceed to xxxx (unsafe) 继续访问;

原因分析

类似的问题都是因为证书错误导致的。而且 Dashbaord 的证书是自签名的,也会导致浏览器提示证书错误;
根本原因在于:在集群部署时,我们使用自签名证书,导致后续的自动创建的证书都属于自签名证书;

解决方案

补充说明:以前我们尝试重新生成 Dashboard 证书来解决问题,但繁琐且不正规(因此我们从笔记中删除该方案);

如果想从根本上解决该问题,那么需要重新签发集群证书,这样才能从根本上解决相关问题。但是成本过高,而且要经过测试验证;

我们选择简单的方法:直接定义 Ingress 资源,并使用 nginx.ingress.kubernetes.io/backend-protocol: “HTTPS” 注解来反向代理 Dashboard 的 HTTPS 端口,由于 Nginx Ingress 默认 nginx.ingress.kubernetes.io/proxy-ssl-verify 为 off,因此不会检查后端 Dashboard 的 TLS 证书,所以也未出现任何错误;

参考 Dashboard 笔记的「通过 Ingress 暴露 Dashboard 服务」部分,以获取 Ingress 资源的配置方法;

相关链接

Kubernetes/TAKS/Web UI (Dashboard)
GitHub/kubernetes/dashboard/docs/user/access-control/creating-sample-user.md

参考文献

GitHub/helm/charts/stable/kubernetes-dashboard
GitHub/kubernetes/dashboard/v2.0.0-beta4
NGINX Ingress Controller/Command line arguments
NGINX Ingress Controller/Annotations/SSL Passthrough
SKIP button in kubernetes dashboard is missing #703
How to sign in kubernetes dashboard? – Stack Overflow
How to expose your Kubernetes Dashboard with cert-manager | by Valerio Coltrè | ITNEXT
Annotations – NGINX Ingress Controller
https backends’ certificates are not verified · Issue #4503 · kubernetes/ingress-nginx
Exposing the Kubernetes Dashboard with an Ingress | Jonathan Gazeley
kubernetes-dashboard获取令牌登陆