dsh-kube-lens:给 DSH 加一个默认只读的 Kubernetes 集群浏览器

前言

用 DSH 的 Web GUI 排查集群问题时,常见的做法是开着终端敲 kubectl,回头再把结果贴回对话。kubeconfig 里的凭证可能是客户端证书、bearer token、exec 凭证插件(aws / gcloud / azure)或 auth-provider 片段,插件要自己重写一遍这套逻辑很容易出错,而且集群一多就要反复切换文件和 context。

下面介绍的 atticuswx/dsh-kube-lens 就是为这件事做的插件。它让插件侧边栏多一个 Kubernetes 图标,主区是资源浏览器,同一套操作也暴露成 Agent 工具,免去在终端和 Web 界面之间来回切换。

这是什么

一句话定位:通过 kubeconfig 访问集群的 DSH 插件,把 kubectl 包装成面板和 Agent 工具,默认只读。

  • 维护者:atticuswx
  • 许可证:MIT
  • 版本:代码里标注为 0.3.0(package.json 的 version 字段,以及 dsh plugin add 支持的 v0.3.0 tag)
  • 分类:admin-security 方向,面向集群读操作与权限控制
  • 不引入额外依赖:所有集群访问都走宿主机上的 kubectl,插件本身不重写凭证逻辑

需要先明确一点:它依赖宿主机已有 kubectl(Rancher Desktop 通常在 ~/.rd/bin/kubectl),以及支持 Web client bundle 的 DSH。包里没有构建步骤,client.js 由浏览器直接加载。

安装与启用

从 GitHub 安装:

dsh plugin --profile web add github:atticuswx/dsh-kube-lens

装完刷新页面,侧边栏会出现 Kubernetes 图标,点开就是集群浏览器。想锁定版本,在地址后面加 tag:

dsh plugin --profile web add github:atticuswx/dsh-kube-lens#v0.3.0

本地开发(改代码即时生效):

git clone https://github.com/atticuswx/dsh-kube-lens.git ~/dsh-plugins/dsh-kube-lens
dsh plugin --profile web add ~/dsh-plugins/dsh-kube-lens

插件挂到 --profile web 上,意味着只有 Web GUI 会有这个面板;Agent 工具在同一个宿主进程里可用。

装完之后有什么

  • 侧边栏出现 Kubernetes 图标,点开是集群浏览器。
  • Agent 多出 6 个只读工具:kube_contexts、kube_get、kube_describe、kube_logs、kube_events、kube_diagnose。
  • 默认只读。写操作关闭时,kube_write 工具和面板上的写按钮都不出现。

配置

配置写在 cordis.patch.yml 的 config 里,改完后需要重新加载插件。

键 默认 说明
kubeconfigPaths [] 额外/指定的 kubeconfig 文件列表,多个文件按 kubectl 的合并规则一起读。空表示 $KUBECONFIG,再空就是 ~/.kube/config。
kubectlPath '' 固定 kubectl 路径。空表示自动探测:PATH、~/.rd/bin、/usr/local/bin、/opt/homebrew/bin。
context '' 默认 context。空表示用 kubeconfig 的 current-context。
namespace '' 默认命名空间。空表示 default。
allowWrites false 打开后才有 kube_write 和面板写按钮。
requestTimeoutMs 20000 单次 kubectl 超时。

如果不想动配置文件,面板右上角的 kubeconfig 按钮可以随时增删 kubeconfig,改完立即生效。几个坑 README 里写得很具体:每个 context 只用它所属的那个文件,不做跨文件按名合并,原因是两个 kubeconfig 常常都把 cluster 叫作 kubernetes,kubectl 合并时只保留第一个,另一个 context 会被指向错误的 API server,表现为 Unauthorized。列表为空时回落到 $KUBECONFIG,再回落到 ~/.kube/config。保存位置是 $DSH_HOME/kube-lens.json(默认 ~/.dsh/kube-lens.json),可以手改,自定义的显示名也存在这里,按 kubeconfig 文件记录,换路径后不会错位。

浏览与搜索

面板的交互按集群浏览器的常见习惯做,几条值得记的:

  • 顶部显示 kubeconfig 文件名(如 prod-cluster),而不是那串 123456789012345678-… 的 context id;hover 能看到完整 context、server 和文件路径。
  • 一个过滤条同时管命名空间和搜索,左边是命名空间触发器(「全部命名空间」或某个具体命名空间),右边直接过滤资源名称;/ 聚焦输入框,Esc 清空或关闭菜单。
  • 「只看异常」按 READY / STATUS 列筛选:未就绪(0/N)或处于 CrashLoopBackOff、ImagePullBackOff、Pending、Error 等状态的对象,用来第一时间定位问题实例。
  • 计数显示为 匹配数/总数,筛选是纯客户端的,不会因为输入而反复请求集群,切换命名空间才会重新请求。

键盘方面,点击列头在 升序 → 降序 → 取消 之间循环,CLUSTER-IP、PORT(S)、CAPACITY 不可排序;表格中 ↑ / ↓ 移动行焦点,Home / End 跳首尾行,Enter 或 Space 打开详情;详情页用 Esc 或左上角返回回到列表,焦点落回进入详情的那一行。

详情页:YAML 与日志

详情页有两个 tab:YAML 和 日志(0.3.0 新增)。

YAML tab 的编辑器是 CodeMirror 6(@codemirror/lang-yaml),打包在插件的 viewer.js 里,不走 CDN,离线可用;只在第一次打开时按需加载,加载失败自动退回只读的 <pre> 视图。支持语法高亮、行号、折叠、括号匹配、撤销/重做、自动换行和 ⌘F 查找,另有复制、下载为 <kind>-<name>.yaml、格式化(保留注释)、还原四项操作。编辑时实时做 YAML 语法校验,错误行内画波浪线,有未保存改动时 tab 上出现小黄点。

「保存到集群」只在 allowWrites: true 时可用,点击后出现显示 kubectl apply -f - 的确认条,确认后才执行。三种情况自动只读,避免把脱敏或不完整的内容写回集群:Secret、清单超过 24k 字符被截断、读取失败。

日志 tab 通过 SSE 持续接收 kubectl logs -f --timestamps 的输出,默认滚底,向上翻看时暂停并显示「回到最新」。搜索框高亮全部匹配,Enter / Shift+Enter 跳到下一个/上一个。支持 200–2000 行 tail、复制全部、下载带时间戳的原始日志;多容器 Pod 会列出容器 tab,有重启时多出「上一次运行」快照。连接断开后自动重连,用上一次时间戳 --since-time 补漏并按时间戳去重,只保留最近 5000 行。离开该 tab 会断开 kubectl 子进程,避免后台一直 tail。

写操作与 Secret 保护

配置里 allowWrites: true 之后:

  • kube_write 的每次调用都先向用户发一次性审批,和 bash 工具的审批同一个通道;拒绝、取消、通道不可用,一律不执行。
  • 面板上的滚动重启、扩缩容、删除 Pod 先弹确认框,再走 /kube-lens/api/write。
  • 详情页 YAML 的「保存到集群」先出现确认条,再走 /kube-lens/api/apply;服务端还会再次检查 allowWrites、拒绝 Secret、拒绝一个清单里出现多个顶层 kind。

Secret 的处理是独立的一层:Secrets 的内容从不返回,kube_get 的 YAML 和面板 YAML 页对 Secret 只显示 type 和键名,面板 YAML 页对 Secret 强制只读,保存接口也会拒绝。日志、事件、清单照常返回。对一个面向运维场景的插件来说,这条策略比「先读出来再说」更省事——误贴 secret 到对话的风险从一开始就不存在。

Agent 工具与 kube_diagnose

六个工具都是对同一套 kubectl 调用的封装。其中 kube_diagnose 的设计值得单独讲:一次调用返回容器状态、重启次数、上次退出码与终止原因、调度失败事件、Service 的 Endpoints 覆盖、上一次运行和当前的日志尾巴,并给出结论化的 findings。

判断规则是启发式,每条结论都附证据:

  • ImagePullBackOff / ErrImagePull → 镜像或仓库凭证
  • CrashLoopBackOff → 重启次数 + 上次退出码
  • OOMKilled → 内存 limit
  • CreateContainerConfigError → 引用的 ConfigMap/Secret
  • Pending + FailedScheduling → 调度器原话
  • Running 但未 Ready → 就绪探针
  • Service 无 Endpoints → 区分「selector 打错」和「Pod 不 Ready」
  • Node 的 Ready / MemoryPressure / DiskPressure / PIDPressure

对 Agent 工作流来说,这个输出格式比直接扔一段 kubectl describe 更容易被下一步动作消费。

已知边界

  • 只实现 Pod / 工作负载 / Service / Node 的深度诊断;其它资源回退到 kubectl describe。
  • 还没有 exec、port-forward;YAML 保存走 kubectl apply,只在 allowWrites: true 时出现,并且需要面板确认。
  • 集群不可达时,工具返回「集群不可达 + server 地址 + 下一步」,而不是 kubectl 的原始堆栈。

适用场景与注意

适合已经在用 DSH Web GUI、希望 Agent 能直接读集群状态再做判断的场景,尤其是集群数量不多、已有 kubectl 环境的团队。诊断工具对 Pod / Service / Node 这几类资源比较有针对性,其它资源只是 describe 转发,不要指望它做全套审计。

安装前照例注意两点:插件以当前 dsh 进程的权限运行,等价于该进程能访问你配置的 kubeconfig 里的全部集群,所以装之前先过一遍源码(仓库文件列表里已列出 index.js、kube.js、diagnose.js、cordis.patch.yml 等)和 MIT 许可证;另外确认宿主机的 kubectl 位置可用,Rancher Desktop 用户如果 PATH 里没有,可以显式配置 kubectlPath。

项目还很早期,公开仓库的星标数据很少,主要是作者个人维护,遇到问题倾向于在仓库 Issues 里反馈。

小结

dsh-kube-lens 的价值在于把「浏览器里看集群」和「Agent 读集群做诊断」合成一处,并且只做了一件事——用 kubectl 已有的凭证处理能力,把只读浏览做透,写操作一律收窄到显式开关加逐次审批后面。目录页在 https://www.skillhub.cn/plugins/atticuswx/dsh-kube-lens ,源码在 https://github.com/atticuswx/dsh-kube-lens 。

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜