kubectl识别go插件需命名kubect-xxx、放path中;入口函数必须为func execute(args[]string, stdin io.reader) error;复用client-go应标准加载配置;stdout输出结果,stderr输出日志与错误。

怎么让 kubectl 识别你的 Go 插件
必须把可执行文件命名为 kubectl-xxx(比如 kubectl-nslist),且放在 $PATH 中。kubectl 启动时会扫描所有以 kubectl- 开头的命令,自动将其注册为子命令。
常见错误:文件名写成 nslist 或 kubectl_nslist —— 都不会被识别;放在当前目录但没加到 $PATH,运行 kubectl nslist 会报错 command "nslist" not found。
- 编译后用
chmod +x确保可执行 - 推荐放去
$HOME/bin/并加入PATH,避免权限或路径问题 - 插件名里不能有大写字母或下划线,只支持小写字母、数字、连字符(如
kubectl-myapp-v2合法,kubectl-MyApp不合法)
插件入口函数为什么必须叫 Execute
Go 插件本质是独立二进制,kubectl 不管你内部怎么写,只按约定调用主函数。它通过反射查找名为 Execute 的导出函数(首字母大写),并传入 args []string 和 stdin io.Reader。
如果你写成 main() 或 Run(),kubectl 调用时会静默失败,只输出空行或 unknown command —— 实际进程已启动,但没执行任何逻辑。
立即学习“go语言免费学习笔记(深入)”;
- 函数签名必须是
func Execute(args []string, stdin io.Reader) error - 返回
error会被转为非零退出码,kubectl 自动显示错误信息 - 不建议在
Execute里直接调os.Exit(),会绕过错误处理和日志统一出口
如何安全复用 client-go 连接集群
别自己解析 ~/.kube/config,直接用 client-go 提供的标准加载器。它能自动处理上下文切换、证书刷新、exec 插件(比如 aws-iam-authenticator)等边界情况。
典型坑:硬编码 https://localhost:6443 或跳过 TLS 验证,在生产环境要么连不上,要么被拦截。client-go 默认启用证书校验,但如果你用 rest.InClusterConfig() 在 Pod 里跑,就完全不用碰 kubeconfig 文件。
- 本地开发用
clientcmd.BuildConfigFromFlags("", clientcmd.RecommendedHomeFile) - 优先用
rest.CopyConfig(cfg)复制配置,避免多个 goroutine 修改同一 config 实例 - 超时要设——默认无超时,网络卡住时命令挂死
stderr 和 stdout 怎么分清楚才不干扰管道
kubectl 插件的 stdout 是给用户看的结果(比如 JSON/YAML 表格),stderr 是错误、警告、进度提示。如果把日志打到 stdout,下游用 | jq 或 > out.json 就会混入乱码。
更隐蔽的问题:某些 shell 组合命令(如 kubectl myplug | head -n1)会 SIGPIPE 掉写 stdout 的进程,但不影响 stderr 输出——所以调试信息必须走 stderr,否则你看不到崩溃现场。
- 用
fmt.Fprintln(os.Stderr, "...")打日志,别用log.Print(它默认走 stderr,但格式不可控) - 结构化输出(如 JSON)只走
stdout;交互式提示(如 “Loading…”)走stderr - 如果用了第三方库打印,检查它是否允许重定向输出目标
最常被忽略的是信号处理——插件收到 SIGINT(Ctrl+C)时,client-go 的 watch 或 stream 可能卡在 read 状态,导致进程无法退出。得显式监听 os.Interrupt 并 cancel context。










