首页 / 资讯中心 / 文章详情

K8s Dashboard无法访问?从链路拆解到七步排查全指南

K8s Dashboard无法访问?从链路拆解到七步排查全指南 ★ FEATURED ARTICLE
K8S dashboard 无法访问这大概是运维圈里被问得最频繁的五个字之一。我见过不少人集群里应用跑得飞起偏偏到了看面板这一步就卡壳白屏、超时、502、401各种姿势的进不去都有。这篇东西就老老实实把这类故障的排查思路完整走一遍从浏览器到 Pod 的每个环节拆开讲配合可以直接抄的命令和判断方法。刚上手 K8S 的朋友能拿着当排查手册被生产环境折磨过的老手也能查漏补缺。先说结论性的经验绝大多数“无法访问”不是 Dashboard 本身坏了而是你访问它的那条链路断在了某个中间环节。1. 先拆解一次访问到底经过几条链路1.1 从浏览器到 Pod必经的四个环节要排查这个问题脑子里必须有一幅完整的访问链路图。你在浏览器敲下地址到真正看到面板中间至少经历了四层转发入口层、Service 层、Endpoint 层、Pod 层。入口层是浏览器最先碰到的常见形态有三种kubectl proxy 的本地代理、NodePort 暴露出来的节点端口、Ingress 控制的域名入口。这一层负责“连接能不能建立”。然后请求到达 ServiceService 是 K8S 内部的负载均衡器它把流量转到后端的 Endpoint。Endpoint 是 Pod 的 IP 列表如果这里为空流量就直接断了。最后才是 Pod 里的容器进程也就是 Dashboard 应用本身。这个链条很像快递转运从发货地浏览器到最终签收Dashboard 页面中间任何一环掉链子结果都是“运单查不到”。这里有个容易忽略的点Service 和 Endpoint 是动态绑定的Service 通过 selector 标签选择 Pod只有 Pod 的标签和 Service 的 selector 对得上Endpoint 才会有数据。很多时候 Pod 明明在跑但因为标签对不上Endpoint 就是空的访问自然就失败了。1.2 把故障按症状分类三类问题对号入座“无法访问”是个太笼统的说法我在排障时会把症状归成三类每一类对应的排查方向完全不同。第一类是“完全连不上”。现象是浏览器转圈、连接超时、拒绝连接。这类问题基本出在入口层端口没放行、Ingress 控制器没起来、kubectl proxy 进程挂了。你的流量压根没进到集群内部。第二类是“连上了但没反应”。现象是访问后长时间白屏、请求挂起或者返回 502。这说明入口是通的但请求在 Service 转发、Endpoint 匹配、Pod 响应这个中后段出了问题。要么 Pod 没 Ready要么 Endpoint 为空要么容器进程假死。第三类是“有响应但内容不对”。现象是能打开登录页但报 403、登录后白屏、接口返回一堆 Forbidden。这类问题基本是权限和配置问题ServiceAccount 权限不足、Token 失效、Dashboard 版本和集群 API 版本不兼容。把这个分类刻在脑子里排障时先对号入座能省下一大半时间。1.3 排查顺序为什么要从外到里很多人遇到这种问题第一反应是去看 Dashboard 的 Pod 日志。我理解这种冲动但这是效率最低的路线。正确顺序应该是从外到里先确认离浏览器最近的那一环再一层层往里走。原因很简单链路是单向的入口不通里层再健康也没用。而且越靠外的环节排查成本越低。查看 Service 状态只需要一条 kubectl 命令而翻 Pod 日志往往要面对几千行无关输出。先花十秒钟确认入口层没问题再把火力对准真正可疑的里层这个习惯能让你避免大量无效操作。更重要的是从外到里排查时每一层都可以做一次“二分排除”。比如通过 kubectl port-forward 直接访问后端 Pod如果通了问题就锁定在入口或 Service 层如果还不通问题就在 Pod 自身。这一步一下就把排查范围缩小了一半。2. 最常见的断点藏在入口方式里2.1 kubectl proxy 方式的三处隐蔽坑kubectl proxy 是本地调试最常见的入口方式也是坑最密集的方式。很多人按网上的命令执行了一通打开浏览器却看到 403或者页面能打开但之后所有接口都报错。第一处坑是 Host 校验。kubectl proxy 默认只接受来自 localhost 的请求并且校验请求头里的 Host 字段。如果你在远程服务器上执行了 kubectl proxy然后在本地浏览器上通过 SSH 隧道访问本地的 Host 字段会被识别成 localhost正常。但如果你用了 NAT 或自定义域名转发就会触发 Host 校验失败直接返回大写的 403。解决办法是把 --accept-hosts 参数扩一下或者直接改用 SSH 隧道别折腾代理参数。第二处坑是 HTTPS 和 HTTP 的混用。新版 Dashboard 默认是 HTTPS 服务而 kubectl proxy 对非 HTTP 服务的转发在旧版本里需要加 --disable-filter 参数才能放行。如果不加你会发现页面打不开报“Invalid filter”一类的错误。这属于工具行为限制和 Dashboard 本身没有关系。第三处坑是代理进程本身不稳定。kubectl proxy 是前台进程终端一关就没了而且长时间跑会遇到连接池耗尽。很多“昨天还能访问今天突然不行”的案例其实就是代理进程挂掉了。所以用这种方式做日常访问并不靠谱更适合临时验证。2.2 NodePort 通了但外面进不来NodePort 是很多团队首选的暴露方式因为它不需要额外部署 Ingress 控制器。但它的问题出在“网络通路”上。第一步要确认 Service 的 nodePort 真的被分配了。执行 kubectl -n kubernetes-dashboard get svc查看 TYPE 列是不是 NodePortPORT 列最后有没有显示 3 开头的随机高位端口。有些 yaml 版本默认是 ClusterIP你直接访问节点 IP 加端口当然不通。第二步是安全组和防火墙。这是云环境里出现频率最高的问题。你在云控制台怎么都打不开但在集群节点上 curl 一下却发现端口是通的那十有八九就是安全组没放行这个端口。有个土办法屡试不爽在集群外的一台机器上执行 telnet 节点IP 端口如果 timeout 而节点本地正常基本可以确定是云平台的网络策略拦截。第三步是监听地址的问题。Dashboard Service 转发后端的端口是 443而 NodePort 是随机分配的节点上的 kube-proxy 会监听所有网卡的对应端口。但如果节点上有多个网卡或者你在云环境用的是私网 IP外部流量到了节点却不一定能命中 kube-proxy 的监听这是一个容易被忽略的小众坑。2.3 Ingress 方式的三类经典翻车Inssress 是把 Dashboard 暴露给外部最正规的方式但翻车案例也最多。最常见的三种情况我都踩过。第一类是 Ingress 控制器根本没运行。很多 K8S 发行版默认不带 Ingress 控制器你创建了 Ingress 资源它只是被记录下来没有实际负载去处理它。判断方法很简单kubectl get pods -n ingress-nginx如果控制器 Pod 不存在或者没有 Ready那问题就是这个。先去把控制器部署起来再回头看 Dashboard。第二类是 annotations 配置错误。Dashboard 后端是 HTTPSIngress 转发到后端时默认按 HTTP 去连接结果会得到后端返回的加密流量直接导致 502 Bad Gateway。这是我在实际环境里见到最多的 Ingress 问题。解决办法是在 Ingress 的 annotations 里强制指定后端协议为 HTTPS同时加上允许自签名证书的配置两条缺一不可。第三类是路径和 Host 不匹配。访问 Dashboard 的域名和 Ingress 规则里的 host 对应不上或者 path 前缀没写对都会导致 404。有一点特别容易犯Dashboard 是一个单页应用如果 Ingress 只把精确路径转发给后端而 Dashboard 内部的静态资源路径带着别的前缀就会出现页面框架能打开但样式全部丢失的情况。最省心的做法是直接用根路径或者确保 path 的 rewrite 规则处理到位。3. 服务与 Pod链路中段的排查要点3.1 Endpoint 为空比 Pod 挂掉更常见我处理过不少 Dashboard 访问失败的工单发现 Endpoint 为空这个问题的出现频率远远超过 Pod 挂掉。现象是 Pod 列表里明明显示 RunningService 也分配了 ClusterIP但浏览器就是访问不了。排查命令是这一条kubectl -n kubernetes-dashboard get endpoints如果 NAME 对应的 ENDPOINTS 列显示为空那问题就锁定在这里。Endpoint 为空的核心原因就两个selector 标签不匹配或者 Pod 的 ready 状态不满足。标签不匹配的场景在版本升级后容易出现你从官方 yaml 安装的 Dashboard 是新标签而 Service 的 selector 还停留在旧标签两边对不上Endpoint 自然没有数据。这种情况删掉 Service 里的旧 selector 改新标签就解决了。还有一种情况是 Pod 没有通过就绪探针的检查K8S 不会把流量转发给未就绪的 Pod。判断方法是用 kubectl describe pod 查看 Events看有没有 Probe failed 相关的字样。如果是拿旧资源文件直接 apply 出来的 DashboardRecipes 探针路径和存活探针路径可能在新版本容器里不合法导致探针一直失败。3.2 Dashboard Pod 自身的状态解读Pod 的状态是排查中段链路的窗口kubectl get pods 一眼扫过去几个高频异常状态要学会区分。CrashLoopBackOff 是最常见的异常状态。意思是容器启动后崩溃被 K8S 反复重启最终进入退避等待。这种情况九成是启动参数问题。Dashboard 的 Deployment 里如果传入了不合法的启动参数比如拼错了 Flags 名称、引用了不存在的 Secret、或者把需要两个参数的值写在了一起容器进程就会直接退出。有时候还跟 RBAC 有关进程启动时尝试获取某些资源列表被 API Server 拒绝代码逻辑直接 panic。ImagePullBackOff 也频繁出现意思是镜像拉取失败。这个状态在离线环境或者内网部署的场景尤其突出。解决办法通常是提前把镜像导入到私有仓库或者让节点用代理拉取。注意这里说的代理是容器运行时层面的配置涉及镜像下载通道的问题不是浏览器代理。还有一种伪健康状态Pod 显示 Running但容器内部进程因为内存压力持续 OOM。Dashboard 在管理大规模集群时会建立大量 informer 缓存默认资源限制不给够的话很容易触发 OOMKilled。这种情况看结局方法要看 restart 次数运行时间很短就加一次重启计数那就基本可以断定是内存问题。3.3 权限问题访问通了却一直报 403 的真相链路完全通畅登录页也出来了但是登录后一片报错、页面上的数据都刷不出来这是第三类问题的集中体现。很多人以为 Dashboard 坏了其实根因是 ServiceAccount 的权限不够。新版 Dashboard 默认使用 kubernetes-dashboard 这个 ServiceAccount它的权限非常受限只能看到很少的集群资源。如果你是用官方 yaml 直接部署的然后想用一个自定义的 Token 登录结果看到大量 403 Forbidden那几乎可以确定是 RBAC 角色没有绑定。要解决有两个方向临时验证就绑定 cluster-admin 集群管理员角色生产环境就得按最小权限原则新建角色把需要的 get/list/watch 权限配齐。绑定命令不难难的是敢不敢给权限。很多小伙伴不敢用 cluster-admin结果连最基本的 Pod 列表都刷不出来其实在封闭的测试环境里临时绑定一下是最高效的验证方式。还有一个坑藏在登录方式上。Dashboard 支持 Token 登录和 Kubeconfig 登录。用 Kubeconfig 登录时如果你本地的 Kubeconfig 是只读权限那即使 Dashboard 后端权限配得再高也会出现页面加载不出来。因为 Dashboard 会拿着你的 Kubeconfig 里的凭证去请求集群凭证权限不足就是不足。4. 七步实操从命令到恢复的完整闭环4.1 先跑一组基础命令确认现状聊完原理就到了打开终端动手的部分。我不建议一上来就盯着日志看先把下面这几条命令敲一遍每一行的输出都会告诉你一个方向。kubectl get ns | grep dashboard kubectl get pods -n kubernetes-dashboard -o wide kubectl get svc -n kubernetes-dashboard kubectl get endpoints -n kubernetes-dashboard kubectl get ingress -A | grep dashboard第一条看命名空间是否存在。如果连 namespace 都没有说明 Dashboard 压根没部署或者被部署到了其他命名空间。第二条看 Pod 状态、所在节点、重启次数。这一条能直接暴露 CrashLoopBackOff、ImagePullBackOff、OOM 这些核心问题。第三条看 Service 的类型和端口映射。重点看 TYPE、PORT 列判断当前到底是 ClusterIP 还是 NodePort端口对不对。第四条看 Endpoint。如果这里为空直接跳过去检查 selector 和 Pod 标签。第五条看是否配置了 Ingress以及它的地址和规则是否合理。这五条命令下来至少能把问题从“不知道在哪”缩小到具体某一段。4.2 七步排查法的每一步都干什么我把完整的排查过程抽象成了七步按顺序走完绝大多数问题都能定位。第一步确认 Dashboard 的资源是否都在。不是只看 Pod还要看 Deployment、Service、Secret、ServiceAccount 这些配套资源。我见过只 copy 了一份 Deployment yaml 就去部署的情况结果 Service 和 SA 全部缺失Pod 起来了但访问不了因为流量没地方可转。第二步看 Pod 健康状态。这里有一个关键技巧不要只看 Running 就放心还要看 READY 那一列是不是 1/1。如果显示 0/1说明容器起来了但没有通过就绪探针流量不会进来。第三步验证 Service 和 Endpoint 对应关系。用 kubectl get endpoints 查看如果为空就检查 selector。同时用 kubectl describe svc 看 Selector 字段和 Pod 的 labels 对比一下一秒就能发现问题。第四步用 port-forward 做后端连通性测试。这是整个排查里最有价值的一步它能帮你把问题从后面一刀切断。kubectl -n kubernetes-dashboard port-forward svc/kubernetes-dashboard 8080:443执行后本地浏览器访问 https://localhost:8080。如果这个能打开说明 Service 到 Pod 这一段是健康的问题在上层入口如果打不开再看 Service、Endpoint、Pod 这一层。第五步查日志。日志是最后一个手段但也是信息量最大的手段。用 kubectl logs 加 --previous 参数看上一次崩溃的日志很多 CrashLoopBackOff 的真实原因都藏在最后几行里。第六步检查权限。看 ServiceAccount、ClusterRoleBinding 是否存在Token 是否有效。这些验证命令不多但容易被漏掉。第七步回到浏览器侧检查。清缓存、试无痕窗口、检查本地代理设置、刷新 DNS这些看似无关的操作实际能解决不少“看起来是服务端问题”的访问故障。4.3 一次典型故障的现场复现与修复用一个我在模拟环境里反复演练过的案例来收尾这一部分现象比较有代表性。环境信息某集群部署了 Dashboard昨天还能访问今天通过 NodePort 地址打开就一直转圈最后超时。按步骤排查。先看 Podkubectl -n kubernetes-dashboard get pods输出显示 NAME 那一列是 dashboard-xxx-xxxREADY 是 0/1RESTARTS 显示 5。这说明容器反复崩溃。看看 describe 的 Detailskubectl -n kubernetes-dashboard describe pod pod-nameEvents 里出现了 Back-off restarting failed container还有 Liveness probe failed 和 OOMKilled 的痕迹。看日志kubectl -n kubernetes-dashboard logs pod-name --previous日志末尾是大量 failed to create informer 和 watch of xxx was interrupted 之类的报错。进一步查看 Deployment 的资源限制发现 limits.memory 被设置成了 64Mi这个值对 Dashboard 来说太小了启动后 informer 缓存一撑直接被打进 OOM。解决方案是调大内存限制并去掉不必要的启动参数 --namespace 限制让 Dashboard 可以正常监听集群事件kubectl -n kubernetes-dashboard edit deployment kubernetes-dashboard把 limits.memory 改到 512Mi删除 --namespace 参数保存后等滚动更新完成。再看 Pod 状态变成 Running 并且 READY 1/1。然后执行 port-forward 测试本地浏览器能打开登录页再把 NodePort 的安全组和防火墙规则检查一遍全链路恢复。这个案例说明了为什么我一直强调从外到里看问题如果你第一眼看到 OOMKilled 就只调内存不检查入口还是一样的不通。5. 高频问题速查与避坑心得5.1 大概率能命中的问题对照表把问题场景和对应解法整理成一张表适合保存下来当成手册用。症状最可能原因快速验证解决办法页面转圈超时NodePort 未放行 / Pod 未 Readytelnet 节点IP 端口查安全组、防火墙检查 Pod states502 Bad GatewayIngress 后端协议错误curl 一下后端服务Ingress 增加 backend-protocol: HTTPS404 找不到页面Ingress path 不匹配查看 ingress rules调整 path 或 rewrite 规则401 UnauthorizedToken 无效或过期重新获取 token新建 Token 并使用正确的 SA403 ForbiddenRBAC 权限不足describe binding绑定 cluster-admin 或放宽角色权限登录后白屏SA 权限不足 / 版本不兼容浏览器的 Console 看请求报错先解除权限问题再考虑升级证书警告自签名证书查看证书详情浏览器添加例外或替换正式证书CrashLoopBackOff启动参数错误 / OOM查看日志或 describe修正启动参数调高内存限制这张表覆盖了我遇到过的绝大多数真实案例尤其是在开发环境排名前三的问题是 NodePort 未放行、RBAC 权限不足、Ingress 后端协议错误。5.2 实操中反复踩过的一些坑第一坑改完配置不滚动重启。修改了 Deployment 或 Service 之后想当然以为配置会自动生效结果访问还是老样子。这里要记住核心操作deployment 的 liveness 和 readiness 探针配置变更后Pod 不会自动重建必须手动 rollout restart否则探针还拿旧的配置跑。第二坑端口清理不干净。NodePort 模式下如果你删除了一个旧 Service 重建新的旧的 nodePort 可能还在被防火墙安全组占用新 Service 的 nodePort 却换了另一个端口你在外部访问的还是旧端口当然不通。每次改完 Service 都要重新确认一下当前的 nodePort 是多少。第三坑多集群环境下 kubectl context 切错。这个坑特别隐蔽你明明在 A 集群排查但当前 context 指向的是 B 集群所有 kubectl 命令返回的都是 B 集群的资源查了一整天才发现查错对象。排查前第一件事就是执行 kubectl config current-context确认操作的是目标集群。第四坑Dashboard 版本和集群版本不匹配。我见过集群还是较老版本却装了一个很新的 Dashboard结果打开界面之后一堆 API 请求 404。Dashboard 的兼容性通常要求集群版本不能太落后升级前先看一眼兼容矩阵别想当然用 latest 标签。5.3 直接给结论更省事的替代方案如果 Dashboard 反复折腾还是不稳我个人的建议是不妨看看替代工具。k9s 是一个基于终端的 K8S 管理工具启动速度快资源占用极低不需要浏览器不需要暴露端口SSH 到节点就能用。很多排查工作我用 Dashboard 要翻好几页 UI 才能完成k9s 里敲几个字符就搞定了。另一个方向是 Web 端用开源的管理面板这类工具的暴露方式和权限模型比官方 Dashboard 更好控制稳定性也经过了大量生产环境的检验。但 Dashboard 依然有不可替代的位置它直观展示集群资源使用情况适合给团队里非运维角色使用也适合做演示。这篇内容虽然花了大量篇幅讲“访问不了”怎么查但其实掌握了这些排查思路任何 Web 应用在 K8S 集群里的访问问题都能套用。最后提醒一句排障时保持冷静按链路一层层来绝大多数的“无法访问”都只是链路上一小块拼图错位了。
阅读完成 · 觉得有帮助?
咨询建站