K8S dashboard 无法访问这问题我在不同环境里至少遇到过十几次。很多初学者第一次部署完 Dashboard浏览器一打开要么白屏、要么一直转圈要么直接 Connection Refused百度一圈下来发现每个人答案都不一样反而越查越懵。其实这类问题的排查思路非常固定先分清访问路径再逐段定位。我写这篇文章把从现象到根因的排查顺序、修复方案、还有各种容易忽略的坑一次性讲清楚适合刚接触 Kubernetes 的运维同学也适合那些部署完 Dashboard 但访问总出问题的开发者参考。1. 访问方式决定排查方向先搞清楚你自己是怎么访问的1.1 两种主流访问方式kubectl proxy 与 NodePortK8S Dashboard 本身是一个典型的 Web 应用跑在集群内部的 Pod 里。默认情况下它没有对外暴露任何端口所以你想从浏览器打开它必须先建立一条从你的电脑到集群内部网络的通路。最常见的通路有两条一条是kubectl proxy另一条是把 Dashboard 的 Service 改成 NodePort 类型。这两条通路对应的故障现象完全不同。kubectl proxy方式下浏览器访问的是http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/如果这条路断了通常是本机代理进程没起来、鉴权文件不生效、或者 Dashboard 服务本身处于异常状态。NodePort 方式下你访问的是https://节点IP:端口这条路最容易出问题的是端口没放通、证书校验失败、以及节点 IP 选错。很多人在排查时根本不区分自己用的是哪种方式拿着 NodePort 的报错去搜kubectl proxy的解法自然怎么试都不对。记住这个原则先确认访问链路再谈修复。提示排障第一步永远是执行kubectl get pods -n kubernetes-dashboard确认资源状态。资源本身都是 Running 的话问题就在链路和配置上资源本身就异常那就先把资源修好。1.2 根据报错类型快速分类我习惯把 Dashboard 无法访问的报错分成三类每一类对应一组相对集中的排查范围第一类浏览器提示“无法访问此网站”“拒绝了连接请求”。这类问题基本与容器无关问题大概率出在端口暴露、防火墙策略、Service 配置上。你访问的目标地址压根没有一个进程在监听或者监听被防火墙挡掉了。第二类浏览器打开后显示“无法访问此页面”“403 Forbidden”或者证书警告。这类问题指向的是鉴权链路RBAC 权限不足、Token 无效、证书不匹配。Dashboard 的登录页本身是能出来的只是你登录之后没有权限看东西或者浏览器在握手阶段就拒绝了服务端证书。第三类页面能打开但一直加载、白屏、接口报错。这类问题往往是 Dashboard 的内部组件依赖出了问题最典型的就是 metrics-server 没装好Dashboard 首页请求指标数据时接口超时页面卡在加载状态。把报错归好类再去翻日志和配置效率会高很多。我见过有同事对着 403 的报错查了俩小时防火墙最后发现只是 ServiceAccount 的 Token 权限没给够方向从一开始就反了。2. 前置检查先看 Dashboard 资源本身是不是健康的2.1 Pod 状态与日志怎么看不管访问方式是什么Dashboard 的 Pod 必须处于 Running 和 Ready 状态。用下面这条命令能看到最直接的状态kubectl get pods -n kubernetes-dashboard -o wide输出的READY列如果显示1/1说明容器起来了且健康检查通过。如果显示0/1或者CrashLoopBackOff先看日志kubectl logs -n kubernetes-dashboard --tail50 pod-name我遇到过一种很隐蔽的情况Pod 状态显示 Running但READY是0/1。原因通常是启动参数里指定了--auto-generate-certificates但挂载的证书目录权限不对导致容器内进程反复重启虽然没到 CrashLoopBackOff但一直没准备好。这时候去看日志会发现报错信息大概是Failed to init certificate之类的内容。如果对 Pod 的启动参数不放心可以直接 describe 一下kubectl describe pod -n kubernetes-dashboard pod-name重点看 Events 部分里面会写清楚镜像拉取失败、探针失败、端口冲突这些常见启动问题。镜像拉取失败在离线环境或者网络受限环境特别常见解决办法是提前把镜像导入到私有仓库再把 Deployment 里的 image 地址改成私有仓库地址。2.2 控制面组件异常导致的次生问题Dashboard 无法访问还有一种很隐蔽的根源控制面组件异常。比如kube-apiserver负载太高或者 etcd 读写超时整个 API 响应变慢Dashboard 登录之后发出去的请求全部超时页面表现就是无限转圈。这种问题从 Dashboard 本身去看是完全正常的Pod 是 Running 的日志也没什么异常但你就是打不开页面。排查方法是在集群节点上查看 kube-apiserver 的指标或者日志kubectl get --raw/healthz如果返回不是ok那说明 apiserver 本身有问题。另外可以看 etcd 的健康状态但这里要提醒一句大多数 Dashboard 访问问题并不在控制面只有在其他排查手段都无效之后才值得把精力放到这个方向。毕竟控制面出了问题表现往往是集群整体都变得不稳定不太可能只影响 Dashboard 一个组件。3. 访问链路逐段排查从进程到端口再到路由3.1 kubectl proxy 方式下最常见的三个问题用kubectl proxy方式访问 Dashboard 时你会先在本地执行kubectl proxy --port8001然后浏览器访问http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/这条路出问题我总结下来有三个高频原因。第一个原因是本地 kubectl 的 kubeconfig 指向的上下文不对。proxy 本质上是拿你本地 kubeconfig 里的凭据去请求 apiserver如果你当前上下文指向的集群根本没有 Dashboard或者凭据没有权限访问kubernetes-dashboard这个命名空间那你在浏览器里看到的就是 403 或者 404。用kubectl config current-context确认一下当前上下文再用kubectl get svc -n kubernetes-dashboard确认服务名和端口基本就能定位。第二个原因是代理进程没起来或者端口被占用。执行kubectl proxy后终端不会退出而是卡在前台保持运行。如果你用的是旧版 kubectl日志里会有Starting to serve on 127.0.0.1:8001的输出看到这个才算代理启动成功。如果 8001 端口被别的程序占用把--port换一个比如 8002。第三个原因是 Dashboard 的服务名拼写错误。服务名大小写、命名空间拼写、https:前缀缺一不可。这个 URL 别自己手输很容易错直接从官方文档复制是最稳的。注意kubectl proxy默认只绑定127.0.0.1这是安全设计只能本机访问不能拿这个地址去其他机器上打开。如果你有远程访问需求要么用 SSH 隧道要么改用 NodePort 方式。3.2 NodePort 方式访问失败的要害在哪里把 Dashboard 的 Service 改成 NodePort 是很多人的第一选择因为改动最小。你的 Service 大概长这样apiVersion: v1 kind: Service metadata: name: kubernetes-dashboard-nodeport namespace: kubernetes-dashboard spec: type: NodePort selector: k8s-app: kubernetes-dashboard ports: - port: 443 targetPort: 8443 nodePort: 30001执行kubectl apply -f之后用kubectl get svc -n kubernetes-dashboard能看到分配的端口然后用https://node-ip:30001访问。这条路排障顺序应该是先确认 Service 的 ENDPOINTS 不为空再确认节点 IP 可达最后确认 TCP 端口放通。ENDPOINTS为空的情况很常见通常是 Service 的selector和 Pod 的标签不匹配。Dashboard 默认部署的 Pod 标签是k8s-app: kubernetes-dashboard如果你的 Service 写成了app: kubernetes-dashboard那永远匹配不上。执行kubectl get endpoints -n kubernetes-dashboard如果 ENDPOINTS 列是空的去查 Pod 的 labels把 Service 的 selector 改一致就行。端口放通是最容易被忽略的。很多云环境里节点安全组默认只放行 22、80、443 等常用端口30001 这种高位端口在安全组里根本没开。你在浏览器里访问不通但在节点本机用 curl 却能通那想都不用想是安全组或防火墙的事。解决办法去云平台的控制台放行对应端口或者在节点上检查 firewalld/iptables 规则。注意集群内如果用了网络策略插件比如 Calico 的 NetworkPolicy还得确认没有 NetworkPolicy 把 Ingress 流量挡掉。3.3 用 Ingress 访问时的证书与路径问题如果你在集群里配了 Ingress Controller比如 Nginx Ingress也可以走 Ingress 把 Dashboard 暴露出去。这种方式比 NodePort 优雅但坑也更多主要集中在路径重写和证书上。Dashboard 默认重定向和静态资源加载的路径逻辑比较复杂Ingress 配置里通常需要指定正确的rewrite-target。一个经过验证可用的 Nginx Ingress 配置片段大概是这样apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: dashboard-ingress namespace: kubernetes-dashboard annotations: nginx.ingress.kubernetes.io/backend-protocol: HTTPS spec: ingressClassName: nginx 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这里最容易踩的坑是backend-protocol没配置成 HTTPS。Dashboard 容器内部监听的是 8443 端口走的是 HTTPS 协议。如果 Ingress 默认按 HTTP 去和后端通信就会报 502 或者 400 Bad Request页面根本打不开。必须显式加上nginx.ingress.kubernetes.io/backend-protocol: HTTPS。证书方面在 Ingress 的 tls 段里指定的 secret 必须是包含证书和私钥的标准 TLS secret。生成方法很简单kubectl create secret tls dashboard-tls \ --certcert.pem \ --keykey.pem \ -n kubernetes-dashboard如果你还没有正式证书可以先自签一个用来测试但记得把浏览器的证书校验暂时改一下或者访问时手动信任否则浏览器会拦一道。生产环境还是建议用正规 CA 签发或者用云厂商的托管证书省心很多。4. 权限问题页面能开但登录后什么都看不到4.1 Token 登录与 kubeconfig 登录的区别Dashboard 登录页有两种方式Token 和 kubeconfig。很多人登录时手里只有一个 SA 的 Token直接粘贴进去结果进入页面后显示一堆红色报错什么资源都列不出来。这不是 Dashboard 坏了而是你这个 Token 对应的 ServiceAccount 权限不够。最简单的验证方式是先创建一个管理员权限的 ServiceAccount然后用它的 Token 登录kubectl -n kubernetes-dashboard create serviceaccount dashboard-admin然后创建一个绑定到cluster-admin角色的 ClusterRoleBindingkubectl create clusterrolebinding dashboard-admin-binding \ --clusterrolecluster-admin \ --serviceaccountkubernetes-dashboard:dashboard-admin拿到 Tokenkubectl -n kubernetes-dashboard create token dashboard-admin把输出的 Token 粘到登录页里就能进入完整的管理界面。注意新版 Dashboard 用kubectl create token而不是kubectl get secret去拿 Token因为 Dashboard 2.x 默认创建的 ServiceAccount 不会自动生成带长期 Token 的 Secret直接get secret往往找不到。提示生产环境不要随意把cluster-admin权限交给普通用户。更合理的做法是按需创建 Role 和 RoleBinding只授予 Dashboard 运维人员真正需要的权限。这个道理大家都懂但我在实际中见过太多次图省事直接给 cluster-admin 的例子。4.2 跨命名空间的权限报错处理有时候你用 Token 登录能进去Dashboard 主界面也正常但是点进某个命名空间看 Pod 就报forbidden。这种情况基本就是 RBAC 里没授对应命名空间的权限。如果你希望某个用户只能看production命名空间的资源可以这样配apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: production name: dashboard-viewer rules: - apiGroups: [] resources: [pods, services, endpoints, configmaps] verbs: [get, list, watch]再把该用户绑到这个 Role 上apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: namespace: production name: dashboard-viewer-binding subjects: - kind: ServiceAccount name: dashboard-viewer namespace: kubernetes-dashboard roleRef: kind: Role name: dashboard-viewer apiGroup: rbac.authorization.k8s.io很多人的误区是只配了 Role没配 RoleBinding或者 Role 里的 rules 漏了资源类型比如只给了pods权限但没给services那界面上能看 Pod 但看不到 Service也是一种“访问异常”的表现。排查时可以逐步加权限、逐步验证别一上来就怀疑网络。5. 那些不太起眼但能把人坑惨的细节5.1 metrics-server 缺失导致的卡顿与报错Dashboard 首页有图形化的 CPU、内存趋势图这些数据来自 metrics-server。如果集群里没有部署 metrics-serverDashboard 的图表区域会一直加载不出来甚至整个页面都显得非常卡。如何判断是不是 metrics-server 的问题执行kubectl top nodes如果报错error: metrics.k8s.io not found那就是 metrics-server 没装或者不正常。部署 metrics-server 不需要复杂的配置通常一条命令就能装好但要注意几个点metrics-server 需要以--kubelet-insecure-tls启动的旧版本配置在某些环境会被 kubelet 证书校验卡住新版本默认处理了大部分场景。另外如果集群用的是 Containerd 作为容器运行时有些旧版 metrics-server 需要额外配置建议直接装最新版本。装好之后验证kubectl top nodes如果能看到 CPU 和内存数据Dashboard 的图表基本就恢复了。我遇到过一个场景metrics-server 本身正常但 Dashboard 和 metrics-server 不在同一个集群或者说中间有网络策略隔离导致 Dashboard 连不上 metrics-server这种问题在跨节点网络策略比较复杂的集群里会出现需要检查 NetworkPolicy 是否放行了 metrics-server 的 443 端口。5.2 防火墙、安全组与本地代理的叠加干扰有时候问题不在集群里而在你的访问路径上叠加了太多层代理。比如你本机开着系统代理或者某类网络加速工具浏览器访问localhost:8001时把流量交给了代理结果代理把这个地址也转发到了外部最后什么都访问不了。这个问题很典型命令行里curl http://localhost:8001/healthz是通的但浏览器打不开。本质就是浏览器走了代理而命令行没走。解决办法很简单浏览器里给localhost和127.0.0.1配置 bypass 代理或者临时把系统代理关掉试一次。还有前面提到的安全组问题我再展开一下。如果集群中多个节点、多个网段混在一起你从办公网访问节点 IP 时中间可能还有一层云防火墙或者专有网络的访问控制。最有效的验证方法是找一个集群内节点在节点上用curl -k https://localhost:30001测试如果节点本地能通但你本地不通问题基本就锁在网络链路上。这时候用nc -vz node-ip 30001从你本地测一下端口输出如果是Connection refused说明节点上没有进程监听输出如果是 timeout 或 filtered那就是被防火墙丢了。6. 一次完整的修复案例从零部署到正常访问6.1 最小可用部署配置与步骤下面我把一套在我这边验证过、可以直接复制的最小部署配置写出来。前提是你已经有一个健康的 Kubernetes 集群kubectl 能正常连上集群。第一步部署 Dashboardkubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml注意新版 Dashboard 的官方推荐部署 YAML 会在kubernetes-dashboard命名空间下创建 ServiceAccount、Service、Deployment 等资源默认 Service 类型是 ClusterIP端口 443。第二步给 Dashboard 的 ServiceAccount 授权。Dashboard 官方部署里默认创建的 SA 是kubernetes-dashboard为了让登录用户拥有管理员权限我再创建一个专用 SAkubectl -n kubernetes-dashboard create serviceaccount admin-user kubectl create clusterrolebinding admin-user-binding \ --clusterrolecluster-admin \ --serviceaccountkubernetes-dashboard:admin-user第三步验证资源状态kubectl get pods -n kubernetes-dashboard kubectl get svc -n kubernetes-dashboard看到kubernetes-dashboardService 的 ENDPOINTS 不是空的Pod 是 Running继续下一步。第四步拿到登录 Tokenkubectl -n kubernetes-dashboard create token admin-user第五步启动代理并访问kubectl proxy浏览器打开官方文档给的那个 URL粘贴 Token 登录。整个流程下来正常情况下 5 分钟就能完成访问。如果是 NodePort 方式额外多一步把 Service 的 type 改成 NodePort或者另建一个 Service见 3.2 节。6.2 遇到报错时的精确日志查看命令排障时日志是最高效的证据。我在各种场景下总结了一套命令组合基本能覆盖 80% 的 Dashboard 访问问题# 查看 Dashboard 容器日志 kubectl logs -n kubernetes-dashboard deployment/kubernetes-dashboard # 查看 Dashboard 的 API 响应状态 curl -sk https://dashboard-svc-cluster-ip:443/healthz # 查看 Service 的端点 kubectl get endpoints -n kubernetes-dashboard # 查看 apiserver 是否健康 kubectl get --raw/healthz这四条命令组合下来容器层、服务层、控制面层一次扫清。日志里如果看到401 Unauthorized那就是 Token 问题404 Not Found多半是 URL 路径或服务名问题connection refused是服务监听端口的问题context deadline exceeded通常是 apiserver 响应超时去查控制面。举一个我实际处理过的例子某环境里 Dashboard 服务正常NodePort 也配了但浏览器一直转圈。日志里没有任何 ERROR。我执行kubectl get --raw/healthz发现返回forbidden再仔细看 kubeconfig 里的凭据已经没有集群权限了是证书过期。换了一个有效 kubeconfig 之后代理就能正常工作。这个例子说明很多“Dashboard 无法访问”本质上不是 Dashboard 的问题而是 kubectl 与集群之间的凭据失效。7. 实战经验心得与避坑清单7.1 几个我踩过最深的坑先说证书。Dashboard 默认会自动生成自签证书浏览器的提示是无法信任。如果你图省事点了“继续访问”在部分浏览器上后续请求依然会被拦尤其是新版 Chrome 对自签证书的限制越来越严格。我现在的习惯是直接用openssl自签一张带 SAN 的证书导入到本地信任库或者用 Ingress 的正规证书方案避免每次开页面都跟浏览器斗智斗勇。第二个坑是 Dashboard 版本和 Kubernetes 版本的兼容性。老版本 Dashboard1.x在 Kubernetes 1.22 之后的集群上大概率出现鉴权失败因为旧版用的一些 API 被移除或者改版了。如果你用的是很老的集群版本和很老的 Dashboard 版本第一时间先去查兼容矩阵别在配置上死磕。第三个坑是 etcd 或 apiserver 的慢请求。这种慢是间歇性的页面有时候能开有时候开不了非常迷惑。我把这个问题归到“资源健康”的范畴里是因为它确实可以通过查看 Dashboard 日志中的超时时间来判断。如果你看到proxy: context canceled这类信息那大概率是上游 apiserver 响应超时导致 Dashboard 代理断开而不是 Dashboard 本身的问题。这时候去查 apiserver 和 etcd 的负载、慢查询调整 etcd 的性能参数比反复折腾 Dashboard 配置有用得多。7.2 一张可以直接收藏的排查速查表我把最终的排查路径整理成表格遇到问题直接按这个顺序走现象优先排查辅助验证命令Connection RefusedService 端口、NodePort、安全组nc -vz node-ip port页面 403 / ForbiddenToken 权限、RBAC 绑定kubectl auth can-i --list页面白屏 / 一直转圈metrics-server、apiserver 负载kubectl top nodes、kubectl get --raw/healthz登录页打不开证书、Ingress backend-protocolcurl -kv https://address页面能开但列表异常ServiceAccount 的 Role 权限kubectl logs -n kubernetes-dashboard这张表不是万能的但它能帮你避免在错误的方向上浪费大量时间。我见过太多人把 403 当成网络问题查把证书警告当成入侵报警查来查去最后发现只是配置细节不一致。K8S 排障这件事九成的问题都出在链路和权限剩下的才是组件自身故障而链路和权限恰恰是最需要耐心逐段验证的。最后再分享一个小技巧任何 Dashboard 访问问题先用curl模拟请求别看浏览器。浏览器会缓存、会有代理、会有证书校验三种因素叠加起来真正的报错信息早就被吞掉了。命令行的错误输出是干净的是排障的第一手证据。遇到问题先问自己一句我这条路到底是怎么建立的然后按链路一段一段打通基本就成功了一半。
阅读完成 · 觉得有帮助?