Kubernetes Lens
通过 kubeconfig 访问集群的 DSH 插件。左侧栏多一个 Kubernetes 图标,主区是一个资源浏览器;同一套操作也暴露成 Agent 工具,用来排查问题。
English — A Kubernetes cluster browser panel and agent tools for the DeepSeek Harness (DSH) Web GUI. Reads contexts from your kubeconfig through kubectl; read-only by default, secrets redacted, writes behind an approval. MIT licensed.
dsh plugin --profile web add github:atticuswx/dsh-kube-lensReload the page and the Kubernetes icon appears in the sidebar. Requires
kubectlon the host.
安装
从 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
前置条件:宿主机有 kubectl(Rancher Desktop 通常在 ~/.rd/bin/kubectl),以及支持 Web client bundle 的 DSH。包内没有构建步骤,client.js 由浏览器直接加载。
安装后会发生什么
- 侧边栏出现一个 Kubernetes 图标,点开是集群浏览器。
- Agent 多了 6 个工具:
kube_contexts、kube_get、kube_describe、kube_logs、kube_events、kube_diagnose。 - 默认只读。写操作关闭时,
kube_write工具和面板上的写按钮都不出现。
为什么走 kubectl
kubeconfig 的凭证可能是客户端证书、bearer token、exec 凭证插件(aws / gcloud / azure)、auth-provider 片段。kubectl 已经把这些都处理好了;一个不引入依赖的插件不可能正确重写一遍。代价是宿主机上要有 kubectl——Rancher Desktop 的用户通常已经把它放在 ~/.rd/bin/kubectl。
切换 kubeconfig
面板右上角的 kubeconfig 按钮可以随时增删 kubeconfig 文件,改完立即生效,不用重启插件:
- 粘贴绝对路径(支持
~/...)→ 「添加」。 - 多个 kubeconfig 一起列出,但每个 context 只用它所属的那个文件:不做跨文件按名合并。
原因很实际——两个 kubeconfig 常常都把 cluster 叫作
kubernetes,kubectl 合并时只保留第一个, 于是另一个文件的 context 会被指向错误的 API server,表现为Unauthorized。 - 列表为空时回落到
$KUBECONFIG,再回落到~/.kube/config。 - 保存位置:
$DSH_HOME/kube-lens.json(默认~/.dsh/kube-lens.json),可以手改。
添加后,context 下拉框会列出新文件里的所有 context,current-context 自动选中。
浏览与搜索
- 顶部显示 kubeconfig 文件名(例如
prod-cluster),而不是那串123456789012345678-…的 context id;hover 可以看到完整的 context、server 和文件路径。 - 点名字旁边的 ✎ 可以改成任意显示名(例如「沙箱集群」),回车保存,
Esc取消;名字存在~/.dsh/kube-lens.json的labels里,按 kubeconfig 文件记录,所以换路径后不会错位。 - 一个 kubeconfig 里若有多个 context,下拉框会显示
文件名 · context以便区分。 - 一个过滤条同时管命名空间和搜索:左边是命名空间触发器(点开选「全部命名空间」或具体某个),右边直接输入过滤资源名称;
/聚焦输入框,Esc清空或关闭菜单。 - 命名空间下拉在命名空间多于 12 个时会自带筛选框。
- 选「全部命名空间」时表格会多出
NAMESPACE列。 - 只看异常按 READY / STATUS 列筛选:未就绪(
0/N)或处于 CrashLoopBackOff、ImagePullBackOff、Pending、Error 等状态的对象,方便第一时间定位问题实例。 - 计数显示为
匹配数/总数,筛选是纯客户端的,不会因为输入而反复请求集群;切换命名空间才会重新请求。
键盘
- 表头排序:点击列头在
升序 → 降序 → 取消之间循环;不可排序的列(CLUSTER-IP、PORT(S)、CAPACITY)不显示排序按钮。 - 表格:
↑/↓移动行焦点,Home/End跳到首行/末行,Enter或Space打开详情。 - 搜索:
/聚焦搜索框(详情页不生效);输入框里Esc清空并退出。 - 详情:
Esc、左上角返回、右上角关闭都回到列表,焦点落回进入详情的那一行。
详情页:YAML 与日志
详情页的 YAML 和 日志 两个 tab(0.3.0 新增):
YAML
- 编辑器是 CodeMirror 6(
@codemirror/lang-yaml),打包在插件的viewer.js里,不走 CDN,离线可用;只在第一次打开 YAML tab 时按需加载,加载失败会自动退回只读的<pre>视图。 - 支持语法高亮、行号、折叠、括号匹配、撤销/重做、自动换行和
⌘F查找。 - 复制:有选中内容时复制选中,否则复制整份清单。下载:保存为
<kind>-<name>.yaml。格式化:用 YAML 解析器重新排版并保留注释。还原:回到打开时的内容。 - 编辑时实时做 YAML 语法校验:错误行内波浪线,状态栏显示第一条错误;有未保存改动时 YAML tab 出现小黄点。
- 保存到集群只在
allowWrites: true时可用:点击后出现确认条(显示kubectl apply -f -),确认后才执行kubectl apply。 - Secret、清单超过 24k 字符被截断、读取失败三种情况自动只读,避免把脱敏或不完整的内容写回集群。
- 快捷键:
⌘F查找、⌘S保存、Esc关闭查找;编辑器内⌘C/⌘V照常。
日志
- 跟随通过 SSE 持续接收
kubectl logs -f --timestamps的输出;默认自动滚底,向上翻看时暂停滚底并显示「回到最新」。 - 搜索框高亮全部匹配,
Enter/Shift+Enter跳到下一个/上一个,显示当前 / 总数。 - 支持时间戳、自动换行、200–2000 行 tail、复制全部、下载原始日志(带时间戳)。
- 多容器 Pod 会列出容器 tab;有重启时多出「上一次运行」快照。切换 tab 会重建对应的流。
- 连接断开后自动重连,用上一次时间戳
--since-time补漏,并按时间戳去重;只保留最近 5000 行,更早内容自动裁剪。 - 离开「日志」tab 会断开 kubectl 子进程,避免后台一直 tail;回到 tab 再重连。
- 日志搜索快捷键:
Enter下一个、Shift+Enter上一个、Esc清空。
配置
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 超时。 |
改配置后需要重新加载插件。
写操作
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。日志、事件、清单照常返回。
诊断是怎么做的
kube_diagnose 一次调用返回:容器状态、重启次数、上次退出码与终止原因、调度失败事件、Service 的 Endpoints 覆盖、以及上一次运行和当前的日志尾巴,并给出结论化的 findings。
判断规则(都是启发式,附证据):
ImagePullBackOff/ErrImagePull→ 镜像或仓库凭证CrashLoopBackOff→ 重启次数 + 上次退出码OOMKilled→ 内存 limitCreateContainerConfigError→ 引用的 ConfigMap/SecretPending+FailedScheduling→ 调度器原话- Running 但未 Ready → 就绪探针
- Service 无 Endpoints → 区分「selector 打错」和「Pod 不 Ready」
- Node 的 Ready / MemoryPressure / DiskPressure / PIDPressure
已知边界
- 只实现 Pod / 工作负载 / Service / Node 的深度诊断;其它资源回退到
kubectl describe。 - 还没有 exec、port-forward。YAML 保存走
kubectl apply,只在allowWrites: true时出现,并且需要面板确认。 - 集群不可达时,工具返回的是「集群不可达 + server 地址 + 下一步」,而不是 kubectl 的原始堆栈。
开发与测试
仓库自带纯函数测试和一套 jsdom 面板门禁:
npm ci
npm test
viewer.js 是预构建产物,已提交在仓库里;安装时不需要构建。只有修改 viewer-src/viewer.js 时才需要重新生成:
npm run build:viewer
更新已安装的插件后:
- 客户端改动刷新页面即可(
client.js的 combo 版本按文件时间变化)。 - Host 改动(
index.js/kube.js的新路由、SSE、apply)需要重载一次宿主:重启dsh web,或在插件管理里重载该插件。
License
MIT — see LICENSE.
No comments yet. Be the first to write one.