1 Dashboard界面简介

Kubernetes Dashboard是K8s官方提供的Web UI,把kubectl的常用能力做成点击式页面,可以在Web界面很方便地查看集群、管理应用、查看日志、运行容器,无需命令行也能运维K8s。
Dashboard所有数据实时调用kube-apiserver REST接口,自身并无状态。可通过ServiceAccount + RBAC实现访问范围控制。

2 Dashboard安装及配置

Dashboard安装非常简单,从官方下载一个yaml文件,使用kubectl apply安装,暴露NodePort,创建管理员Token,就可以在浏览器登录了。

2.1 从官方下载recommended.yaml文件

下载官方资源清单文件

[root@master 10-dashboard]# wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml

下载的recommended.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.

apiVersion: v1
kind: Namespace
metadata:
  name: kubernetes-dashboard

---

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

---

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

---

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

---

apiVersion: v1
kind: Secret
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard-csrf
  namespace: kubernetes-dashboard
type: Opaque
data:
  csrf: ""

---

apiVersion: v1
kind: Secret
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard-key-holder
  namespace: kubernetes-dashboard
type: Opaque

---

kind: ConfigMap
apiVersion: v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard-settings
  namespace: kubernetes-dashboard

---

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
rules:
  # Allow Dashboard to get, update and delete Dashboard exclusive secrets.
  - apiGroups: [""]
    resources: ["secrets"]
    resourceNames: ["kubernetes-dashboard-key-holder", "kubernetes-dashboard-certs", "kubernetes-dashboard-csrf"]
    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.
  - apiGroups: [""]
    resources: ["services"]
    resourceNames: ["heapster", "dashboard-metrics-scraper"]
    verbs: ["proxy"]
  - apiGroups: [""]
    resources: ["services/proxy"]
    resourceNames: ["heapster", "http:heapster:", "https:heapster:", "dashboard-metrics-scraper", "http:dashboard-metrics-scraper"]
    verbs: ["get"]

---

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
rules:
  # Allow Metrics Scraper to get metrics from the Metrics server
  - apiGroups: ["metrics.k8s.io"]
    resources: ["pods", "nodes"]
    verbs: ["get", "list", "watch"]

---

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

---

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: kubernetes-dashboard
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: kubernetes-dashboard
subjects:
  - kind: ServiceAccount
    name: kubernetes-dashboard
    namespace: kubernetes-dashboard

---

kind: Deployment
apiVersion: apps/v1
metadata:
  labels:
    k8s-app: kubernetes-dashboard
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
spec:
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      k8s-app: kubernetes-dashboard
  template:
    metadata:
      labels:
        k8s-app: kubernetes-dashboard
    spec:
      securityContext:
        seccompProfile:
          type: RuntimeDefault
      containers:
        - name: kubernetes-dashboard
          image: kubernetesui/dashboard:v2.7.0
          imagePullPolicy: Always
          ports:
            - containerPort: 8443
              protocol: TCP
          args:
            - --auto-generate-certificates
            - --namespace=kubernetes-dashboard
            # 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
          securityContext:
            allowPrivilegeEscalation: false
            readOnlyRootFilesystem: true
            runAsUser: 1001
            runAsGroup: 2001
      volumes:
        - name: kubernetes-dashboard-certs
          secret:
            secretName: kubernetes-dashboard-certs
        - name: tmp-volume
          emptyDir: {}
      serviceAccountName: kubernetes-dashboard
      nodeSelector:
        "kubernetes.io/os": linux
      # Comment the following tolerations if Dashboard must not be deployed on master
      tolerations:
        - key: node-role.kubernetes.io/master
          effect: NoSchedule

---

kind: Service
apiVersion: v1
metadata:
  labels:
    k8s-app: dashboard-metrics-scraper
  name: dashboard-metrics-scraper
  namespace: kubernetes-dashboard
spec:
  ports:
    - port: 8000
      targetPort: 8000
  selector:
    k8s-app: dashboard-metrics-scraper

---

kind: Deployment
apiVersion: apps/v1
metadata:
  labels:
    k8s-app: dashboard-metrics-scraper
  name: dashboard-metrics-scraper
  namespace: kubernetes-dashboard
spec:
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      k8s-app: dashboard-metrics-scraper
  template:
    metadata:
      labels:
        k8s-app: dashboard-metrics-scraper
    spec:
      securityContext:
        seccompProfile:
          type: RuntimeDefault
      containers:
        - name: dashboard-metrics-scraper
          image: kubernetesui/metrics-scraper:v1.0.8
          ports:
            - containerPort: 8000
              protocol: TCP
          livenessProbe:
            httpGet:
              scheme: HTTP
              path: /
              port: 8000
            initialDelaySeconds: 30
            timeoutSeconds: 30
          volumeMounts:
          - mountPath: /tmp
            name: tmp-volume
          securityContext:
            allowPrivilegeEscalation: false
            readOnlyRootFilesystem: true
            runAsUser: 1001
            runAsGroup: 2001
      serviceAccountName: kubernetes-dashboard
      nodeSelector:
        "kubernetes.io/os": linux
      # Comment the following tolerations if Dashboard must not be deployed on master
      tolerations:
        - key: node-role.kubernetes.io/master
          effect: NoSchedule
      volumes:
        - name: tmp-volume
          emptyDir: {}

2.2 安装Dashboard

recommended.yaml资源清单文件包含了RBAC、Secret、Deployment和Service等对象,需要kubernetesui/dashboard:v2.7.0和kubernetesui/metrics-scraper:v1.0.8这两个镜像(镜像文件在本文配套资料包中,如无法上网,可以下载资料包后使用docker load -i *.tgz离线安装这两个镜像)。
配套资料包地址:https://download.csdn.net/download/field1003/91965690
这里介绍两种安装方式:在线安装和离线安装。

2.2.1 在线安装

如果已经配置好网络,可以访问到github、dockerhub等网站,则可以通过以下命令安装Dashboard
[root@master 10-dashboard] kubectl apply -f recommended.yaml
该命令将创建Dashboard所需资源对象,下载镜像文件。
经过一段漫长的等待,Dashboard就安装完成了,这时就可以进入下一阶段的创建管理员并获取Token了。

2.2.2 离线安装

如果镜像文件一直下载超时,可以考虑离线安装镜像文件,离线安装镜像文件时,需要下载与k3s相对应的镜像版本,否则容易出现兼容性问题。
本文k3s版本为1.29.6,与dashboard-v2.7.0、metrics-scraper-v1.0.8兼容。

(1) 离线导入镜像文件
本文配套资料包中,k8s-test/1-setup/images目录下,有metrics-scraper-v1.0.8.tar和dashboard-v2.7.0.tar两个文件,可以通过docker -i命令离线加载。

# 安装metrics-scraper
[root@master images]# docker load -i metrics-scraper-v1.0.8.tar
d01384fea991: Loading layer [==================================================>]  43.82MB/43.82MB
bcec7eb9e567: Loading layer [==================================================>]  3.584kB/3.584kB
Loaded image: kubernetesui/metrics-scraper:v1.0.8
# 安装dashboard
[root@master images]# docker load -i dashboard-v2.7.0.tar
bd8a70623766: Loading layer [==================================================>]  249.2MB/249.2MB
c88361932af5: Loading layer [==================================================>]  3.072kB/3.072kB
Loaded image: kubernetesui/dashboard:v2.7.0
[root@master images]# docker images
REPOSITORY                                               TAG                    IMAGE ID       CREATED         SIZE
registry.k8s.io/ingress-nginx/controller                 v1.12.0                a4a8af0db089   7 months ago    302MB
registry.k8s.io/ingress-nginx/kube-webhook-certgen       v1.5.0                 6595b1857d40   7 months ago    66.1MB
nginx                                                    1.27.3                 66f8bdd3810c   8 months ago    192MB
nginx                                                    1.27.5                 66f8bdd3810c   8 months ago    192MB
rancher/local-path-provisioner                           v0.0.27                c45111663115   14 months ago   49.3MB
rancher/klipper-helm                                     v0.8.4-build20240523   0c1204a22f13   15 months ago   263MB
rancher/klipper-lb                                       v0.4.7                 edc812b8e25d   18 months ago   11.8MB
rancher/mirrored-library-traefik                         2.10.7                 ee69e8120b64   18 months ago   153MB
rancher/mirrored-metrics-server                          v0.7.0                 b9a5a1927366   19 months ago   66.8MB
rancher/mirrored-library-busybox                         1.36.1                 65ad0d468eb1   2 years ago     4.26MB
rancher/mirrored-coredns-coredns                         1.10.1                 ead0a4a53df8   2 years ago     53.6MB
kubernetesui/dashboard                                   v2.7.0                 07655ddf2eeb   2 years ago     246MB
kubernetesui/metrics-scraper                             v1.0.8                 115053965e86   3 years ago     43.8MB
busybox                                                  1.34.1                 beae173ccac6   3 years ago     1.24MB
rancher/mirrored-pause                                   3.6                    6270bb605e12   3 years ago     683kB
k8s.gcr.io/sig-storage/nfs-subdir-external-provisioner   v4.0.2                 932b0bface75   4 years ago     43.8MB

(2) 创建资源对象

# 执行kubectl apply命令,创建资源对象
[root@master 10-dashboard]# kubectl apply -f recommended.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命名空间下所有资源
# 发现dashboard这个Pod拉取镜像失败,我们之前已经安装过这个应用,理论上讲不应该出现这个错误
# 查看recommended.yaml文件,发现dashboard这个镜像的拉取策略为Always,无论本地是否存在,均从仓库拉取
[root@master 10-dashboard]# kubectl get all -n kubernetes-dashboard
NAME                                             READY   STATUS         RESTARTS   AGE
pod/dashboard-metrics-scraper-5657497c4c-88kgz   1/1     Running        0          35s
pod/kubernetes-dashboard-78f87ddfc-t8426         0/1     ErrImagePull   0          35s

NAME                                TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
service/dashboard-metrics-scraper   ClusterIP   10.43.252.114   <none>        8000/TCP   15s
service/kubernetes-dashboard        ClusterIP   10.43.15.140    <none>        443/TCP    15s

NAME                                        READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/dashboard-metrics-scraper   1/1     1            1           35s
deployment.apps/kubernetes-dashboard        0/1     1            0           35s

NAME                                                   DESIRED   CURRENT   READY   AGE
replicaset.apps/dashboard-metrics-scraper-5657497c4c   1         1         1       35s
replicaset.apps/kubernetes-dashboard-78f87ddfc         1         1         0       35s
# 可以手动修改recommanded.yaml文件,Always改为IfNotPresent。也可以使用kubectl patch命令快速修改。
[root@master 10-dashboard]# kubectl -n kubernetes-dashboard patch deployment kubernetes-dashboard --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/imagePullPolicy", "value": "IfNotPresent"}]'
deployment.apps/kubernetes-dashboard patched
# 打完patch后,所有镜像均正常运行
[root@master 10-dashboard]# kubectl get pod -n kubernetes-dashboard
NAME                                         READY   STATUS    RESTARTS   AGE
dashboard-metrics-scraper-5657497c4c-88kgz   1/1     Running   0          2m9s
kubernetes-dashboard-5b749d9495-44mbs        1/1     Running   0          12s

2.3 创建管理员并获取Token

新建ServiceAccount dashboard-admin,并将其与集群的cluster-admin绑定。
配置文件

[root@master 10-dashboard]# cat dashboard-admin-sa.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: dashboard-admin
  namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: dashboard-admin
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: dashboard-admin
  namespace: kubernetes-dashboard

绑定

[root@master 10-dashboard]# kubectl apply -f dashboard-admin-sa.yaml
serviceaccount/dashboard-admin created
clusterrolebinding.rbac.authorization.k8s.io/dashboard-admin unchanged
[root@master 10-dashboard]#

获取Token

[root@master 10-dashboard]# kubectl -n kubernetes-dashboard create token dashboard-admin
eyJhbGciOiJSUzI1NiIsImtpZCI6IlVaeDdlWkZDck1GRzdubWswanBPRk95eE9Lc0xRdzZHeTNMSUZWNG13STAifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiLCJrM3MiXSwiZXhwIjoxNzU1NTM1NDk3LCJpYXQiOjE3NTU1MzE4OTcsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJrdWJlcm5ldGVzLWRhc2hib2FyZCIsInNlcnZpY2VhY2NvdW50Ijp7Im5hbWUiOiJkYXNoYm9hcmQtYWRtaW4iLCJ1aWQiOiIzZWJkN2FiOC05ODg4LTRhZDctOTg4YS04MDc2MDJiZGIwOGUifX0sIm5iZiI6MTc1NTUzMTg5Nywic3ViIjoic3lzdGVtOnNlcnZpY2VhY2NvdW50Omt1YmVybmV0ZXMtZGFzaGJvYXJkOmRhc2hib2FyZC1hZG1pbiJ9.bZhYQYtUsbopQocQz0TBGXWCZM9NyvgF8GSrFg_LlOA5d99-YrCMj27VlmQ9MYVgYoYzTOjSQZ4MnpsbOZApGajeWJUtVcmxJFcErmHZy80zITxiuGsbIN2cWM5_8cBKqbT6Rl5J056pflp95eaYQ9lYr0qgtvoZLLFeDArkuvDMToh-y5_rXk8g_jLpEVg9EjUuGIJv2C9k-lOrpv1oPCSqAqqp6bhNOjVEEcorKJ6BhUtPKDuyKhW1unj_U8pQzgxj9farHA2jwNwhbYgeSFhiZJ6CUziVnP88-fZe_Zyre3bnUuMwG2shusGkQ3fq3uM-ySRq07u-VyD9haol1Q

2.4 暴露端口,集群外可访问

得到管理员Token,在集群内部,就可以通过ClusterIP访问Dashboard了。

[root@master 10-dashboard]# kubectl get svc -n kubernetes-dashboard
NAME                        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
dashboard-metrics-scraper   ClusterIP   10.43.252.114   <none>        8000/TCP   8m49s
kubernetes-dashboard        ClusterIP   10.43.15.140    <none>        443/TCP    8m49s

如果我们想要在集群外部访问Dashboard,还需要将ClusterIP类型Service改为NodePort类型Service。
可以通过修改recommanded.yaml的Service对象,添加一个type: NodePort字段,由默认的ClusterIP改为NodePort。也可以通过kubectl patch快速修改。

# 通过kubectl patch将Service对象的type改为NodePort
[root@master 10-dashboard]# kubectl -n kubernetes-dashboard patch svc kubernetes-dashboard --type='json' -p='[{"op":"replace","path":"/spec/type","value":"NodePort"}]'
service/kubernetes-dashboard patched
# 查看Service,可以看到已经变成NodePort,对外暴露端口为10981
[root@master 10-dashboard]# kubectl get svc -n kubernetes-dashboard
NAME                        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)         AGE
dashboard-metrics-scraper   ClusterIP   10.43.252.114   <none>        8000/TCP        19m
kubernetes-dashboard        NodePort    10.43.15.140    <none>        443:10981/TCP   19m

2.5 小结

Dashboard安装非常简单,如果网络可达,一个命令即可安装完成,然后创建管理员及暴露端口就可以访问。如果网络不可达,则需要自己手动操作,下载镜像,修改配置文件等等。
如果是离线安装,可以提前将官方下载的recommended.yaml文件修改好,把第二步Deployment镜像下载策略改为IfNotPresent,把第四步Service类型改为NodePort,这样还可以省去暴露端口的步骤。两者对比如下:

[root@master 10-dashboard]# diff recommended.yaml recommended-offline.yaml
194c194
<           imagePullPolicy: Always
---
>           imagePullPolicy: IfNotPresent
246a247
>   type: NodePort
249a251
>       nodePort: 32000

3 访问Dashboard

(1) 查看Dashboard Service NodePort端口

# Dashboard对外暴露端口为10981
[root@master 10-dashboard]# kubectl get svc -n kubernetes-dashboard
NAME                        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)         AGE
dashboard-metrics-scraper   ClusterIP   10.43.252.114   <none>        8000/TCP        22m
kubernetes-dashboard        NodePort    10.43.15.140    <none>        443:10981/TCP   22m

(2) 集群外使用浏览器打开Dashboard地址
https://192.168.88.132:10981
弹出风险提示。如果出现“警告:面临潜在的安全风险”,点击高级,接收风险
点击 高级->接受风险并继续
接收风险并继续
(3) Token方式登录
Dashboard有两种登录方式:Token和Kubeconfig。
Token方式相对简单,只需要向输入框填入生成的Token即可访问。
Kubeconfig方式更加灵活,需要提供一个kubeconfig文件,让Dashboard自己从文件解析Token。
这里演示Token方法。

输入前面生成的Token,然后点击“登录”。
选择Token选项,并输入Token
(4) 进入Dashboard管理界面
点击登录,即可进入Dashboard管理界面,左侧有工作负载、服务、配置和存储、集群及自定义资源等分类,点击即可查看对应资源对象详情,与kubectl命令行查看到的内容相同。
Dashboard管理界面

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐