Skip to content

安装 Kubernetes Dashboard 控制面板

安装 Kubernetes Dashboard 控制面板示意图

前言

在 Kubernetes 集群中安装 Dashboard 是一个很常见的需求。本文档将指导你在各种 Kubernetes 环境中安装 Kubernetes Dashboard,包括 Docker Desktop、Minikube、kubeadm 部署的集群等。

注意:本文档基于 Dashboard v2.7.0 版本编写。请查看 Kubernetes Dashboard 发布页面 以确认最新稳定版本。

第一步:准备工作

1.1 拉取镜像(可选)

Dashboard 所需的镜像通常会在部署时自动拉取。但如果你的网络环境较差,或希望提前准备镜像,可以手动拉取。

shell
docker pull kubernetesui/dashboard:v2.7.0
docker pull kubernetesui/metrics-scraper:v1.0.8
shell
ctr image pull docker.io/kubernetesui/dashboard:v2.7.0
ctr image pull docker.io/kubernetesui/metrics-scraper:v1.0.8
shell
nerdctl pull kubernetesui/dashboard:v2.7.0
nerdctl pull kubernetesui/metrics-scraper:v1.0.8

提示

  • Docker:适用于 Docker Desktop、使用 Docker 作为运行时的集群
  • containerd:适用于 Kubernetes 1.24+ 默认使用 containerd 的集群(如 kubeadm 部署)
  • nerdctl:containerd 的 Docker 兼容命令行工具

💡 注意

containerd 的终端工具 ctr 在拉取镜像时,可能会因为网络环境问题而失败,这时可以拷贝一台可以连接国际互联网的代理工具提供的代理地址到该服务器以达到访问国际互联网的目的,话不多话,你懂得~

1. 提取 dashboard

bash
# 将 <your-proxy-ip> 替换为实际代理地址
HTTP_PROXY=http://<your-proxy-ip>:7890 \
HTTPS_PROXY=http://<your-proxy-ip>:7890 \
NO_PROXY=localhost,127.0.0.1,.local,10.0.0.0/8,192.168.0.0/16,172.16.0.0/12 \
ctr image pull docker.io/kubernetesui/dashboard:v2.7.0

2. 提取 metrics-scraper

bash
# 将 <your-proxy-ip> 替换为实际代理地址
HTTP_PROXY=http://<your-proxy-ip>:7890 \
HTTPS_PROXY=http://<your-proxy-ip>:7890 \
NO_PROXY=localhost,127.0.0.1,.local,10.0.0.0/8,192.168.0.0/16,172.16.0.0/12 \
ctr image pull docker.io/kubernetesui/metrics-scraper:v1.0.8

为 kubelet 配置代理(可选)

如果希望 Pod 在调度时自动通过代理拉取镜像,需要为 kubelet 配置代理。在每个节点上执行:

bash
sudo mkdir -p /etc/systemd/system/kubelet.service.d
sudo tee /etc/systemd/system/kubelet.service.d/http-proxy.conf > /dev/null <<EOF
[Service]
Environment="HTTP_PROXY=http://<your-proxy-ip>:7890"
Environment="HTTPS_PROXY=http://<your-proxy-ip>:7890"
Environment="NO_PROXY=localhost,127.0.0.1,.local,10.0.0.0/8,192.168.0.0/16,172.16.0.0/12"
EOF

sudo systemctl daemon-reload
sudo systemctl restart kubelet

⚠️ 特别提醒:如果代理 IP 是通过 DHCP 自动分配的,终端设备重启或重新接入网络后,代理 IP 可能会发生变化,导致 kubelet 无法正常拉取镜像。建议使用静态 IP 的代理节点,或在使用完成后及时删除 kubelet 的代理配置。

第二步:安装 Kubernetes Dashboard

Kubernetes Dashboard 项目官方提供了规范化的安装 YAML 清单文件,我们可以直接应用它。你可以通过 kubectl apply -f 应用线上文件,也可以将资源定义文件下载到本地进行存储和部署。

2.1 下载 Kubernetes Dashboard 资源定义

打开终端(Terminal),执行以下命令:

shell
wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml -O kubernetes-dashboard.yaml

如果 wget 不可用,也可以使用 curl

shell
curl -L https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml -o kubernetes-dashboard.yaml

注意

请务必查看 Kubernetes Dashboard 发布页面 以确认最新稳定版本。上述 URL 中的 v2.7.0 可能会随时间变化。如果遇到问题,请替换为最新的版本号。

2.2 部署 Dashboard 到 Kubernetes 环境

shell
kubectl apply -f kubernetes-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

2.3 验证安装

检查 Dashboard 的 Pod 是否正在运行。它会被创建在 kubernetes-dashboard 命名空间中。

bash
kubectl get pods -n kubernetes-dashboard

等待 Pod 的状态变为 Running。输出应类似于:

NAME                                         READY   STATUS    RESTARTS   AGE
dashboard-metrics-scraper-5f44d5f6c6-9k5pj   1/1     Running   0          60s
kubernetes-dashboard-678bc9f755-2nx9r        1/1     Running   0          60s

第三步:创建访问 Dashboard 的权限

默认安装的 Dashboard 具有最小的 RBAC(基于角色的访问控制)权限。我们需要创建一个拥有适当权限的 Service Account 来登录和访问集群资源。

3.1 编写 ServiceAccount 及 ClusterRoleBinding 资源定义文件

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

警告

创建一个名为 admin-user 的 Service Account 并将其绑定到 cluster-admin 角色(拥有最高权限)。注意:在生产环境中,应授予更精细的权限。

3.2 部署 ServiceAccount 及 ClusterRoleBinding 资源定义到 Kubernetes 环境

shell
kubectl apply -f dashboard-adminuser.yaml

第四步:访问 Dashboard

有几种方法可以访问 Dashboard,最简单的是通过 kubectl proxy

方法一:使用 kubectl proxy(推荐,安全)

  1. 启动代理: 这个命令会在你的本地机器(127.0.0.1)和 Kubernetes API Server 之间创建一个安全的代理通道。

    bash
    kubectl proxy

    代理启动后,会输出类似于 Starting to serve on 127.0.0.1:8001 的信息。让这个终端窗口保持运行。

  2. 访问 Dashboard: 现在,你可以在浏览器中访问以下 URL:

    http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/

    浏览器会打开 Dashboard 的登录界面。

方法二:使用 NodePort(不推荐用于生产,但有时更直接)

  1. 修改 Dashboard 服务类型: 默认的 Dashboard Service 是 ClusterIP 类型,只能在集群内部访问。我们可以将其改为 NodePort

    bash
    kubectl patch svc kubernetes-dashboard -n kubernetes-dashboard -p '{"spec": {"type": "NodePort"}}'
  2. 查找分配的端口

    bash
    kubectl get svc -n kubernetes-dashboard

    在输出中,找到 kubernetes-dashboard 服务,你会看到 PORT(S) 列类似 443:3xxxx/TCP。这里的 3xxxx 就是映射到你本地主机的端口号(NodePort)。

  3. 访问 Dashboard: 在浏览器中访问:

    https://<任意节点IP>:<NodePort>

    提醒

    重要提示:由于证书问题,浏览器会显示安全警告。你需要点击"高级" -> "继续前往" 才能继续。

方法三:使用 Port Forward(快速调试)

如果你只想快速测试,可以使用 Port Forward:

bash
kubectl port-forward -n kubernetes-dashboard service/kubernetes-dashboard 8443:443

然后访问:https://localhost:8443

第五步:获取令牌(Token)登录

无论使用哪种访问方法,你都会看到需要一个 TokenKubeconfig 文件来登录。我们使用之前创建的 admin-user 的 Token。

5.1 获取登录令牌

执行以下命令获取 admin-user 的 Token:

shell
kubectl -n kubernetes-dashboard create token admin-user
shell
kubectl -n kubernetes-dashboard get secret $(kubectl -n kubernetes-dashboard get sa/admin-user -o jsonpath="{.secrets[0].name}") -o go-template="{{.data.token | base64decode}}"

这个命令会直接输出一个很长的新令牌。复制整个令牌字符串

说明

  • Kubernetes 1.24+create token 命令会生成一个带有过期时间的短期令牌(默认 1 小时)
  • Kubernetes 1.23 及以下:从 Secret 中提取的令牌是长期有效的
  • 如果需要创建长期有效的令牌,可以手动创建 Secret,或使用 --duration 参数(如 --duration=8760h 表示 1 年)

5.2 登录 Dashboard

  1. 在登录界面,选择 Token
  2. 将刚才复制的令牌粘贴到输入框中。
  3. 点击"登录"。

登录成功后,你就可以看到 Kubernetes Dashboard 的管理界面了,可以查看和管理你的集群中的所有资源。

Kubernetes Dashboard 界面示意

第六步:后续配置建议(可选)

6.1 设置资源限制

在生产环境中,建议为 Dashboard Pod 设置资源限制。可以修改 kubernetes-dashboard.yaml 文件,在部署中添加:

yaml
resources:
  requests:
    memory: "256Mi"
    cpu: "100m"
  limits:
    memory: "512Mi"
    cpu: "200m"

6.2 启用 HTTPS 和 Ingress

如需通过域名访问 Dashboard,建议配置 Ingress 并启用 HTTPS:

yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: kubernetes-dashboard
  namespace: kubernetes-dashboard
spec:
  tls:
  - hosts:
    - dashboard.example.com
    secretName: dashboard-tls
  rules:
  - host: dashboard.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: kubernetes-dashboard
            port:
              number: 443

故障排除

ImagePullBackOff

确保网络连接正常,能够从 k8s.gcr.io(或其镜像仓库)拉取镜像。国内用户可能会遇到网络问题,可以考虑使用镜像源。

解决方案

  1. 修改 YAML 文件中的镜像地址为国内镜像源
  2. 或者手动拉取镜像到本地节点

无法登录

  • 确认你复制了 整个 Token,它非常长,确保没有遗漏开头或结尾的字符
  • 检查 Token 是否已过期(Kubernetes 1.24+ 默认 1 小时),可以重新生成
  • 确认 ServiceAccount 和 ClusterRoleBinding 已正确创建

权限错误

确保你已经正确创建了 ClusterRoleBinding 并将 admin-user 绑定到了 cluster-admin 角色:

bash
kubectl get clusterrolebinding admin-user -o yaml

浏览器无法访问

  • 确认 kubectl proxy 正在运行
  • 检查防火墙是否放行了相关端口
  • 如果使用 NodePort,确认节点 IP 和端口正确

Pod 一直处于 Pending 状态

检查节点资源是否充足:

bash
kubectl describe pod -n kubernetes-dashboard
kubectl top nodes

卸载 Dashboard

bash
# 删除 Dashboard 资源
kubectl delete -f kubernetes-dashboard.yaml

# 删除管理员账号
kubectl delete -f dashboard-adminuser.yaml

# 删除命名空间(可选)
kubectl delete namespace kubernetes-dashboard

参考链接


现在,你已经成功在你的 Kubernetes 集群中安装并运行了 Kubernetes Dashboard!🎉

附件

1. kubernetes-dashboard.yaml

点击查看详细的文件内容

如果您的网络环境无法访问 Github,可以使用博文提供的 kubernetes-dashboard.yaml,该文件与上面 wget 下载的文件内容完全一致!

kubernetes-dashboard.yaml
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. dashboard-adminuser.yaml

点击查看详情的文件内容

该文件与 3.1 编写 ServiceAccount 及 ClusterRoleBinding 资源定义文件 小节描述的文件一致!

dashboard-adminuser.yaml
yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kubernetes-dashboard
最后更新2026/07/07 07:32
如果你觉得这篇文章有帮助,或者想聊聊技术、工作,欢迎通过下面方式联系我:
contact fishfinal