
把Kubernetes集群用熟之后我最大的一个感受是命令行确实高效但它不适合“看”。集群里跑了几十个工作负载、上百个Pod的时候用kubectl一条一条地查状态、翻日志、看事件效率低得令人抓狂。Kubernetes Dashboard就是来解决这个问题的——它是Kubernetes官方维护的Web可视化管理界面把节点、工作负载、服务、配置、存储的实时状态都摆到浏览器里能看Pod日志、能进容器、能直接编辑YAML还能按角色分配只读或管理权限。这篇文章按我自己从部署到落地的完整过程来写适合刚接触Kubernetes的开发和运维新人也适合集群已经跑了一段时间、正想补上可视化监控这块短板的团队。内容会覆盖版本选型、部署、登录、日常可视化管理、常见故障排查最后说说生产环境安全加固。1. 版本匹配与环境准备开局决定结局1.1 为什么选官方Dashboard而不是其他可视化工做可视化方案的时候我其实先看了一圈“别人家”的东西。有的多集群管理平台功能确实全但组件太重部署完还要维护一套独立数据库对单集群团队来说明显杀鸡用牛刀有的桌面客户端工具界面漂亮可它装在个人笔记本上团队成员每人得配一套环境出了问题很难在服务器上远程排查还有的终端交互工具适合习惯敲命令的人但给值班同学看板用还是少了点“所见即所得”的感觉。在模拟项目X里我见过团队为了可视化上了一套重型平台光部署就要好几台机器学习成本高日常没人维护最后变成了摆设。而官方Dashboard对手上只有一两套集群、又不想引入额外基础设施的团队来说是最务实的选择。它只包含一个命名空间下的几个组件卸载干净升级简单社区里能搜到的问题案例也最多。对大多数场景来说官方轻量方案的性价比是最高的。1.2 Dashboard版本与Kubernetes版本怎么对应版本匹配是很多人上来就翻车的点。Dashboard本质上是Kubernetes API的客户端它要调用集群的接口来读数据而不同Kubernetes版本的API能力在持续变化旧版Dashboard用的某些接口可能在新集群里被废弃新版Dashboard又可能要求比较新的集群环境。版本不对最典型的现象是组件反复崩溃页面一直打不开日志里全是接口兼容性报错。我建议先跑一下命令确认集群版本再选择对应的Dashboard版本kubectl version kubectl get nodes -o wide参考对照关系如下Kubernetes版本推荐Dashboard版本说明1.19 ~ 1.23v2.6.x老集群稳定之选1.24 ~ 1.27v2.7.x覆盖面最广资料最多1.28v3.0.x新版界面要求较新的集群能力我在一个1.21版本的测试集群上直接把v2.7.0的yaml套进去Pod起来以后接口陆续报错回退到v2.6.x才恢复正常。所以别嫌这一步麻烦先把对应关系确认好后面能少折腾一晚上。1.3 环境检查清单部署之前我习惯一次性把环境确认完避免中途反复横跳kubectl能正常访问目标集群当前context确实指向要操作的集群。多人共用服务器时坑过很多次操作前先kubectl config current-context看一眼。已经确认集群版本并决定好Dashboard版本。准备一个可用的公共镜像源地址。官方自带的镜像地址在部分网络环境下拉取很容易超时提前想好替换方案后面我会专门讲。浏览器用新版Chrome或Edge。某些老版本浏览器对自签证书和WebSocket支持不太好会导致页面转圈。如果你用的是各云厂商的托管集群操作步骤和自建集群几乎没有区别按下面的流程走就行。2. 部署实操一条命令只是开始2.1 部署主组件Dashboard官方提供了一整套整合好的yaml一条命令就能把这些资源全部创建出来kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml这条yaml里包含了命名空间、ServiceAccount、Secret、ConfigMap、Deployment、Service这些资源。我拆开说明一下设计思路所有组件都收在kubernetes-dashboard这个命名空间里后面升级、卸载都很干净默认Service类型是ClusterIP也就是说正常情况下集群外根本访问不到这种默认最安全也不容易被误暴露。apply之后先看Pod状态这是最容易出问题的环节kubectl get pods -n kubernetes-dashboard -o wide如果显示Running并且READY是1/1主组件就算起来了。推荐顺手看一眼日志确认没有隐藏报错kubectl logs -n kubernetes-dashboard -l k8s-appkubernetes-dashboard --tail50日志里没有连续的ERROR基本可以放心进入下一步。2.2 镜像拉不下来的兜底方案我在不少环境里都遇到过Pod卡在ImagePullBackOff的情况。这不是配置错了而是节点拉取官方镜像超时或者直接被环境策略拒绝。处理方法很直接把Deployment里的镜像地址替换成你的环境能访问的仓库地址。kubectl -n kubernetes-dashboard edit deploy kubernetes-dashboard找到containers下面image字段比如默认的kubernetesui/dashboard:v2.7.0把前缀替换成你准备好的公共镜像源地址比如镜像仓库地址/kubernetesui/dashboard:v2.7.0保存退出。Deployment会自动触发滚动更新再观察Pod状态即可。这里有个经验与其等报错了再改不如部署前就把yaml下载下来全局替换wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml sed -i s#kubernetesui/dashboard:v2.7.0#镜像仓库地址/kubernetesui/dashboard:v2.7.0#g recommended.yaml kubectl apply -f recommended.yaml公司内网环境更常见的做法是先把镜像推到内网私有仓库再把yaml里的image全部改成内网地址这样后续CICD或者新节点扩容都不会被外网波动影响。2.3 确认Service状态主组件起来了还需要确认Service是否正常kubectl get svc -n kubernetes-dashboard看到kubernetes-dashboard这个Service存在并且端口是443说明服务端已经准备好了。到这里部署阶段结束后面全是账号和访问的事情。3. 账号创建与访问方式登录是最大的坎3.1 创建管理员ServiceAccountDocker刚装好的Dashboard是不会让你登录的因为它默认没有任何账号有权限这是出于安全设计。很多新手在这一步直接卡死以为是部署坏了其实只是缺一个“人”。我需要创建一个ServiceAccount再通过ClusterRoleBinding把集群管理员角色绑给它。保存下面内容为admin-sa.yamlapiVersion: 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执行kubectl apply -f admin-sa.yaml简单解释一下这里的权限模型ServiceAccount相当于登录身份ClusterRoleBinding相当于门禁授权。cluster-admin是集群内置的最高权限角色绑上去之后这个账号就能管理整个集群。这个账号建议只给负责集群初始化和管理的人用不要全员共享后面我会讲怎么按需给只读权限。3.2 获取登录Token从Kubernetes 1.24开始系统不再为ServiceAccount自动生成长期有效Token最省事的方式是用kubectl直接签发一个kubectl -n kubernetes-dashboard create token admin-user输出的那一长串就是登录令牌。不过默认签发的Token有效期很短如果想减少反复签发的频率可以加时长参数kubectl -n kubernetes-dashboard create token admin-user --duration 8760h如果还是老版本Kubernetes也可以从Secret里取Tokenkubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret -o name | grep admin-user)拿到Token之后在Dashboard登录页选择“令牌”方式粘贴进去就能进入主界面了。3.3 三种访问方式怎么选访问方式决定了Dashboard以什么入口暴露给使用者我实际用下来有三个选择各有取舍。第一种是kubectl proxy只在执行命令的本机有效kubectl proxy然后浏览器打开http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/这种方式的优点是完全不动集群里的Service关闭proxy就断开了访问适合在服务器上临时排障安全风险最小。缺点是只有本机能访问没法给别人用。第二种是NodePort适合内网测试和给团队成员临时访问kubectl -n kubernetes-dashboard patch svc kubernetes-dashboard -p {spec:{type:NodePort}}查看分配到的端口kubectl -n kubernetes-dashboard get svc kubernetes-dashboard输出里的端口形如31234访问地址就是https://任意节点IP:31234。注意地址栏一定要写https并且接受自签证书的告警。这种方式改一下Service类型就行简单粗暴但一般不建议生产使用因为只要节点IP可通任何人都能摸到登录页。第三种是Ingress生产环境我最推荐。Service保持ClusterIP不变由Ingress把域名转发到Dashboard服务同时在Ingress上挂正式TLS证书。需要注意Dashboard后端是HTTPS服务Ingress的后端协议要配置成HTTPS否则会出现反复重定向、页面一直加载不出来的情况。入口统一走域名后续在Ingress层做访问控制、日志记录都方便。4. 可视化管理实操从看到到操控4.1 界面模块怎么看登录之后默认进入“概览”页左侧菜单的布局和kubectl操作的对象一一对应集群命名空间、节点、持久卷、存储类、角色等集群级资源工作负载Deployment、StatefulSet、DaemonSet、Pod、Job、CronJob服务与发现Service、Ingress、Endpoint配置ConfigMap、SecretSecret里的内容会脱敏显示要查看明文只能进入详情再点显示存储持久卷声明、持久卷顶部可以切换命名空间默认看全部。资源多的时候按命名空间过滤能让列表清爽很多——我遇到过整个集群一百多个Pod铺在一个页面里想找某个出问题的服务全靠人眼扫描后来都是先选命名空间再筛选。页面右上角可以调自动刷新间隔默认的刷新已经够用。看板的价值在于“一眼扫过去发现问题”所以刷新间隔别调太短5秒到30秒比较合适时间太短反而容易分散注意力。4.2 看日志、看事件、进容器点进任意一个Pod顶部有详情、日志、终端几个页签。日志页的“上一容器”开关强烈建议记住容器崩溃重启过的话当前日志只会显示重启之后的内容崩溃前的输出全在“上一容器”里。我在模拟项目X里排查过一次内存溢出导致的OOM重启就是靠这个开关看到了崩溃前的异常堆栈才知道问题出在业务代码的缓存没有上限而不是环境配置。Pod详情下面的“事件”区域同样重要。调度失败、镜像拉不出来、健康检查没通过原因都列在这里。以前这些信息必须kubectl describe才能看到现在浏览器里直接展示排障效率完全是两个档次。还有一个我经常用但很多人不知道的功能Pod页面右侧的“终端”按钮可以直接进入容器里的shell等于kubectl exec的Web版。临时看环境变量、检查进程、手动跑一条命令都不需要再开终端敲命令尤其适合借给不熟悉命令行的同事做联调。4.3 让CPU和内存曲线显示出来Dashboard刚装完时工作负载页面看不到实时CPU和内存曲线只能看到YAML里声明的请求与限制。这是因为Dashboard需要metrics-server提供指标数据而metrics-server不会随集群自动安装要单独部署kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml装完验证一下kubectl top nodes能输出节点CPU和内存使用率说明指标链路已经通了。回到Dashboard刷新页面Pod列表就会出现资源使用曲线和实际使用量排查某个服务是不是吃满了配额时非常直观。这里有个常见坑如果集群的kubelet证书是自签的metrics-server会一直报x509证书错误kubectl top没有输出。处理方式是在metrics-server的Deployment里加一个启动参数- --kubelet-insecure-tls然后重启metrics-server。加参数这个动作只在可控内网环境里建议使用生产环境还是要正规处理证书链路不能让所有节点都跳过证书校验。4.4 在Web界面里直接创建资源页面上方的“”号可以创建资源支持表单和YAML编辑器两种方式。给某个命名空间临时起一个调试用的Pod时我通常直接切到YAML模式粘贴定义选好命名空间点上传几秒钟就能在列表里看到它。这个能力对不熟悉kubectl的同事特别友好。团队里做演示、联调或者临时验证时直接在页面里改副本数、加环境变量就行不必每次都教我“你要先这样再那样”。当然页面上能做的不等于生产上就可以随便做正式变更我仍然建议走版本库加审核流程页面操作更适合临时排障和演示场景。5. 常见问题与排查实录5.1 Token失效与登录404现象一前一天还能正常登录今天粘贴Token进去提示未授权。原因多半是Token过期了。用kubectl create token签发的Token默认有效期很短约1小时。要么重新签发要么签发时加上--duration参数拉长有效期日常使用建议至少给到按周计算。现象二登录后直接跳到404页面。最常见的是ServiceAccount和ClusterRoleBinding里的namespace对不上或者没有正确绑定cluster-admin。回到admin-sa.yaml确认两个资源的namespace都是kubernetes-dashboardserviceAccountName大小写完全一致重新apply后重新签发Token再登录。5.2 浏览器提示证书过期Dashboard默认会自动生成自签证书部分版本的证书有效期很短过一段时间浏览器就会强拦截。最直接的恢复办法是删掉原有证书Secret让Dashboard重新生成kubectl -n kubernetes-dashboard delete secret kubernetes-dashboard-certs kubectl -n kubernetes-dashboard delete pod -l k8s-appkubernetes-dashboard等新Pod起来后清掉浏览器缓存再访问。浏览器有时会缓存旧的证书状态开无痕窗口验证最省事。5.3 访问地址空白或一直转圈最常见的原因是用了http而不是https。Dashboard服务监听在HTTPS端口用http访问时服务端要么拒绝要么反复重定向页面就一直白屏转圈。先确认地址栏写的是https并接受自签证书告警。如果协议没问题还是转圈打开Dashboard的Pod日志看输出很多情况下日志会直接说明是连接被重置还是证书不匹配比在浏览器里猜快得多。5.4 权限不足403的处理思路登录之后能看到界面但打开某个资源时报403这不是Dashboard坏了而是当前账号的RBAC权限不够。查一下当前Token对应的ServiceAccount绑定了哪些角色view只能读edit可以改但不能删cluster-admin是全权限。按实际需要调整绑定不要图省事给所有人发cluster-admin权限收得越紧出事之后影响面越小。6. 生产环境安全加固建议6.1 给只读成员建独立账号日常值班的同学大多数只需要看不需要改。我一般会单独建一个只读账号名字直接叫readonly-user绑定内置的view角色apiVersion: v1 kind: ServiceAccount metadata: name: readonly-user namespace: kubernetes-dashboard --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: readonly-user roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: view subjects: - kind: ServiceAccount name: readonly-user namespace: kubernetes-dashboard这样他们能看到集群全貌但改不了任何资源就算账号泄露破坏面也可控。管理操作还是集中在管理员账号上。6.2 网络接入层要收紧NodePort一旦放开任何能访问到节点IP的人都能看到登录页自签证书挡不住持续的暴力尝试。生产环境我强烈建议只保留一种入口用Ingress加正式TLS证书并在Ingress层做好基本访问控制。如果云环境有安全组再把允许访问Dashboard的IP白名单范围缩小。既然已经上了Ingress就别留着NodePort避免同时开两个口子还容易忘。6.3 Token轮换与kubeconfig登录长期Token用起来方便但泄露风险也大。建议定期重新签发别一个Token用半年。Dashboard登录页支持切换“Kubeconfig”页签上传权限范围较小的kubeconfig文件直接登录权限跟着文件里的用户走比到处粘贴Token干净。给团队成员分配凭证时按角色生成不同权限的kubeconfig也方便一人一证、事后追溯。6.4 我实际使用中的一点体会Dashboard这类可视化工具最大的价值不是替代kubectl而是降低“看集群”的门槛。以前群里有人说服务挂了我要先问命名空间再拉日志再看事件来回好几轮才能定位。现在把只读账号开放给值班同学他们自己打开页面就能看到错误原因很多基础排查根本不会传到我这来。最后再分享一个从踩坑里得来的习惯每次升级Dashboard之前先去官方Release页面看兼容性说明再在测试集群上把登录、看日志、进容器这几个核心动作完整跑一遍确认没问题再动生产。可视化工具看起来不起眼可大家都等着用它的时候它自己先挂了才是最折腾人的场景。