k8s-cluster
K8s 多集群连接管理
前提准备
kubeconfig 文件获取:
- 从部署平台申请下载各集群的 kubeconfig 文件
- 每个集群拆分为独立文件,命名为
<集群ID>.yaml(如kube-ack-account-dev.yaml) - 统一存放在本地指定路径:
~/jobs/tcl/k8s/kubeconfigs/
环境配置
kubeconfig 目录:默认 ~/jobs/tcl/k8s/kubeconfigs/,可通过环境变量 $K8S_KUBECONFIG_DIR 自定义。
# 默认路径
KUBE_DIR="${K8S_KUBECONFIG_DIR:-$HOME/jobs/tcl/k8s/kubeconfigs}"
# 其他用户自定义
export K8S_KUBECONFIG_DIR=~/.kube/my-clusters/
kubectl 依赖检查:使用前必须确认 kubectl 已安装。
# 检查是否安装
which kubectl && kubectl version --client --short 2>/dev/null || kubectl version --client 2>/dev/null
# 未安装时按系统安装:
# macOS: brew install kubectl
# Ubuntu/Debian: sudo apt-get install -y kubectl
# CentOS/RHEL: sudo yum install -y kubectl
# 通用: curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" && sudo install kubectl /usr/local/bin/
所有后续命令中的 ~/jobs/tcl/k8s/kubeconfigs/ 均需替换为 $KUBE_DIR。
命名规则
| 标识 | 含义 | 标识 | 含义 |
|---|---|---|---|
| account | 账号集群 | eu | 欧洲 |
| dev | 开发环境 | mb | 北美 |
| test、sit、-t | 测试环境 | sg | 新加坡 |
| uat | 预发环境 | snm | 南传集群 |
| prod、-o、-p | 生产环境 | -gw | 网关 |
| bj | 北京 | -ops | 运维 |
| sz | 深圳 | hwt | 海外测试 |
| asia | 亚洲 | sx | 商显 |
| ai | AI 业务 | sa | 南美 |
| lacus | Lacus 业务 | us | 美国 |
| tclplus | TCL+ 业务 | el | EagleLab |
| iot | IoT 业务 | xr | XR 业务 |
| tvplus | TVPlus 业务 | tongxun | 通讯业务 |
| Terminal | 终端管理 | rus | 俄罗斯 |
雷鸟集群别名:kube-ack-o / kube-ack-o2(ACK)= kube-tke-o / kube-tke-t(TKE)= 雷鸟集群
集群列表
ACK(阿里云)
| 集群 ID | 业务/用途 | 环境 |
|---|---|---|
| kube-ack-account-dev | 账号集群 | 开发 |
| kube-ack-account-prod | 账号集群 | 生产 |
| kube-ack-account-sit | 账号集群 | 测试 |
| kube-ack-account-uat | 账号集群 | 预发 |
| kube-ack-ai-bj-o | AI 北京 | 生产 |
| kube-ack-ai-sz-o | AI 深圳 | 生产 |
| kube-ack-asia | 亚洲 | 生产 |
| kube-ack-bj-aigc-t | AIGC 北京 | 测试 |
| kube-ack-eaglelab-hwt | EagleLab 海外测试 | 测试 |
| kube-ack-el-asia | EagleLab 亚洲 | 生产 |
| kube-ack-el-eu | EagleLab 欧洲 | 生产 |
| kube-ack-eu-o | 欧洲 | 生产 |
| kube-ack-eu-o-gw | 欧洲 | 生产(网关) |
| kube-ack-hwt | 海外测试 | 测试 |
| kube-ack-iot-asia-prod | IoT 亚洲 | 生产 |
| kube-ack-iot-dev | IoT | 开发 |
| kube-ack-iot-eu-prod | IoT 欧洲 | 生产 |
| kube-ack-iot-pre | IoT | 预发 |
| kube-ack-iot-prod | IoT | 生产 |
| kube-ack-iot-test | IoT | 测试 |
| kube-ack-lacus-o | Lacus | 生产 |
| kube-ack-o | 雷鸟集群 | 生产 |
| kube-ack-o2 | 雷鸟集群 2 | 生产 |
| kube-ack-sx | 商显 | 生产 |
| kube-ack-sz-ai-t | AI 深圳 | 测试 |
| kube-ack-t3 | 雷鸟测试 | 测试 |
| kube-ack-tclplus-prod | TCL+ | 生产 |
| kube-ack-tclplus-sit | TCL+ | 测试 |
| kube-ack-tclplus-uat | TCL+ | 预发 |
| kube-ack-terminal | 终端管理 | 生产 |
| kube-ack-tongxun | 通讯 | 生产 |
| kube-ack-xr-eu-o | XR 欧洲 | 生产 |
| kube-ack-xr-eu-t | XR 欧洲 | 测试 |
| kube-ack-xr-p | XR | 生产 |
| kube-ack-xr-sg-o | XR 新加坡 | 生产 |
| kube-ack-xr-t | XR | 测试 |
| kube-ack-xr-us-o | XR 美国 | 生产 |
EKS(AWS)
| 集群 ID | 业务/用途 | 环境 |
|---|---|---|
| kube-eks-el-sa-o | EagleLab 南美 | 生产 |
| kube-eks-iot-eu-prod | IoT 欧洲 | 生产 |
| kube-eks-iot-mb-prod | IoT 北美 | 生产 |
| kube-eks-iot-mb-test | IoT 北美 | 测试 |
| kube-eks-iot-sg-prod | IoT 新加坡 | 生产 |
| kube-eks-iot-sp-prod | IoT SP | 生产 |
| kube-eks-tongxun-eu | 通讯 欧洲 | 生产 |
| kube-eks-tvplus-dev | TVPlus | 开发 |
| kube-eks-tvplus-prod | TVPlus | 生产 |
| kube-eks-tvplus-test | TVPlus | 测试 |
| kube-eks-us-tongxun | 通讯 美国 | 生产 |
TKE(腾讯云)
| 集群 ID | 业务/用途 | 环境 |
|---|---|---|
| kube-tke-o | 雷鸟集群 | 生产 |
| kube-tke-o-gw | 雷鸟集群 | 生产(网关) |
| kube-tke-o-ops | 雷鸟集群 | 生产(运维) |
| kube-tke-snm-o | 南传集群 | 生产 |
| kube-tke-snm-o-gw | 南传集群 | 生产(网关) |
| kube-tke-snm-t | 南传集群 | 测试 |
| kube-tke-t | 雷鸟集群 | 测试 |
KCE(火山云)
| 集群 ID | 业务/用途 | 环境 |
|---|---|---|
| kube-kce-el-rus | EagleLab 俄罗斯 | 生产 |
| kube-kce-iot-rus-dev | IoT 俄罗斯 | 开发 |
| kube-kce-iot-rus-prod | IoT 俄罗斯 | 生产 |
| kube-kce-rus-o | 俄罗斯 | 生产 |
GKE(Google Cloud)
| 集群 ID | 业务/用途 | 环境 |
|---|---|---|
| kube-gke-sa-o | 南美 | 生产 |
AKS(Azure)
| 集群 ID | 业务/用途 | 环境 |
|---|---|---|
| kube-aks-asia-poc | 亚洲 POC | POC |
其他
| 集群 ID | 业务/用途 | 环境 |
|---|---|---|
| kube-mlops-common-t | MLOps 通用 | 测试 |
连接集群
# 设置 kubeconfig 目录变量
KUBE_DIR="${K8S_KUBECONFIG_DIR:-$HOME/jobs/tcl/k8s/kubeconfigs}"
# 指定 kubeconfig 执行命令
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> <命令>
# 或设置环境变量(当前 shell 生效)
export KUBECONFIG="$KUBE_DIR"/<集群ID>
kubectl <命令>
常用读操作命令
# 设置 kubeconfig 目录变量
KUBE_DIR="${K8S_KUBECONFIG_DIR:-$HOME/jobs/tcl/k8s/kubeconfigs}"
# 查看节点
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> get nodes
# 查看所有命名空间
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> get namespaces
# 查看 Pod
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> get pods -n <namespace>
# 查看 Deployment
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> get deployments -n <namespace>
# 查看 Service
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> get svc -n <namespace>
# 查看 Pod 详情
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> describe pod <pod-name> -n <namespace>
# 查看日志
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> logs <pod-name> -n <namespace>
ImagePullBackOff 网络排查
当 Pod 卡在 ImagePullBackOff / Init:ImagePullBackOff 时,容器未启动,无法直接 exec。
排查步骤
KUBE_DIR="${K8S_KUBECONFIG_DIR:-$HOME/jobs/tcl/k8s/kubeconfigs}"
# 1. 查看事件确认错误类型
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> describe pod <pod-name> -n <namespace> | tail -30
# 区分超时(i/o timeout)vs 认证失败(authorization failed)vs 镜像不存在
# 2. 对比不同节点的网络连通性
# 在正常节点上尝试拉取镜像:
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> run test-normal --image=<镜像地址> \
--overrides='{"spec":{"nodeName":"<正常节点名>","containers":[{"name":"t","image":"<镜像地址>","command":["sh","-c","while true; do sleep 3600; done"]}]}}' \
-n default
# 在问题节点上测试:
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> run test-broken --image=<镜像地址> \
--overrides='{"spec":{"nodeName":"<问题节点名>","containers":[{"name":"t","image":"<镜像地址>","command":["sh","-c","while true; do sleep 3600; done"]}]}}' \
-n default
关键发现(经验)
i/o timeout= 网络不通(安全组/路由问题),不是认证或镜像问题。国内 ACK 集群访问 Docker Hub 也会报此错误authorization failed= 网络通但认证失败(可能是镜像不存在或 secret 配置错误)kubectl debug用新镜像也会在问题节点上卡住(同样需要拉镜像)- 系统容器(kube-proxy、csi-plugin 等)通常没有 curl/wget/nslookup 等调试工具
- 调试镜像替代方案:Docker Hub 不可用时,使用
registry.cn-hangzhou.aliyuncs.com/acs/busybox:v1.29.2或节点已有镜像
节点内网络测试(使用已存在镜像)
KUBE_DIR="${K8S_KUBECONFIG_DIR:-$HOME/jobs/tcl/k8s/kubeconfigs}"
# 查看问题节点上已有的镜像,选一个创建 debug pod
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> get pods -A -o jsonpath='{range .items[*]}{.spec.nodeName}{"\t"}{range .spec.containers[*]}{.image}{"\n"}{end}{end}' | grep <节点IP>
# 用已有镜像创建测试 pod(避免再次拉镜像)
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> run net-test --image=<已有镜像> \
--overrides='{"spec":{"nodeName":"<问题节点名>","containers":[{"name":"test","image":"<已有镜像>","command":["sh","-c","while true; do sleep 3600; done"]}]}}' \
-n default
# 等 Running 后测试连通性
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> exec net-test -n default -- sh -c "nslookup <仓库域名> && curl -sv --connect-timeout 10 https://<仓库域名>/v2/"
常见原因
- 新节点池安全组出方向未放行 443 端口
- 新节点所在子网缺少 NAT 网关/公网路由
- DNS 解析到公网 IP 而非 VPC 内网端点(ACR 企业版应配置 VPC Endpoint)
- Docker Hub 访问受限:国内 ACK 集群通常无法直接访问 Docker Hub(
docker.io),表现为i/o timeout。调试时应使用阿里云镜像源(registry.cn-hangzhou.aliyuncs.com/acs/)或节点已有镜像
常见 Pod 异常状态排查
CrashLoopBackOff
KUBE_DIR="${K8S_KUBECONFIG_DIR:-$HOME/jobs/tcl/k8s/kubeconfigs}"
# 查看容器日志
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> logs <pod-name> -n <namespace> --previous
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> logs <pod-name> -n <namespace> -c <容器名> --previous
# 查看事件定位原因
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> describe pod <pod-name> -n <namespace> | tail -30
# 临时覆盖启动命令排查(绕过 crash)
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> run debug-crash --image=<原镜像> \
--command -n <namespace> -- sh -c "while true; do sleep 3600; done"
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> exec debug-crash -n <namespace> -- sh -c "cat /app/config.yaml && ls -la /app"
常见原因:启动参数/环境变量错误、依赖服务未就绪、资源限制过小、健康检查配置不当、ConfigMap/Secret 缺失。
Pending
KUBE_DIR="${K8S_KUBECONFIG_DIR:-$HOME/jobs/tcl/k8s/kubeconfigs}"
# 查看调度事件
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> describe pod <pod-name> -n <namespace> | grep -A 10 "Events:"
# 检查节点资源
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> top nodes
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> describe nodes | grep -A 5 "Allocated resources"
# 查看 Taint 与 Toleration
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.taints}{end}'
常见原因:节点资源不足、Taint 未匹配、亲和性条件不满足、PVC 未绑定、ResourceQuota 限制。
OOMKilled
KUBE_DIR="${K8S_KUBECONFIG_DIR:-$HOME/jobs/tcl/k8s/kubeconfigs}"
# 确认 OOM 事件
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> get pod <pod-name> -n <namespace> \
-o jsonpath='{.status.containerStatuses[0].lastState.terminated.reason}'
# 查看当前资源限制与请求
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> get pod <pod-name> -n <namespace> \
-o jsonpath='{.spec.containers[0].resources}'
解决方案:调大 resources.limits.memory(建议比峰值高 20-30%);Java 应用确保 -Xmx 小于容器 limit;监控内存泄漏。
Terminating 卡死
KUBE_DIR="${K8S_KUBECONFIG_DIR:-$HOME/jobs/tcl/k8s/kubeconfigs}"
# 查看是否有 Finalizer 阻止删除
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> get pod <pod-name> -n <namespace> \
-o jsonpath='{.metadata.finalizers}'
# 强制删除(谨慎使用,可能残留资源)
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> delete pod <pod-name> -n <namespace> --grace-period=0 --force
网络与服务发现排查
CoreDNS 故障排查
KUBE_DIR="${K8S_KUBECONFIG_DIR:-$HOME/jobs/tcl/k8s/kubeconfigs}"
# 检查 CoreDNS Pod 状态
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> get pods -n kube-system -l k8s-app=kube-dns
# 测试 DNS 解析
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> run dns-test --image=registry.cn-hangzhou.aliyuncs.com/acs/busybox:v1.29.2 --restart=Never -n default -- \
sh -c "nslookup kubernetes.default.svc.cluster.local && nslookup baidu.com"
# 查看 CoreDNS 日志
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> logs -n kube-system -l k8s-app=kube-dns --tail=100
Service/Endpoint 不匹配
KUBE_DIR="${K8S_KUBECONFIG_DIR:-$HOME/jobs/tcl/k8s/kubeconfigs}"
# 查看 Service 与 Endpoint
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> get svc <svc-name> -n <namespace> -o wide
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> get endpoints <svc-name> -n <namespace>
# 对比 Pod 标签是否与 Service Selector 匹配
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> get svc <svc-name> -n <namespace> -o jsonpath='{.spec.selector}'
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> get pods -n <namespace> --show-labels
# 测试 Service 连通性
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> run svc-test --image=registry.cn-hangzhou.aliyuncs.com/acs/busybox:v1.29.2 --restart=Never -n <namespace> -- \
sh -c "wget -qO- http://<svc-name>.<namespace>.svc.cluster.local:<port> || echo 'FAIL'"
Ingress 路由不通
KUBE_DIR="${K8S_KUBECONFIG_DIR:-$HOME/jobs/tcl/k8s/kubeconfigs}"
# 查看 Ingress 配置与 Controller 状态
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> get ingress <ingress-name> -n <namespace> -o wide
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> get pods -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> logs -n ingress-nginx -l app.kubernetes.io/name=ingress-nginx --tail=50
NetworkPolicy 拦截
KUBE_DIR="${K8S_KUBECONFIG_DIR:-$HOME/jobs/tcl/k8s/kubeconfigs}"
# 查看当前命名空间的 NetworkPolicy
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> get networkpolicy -n <namespace>
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> get networkpolicy <policy-name> -n <namespace> -o yaml
日志与调试技巧
日志查看进阶
KUBE_DIR="${K8S_KUBECONFIG_DIR:-$HOME/jobs/tcl/k8s/kubeconfigs}"
# 多容器 Pod 指定容器
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> logs <pod-name> -n <namespace> -c <容器名>
# 查看上次崩溃的日志
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> logs <pod-name> -n <namespace> --previous
# 按标签批量查看
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> logs -n <namespace> -l app=<应用名> --tail=200
# 实时追踪日志
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> logs <pod-name> -n <namespace> -f
kubectl debug 高级用法
ACK 集群镜像拉取注意:部分阿里云 ACK 集群无法访问 Docker Hub,
busybox、ubuntu、nicolaka/netshoot等 Docker Hub 镜像会报 ImagePullBackOff。应使用阿里云镜像源或节点已有镜像。
KUBE_DIR="${K8S_KUBECONFIG_DIR:-$HOME/jobs/tcl/k8s/kubeconfigs}"
# 使用临时容器调试(ACK 集群用阿里云镜像)
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> debug <pod-name> -n <namespace> --image=registry.cn-hangzhou.aliyuncs.com/acs/busybox:v1.29.2 -- sh
# 复制 Pod 配置创建调试副本
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> debug <pod-name> -n <namespace> --image=registry.cn-hangzhou.aliyuncs.com/acs/busybox:v1.29.2 --copy-to=debug-copy -- sh
# 节点级别调试(用 alpine 替代 netshoot)
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> debug node/<node-name> --image=registry.cn-hangzhou.aliyuncs.com/acs/alpine:latest -- chroot /host sh
# 使用节点已有镜像创建调试 Pod(避免拉镜像)
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> get pods -A -o jsonpath='{range .items[*]}{.spec.containers[*].image}{"\n"}{end}' | sort -u
kubectl --kubeconfig "$KUBE_DIR"/<集群ID> run debug-node --image=<已有镜像> --overrides='{"spec":{"containers":[{"name":"t","image":"<已有镜像>","command":["sh","-c","while true; do sleep 3600; done"]}]}}' -n default
常用调试镜像(阿里云 ACK 集群可用)
| 用途 | 阿里云镜像 | 包含工具 | 验证状态 |
|---|---|---|---|
| 轻量级基础调试 | registry.cn-hangzhou.aliyuncs.com/acs/busybox:v1.29.2 | nslookup, wget, sh | ✅ 已验证可用 |
| 轻量完整环境 | registry.cn-hangzhou.aliyuncs.com/acs/alpine:latest | apk, sh, wget | ✅ 已验证可用 |
| 完整 Linux 环境 | registry.cn-hangzhou.aliyuncs.com/acs/ubuntu:latest | apt-get, bash | ✅ 已验证可用 |
注意:以下 Docker Hub 镜像在 ACK 集群不可用(ImagePullBackOff):
nicolaka/netshoot- 阿里云无对应镜像,网络排查用alpine+apk add curl tcpdump替代tutum/dnsutils- DNS 排查用busybox的nslookup替代
镜像可用性策略:
- 优先使用阿里云镜像源(
registry.cn-hangzhou.aliyuncs.com/acs/) - 如果阿里云镜像也不可用,查询节点已有镜像并使用
- Docker Hub 镜像仅在国际集群(EKS/GKE/海外 ACK)上使用
操作权限控制
读操作(默认允许,无需确认):
get(nodes, pods, deployments, svc, ingress, pvc, hpa, namespaces, logs 等)describe(pod, node, deploy, svc 等)config view/cluster-infotop/diff
写操作(必须用户手动确认,不可跳过):
apply/create/delete/editscale/rollout/setlabel/annotate/taint/cordon/uncordon/drainexec中执行的写入命令- 任何涉及
--force/--grace-period=0的危险操作
规则:执行任何写操作前,必须明确告知用户操作内容和影响范围,获得用户确认后才能继续。禁止在未确认的情况下执行任何修改集群状态的命令。
注意事项
- 使用前确认 kubectl 已安装(
which kubectl) - 写操作(apply/delete/scale 等)需用户确认
- kubeconfig 目录通过
$K8S_KUBECONFIG_DIR环境变量配置,默认~/jobs/tcl/k8s/kubeconfigs/ - kubeconfig 文件名即集群 ID,新增集群只需将配置文件放入该目录
- 所有脚本中的路径使用
KUBE_DIR="${K8S_KUBECONFIG_DIR:-$HOME/jobs/tcl/k8s/kubeconfigs}"动态获取 - 排查完成后记得删除测试 Pod:
kubectl delete pod <测试pod名> -n default
集群列表维护
使用本 skill 时,检查实际目录与列表是否一致:
KUBE_DIR="${K8S_KUBECONFIG_DIR:-$HOME/jobs/tcl/k8s/kubeconfigs}"
# 1. 实际目录中的 kubeconfig 文件
ls "$KUBE_DIR"/ | sort > /tmp/actual_clusters.txt
# 2. 从 skill 列表中提取所有集群 ID
grep "^| kube-" ~/.hermes/skills/devops/k8s-cluster/SKILL.md | awk -F'|' '{gsub(/ /,"",$2); print $2}' | sort > /tmp/listed_clusters.txt
# 3. 对比差异
diff /tmp/listed_clusters.txt /tmp/actual_clusters.txt
结果判断:
- 无差异 → 列表和目录完全一致,直接使用
- 有差异 → 输出 diff 结果,逐条处理:
<开头:列表中有但目录里没有 → 文件被删除,询问是否移除>开头:目录有但列表里没有 → 新增文件,执行以下验证:
新增 kubeconfig 验证步骤:
KUBE_DIR="${K8S_KUBECONFIG_DIR:-$HOME/jobs/tcl/k8s/kubeconfigs}"
# 1. 检查是否为有效的 kubeconfig(必须包含 apiServer 和 cluster 字段)
grep -q "apiServer:" "$KUBE_DIR"/<新增文件名> && grep -q "clusters:" "$KUBE_DIR"/<新增文件名> && echo "有效kubeconfig" || echo "无效文件"
# 2. 提取集群名称(cluster-name 或 server 地址)
kubectl --kubeconfig "$KUBE_DIR"/<新增文件名> config view --minify -o jsonpath='{.clusters[0].name}' 2>/dev/null
# 3. 测试连接(可选,需要网络可达)
kubectl --kubeconfig "$KUBE_DIR"/<新增文件名> cluster-info 2>/dev/null | head -1
验证通过后,询问用户该集群的业务/环境信息,确认后加入 SKILL.md 列表。如果文件不是有效的 kubeconfig,不加入列表并提示用户清理。
重复集群检测:
新增或变更时,对比 server URL 防止不同文件指向同一集群:
KUBE_DIR="${K8S_KUBECONFIG_DIR:-$HOME/jobs/tcl/k8s/kubeconfigs}"
# 提取所有 kubeconfig 的 server URL
for f in "$KUBE_DIR"/*; do
server=$(kubectl --kubeconfig "$f" config view --minify -o jsonpath='{.clusters[0].cluster.server}' 2>/dev/null)
echo "$(basename "$f") -> $server"
done | sort -t'>' -k2
相同 server URL 的文件会相邻排列,提示用户确认:
- 是否为备份/副本 → 保留一个主文件
- 是否同一集群不同用户/权限 → 确认保留
- 确认无重复后,更新集群列表
注意:不硬编码 server URL 到 SKILL.md(涉及内部地址),每次检查时动态提取对比即可。
集群唯一 ID 映射表:
文件路径:~/.hermes/skills/devops/k8s-cluster/references/cluster_uid_map.json
格式:
{
"766618ad": {"cluster_id": "kube-ack-account-dev"},
"70594665": {"cluster_id": "kube-ack-account-prod"}
}
- key 为 server URL 的 MD5 前 8 位(集群指纹)
- value 为对应的集群 ID(即 kubeconfig 文件名)
使用方式:
KUBE_DIR="${K8S_KUBECONFIG_DIR:-$HOME/jobs/tcl/k8s/kubeconfigs}"
# 他人导入自己的 kubeconfig 后,计算指纹查表
server=$(kubectl --kubeconfig "$KUBE_DIR"/<文件名> config view -o jsonpath='{.clusters[0].cluster.server}')
fingerprint=$(echo -n "$server" | md5sum | cut -c1-8)
python3 -c "import json; m=json.load(open(os.path.expanduser('~/.hermes/skills/devops/k8s-cluster/references/cluster_uid_map.json'))); print(m.get('$fingerprint', '未知集群'))"
- 匹配成功 → 获取对应集群 ID,直接使用
- 匹配失败 → 新集群,走新增集群验证流程
- 此映射表随 skill 一起发布,他人无需知道真实 server URL 即可对应到集群 ID