client-go连接kubernetes集群需确保配置正确:本地开发用buildconfigfromflags指定kubeconfig路径并设置currentcontext;集群内运行必须用inclusterconfig且pod绑定有rbac权限的serviceaccount;查api信息用discoveryclient,查资源注意命名空间语义和groupversion匹配;所有配置初始化必须检查error,避免nil config导致panic。

直接用 client-go 获取集群信息,核心不是“查什么”,而是“连得上、认得对、问得准”——配置错一步,no Auth Provider found for name "oidc" 或 x509: certificate signed by unknown authority 就立刻报出来,根本到不了“获取”那步。
本地开发:必须用 BuildConfigFromFlags,别碰 InClusterConfig
在本地写代码调试时,rest.InClusterConfig() 一定失败,它只读 /var/run/secrets/kubernetes.io/serviceaccount/ 下的 token 和证书,本地压根没这路径。硬用会 panic。
- 正确做法是显式传入 kubeconfig 文件路径:
clientcmd.BuildConfigFromFlags("", "/path/to/kubeconfig") - 如果
kubeconfig里有多个 context(比如dev、prod),必须手动指定:clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, &clientcmd.ConfigOverrides{CurrentContext: "prod"}) - 常见错误:把多个集群的 config 合并进一个文件,却没指定
CurrentContext,结果连上的是默认 context,查到的却是另一个集群的数据
集群内运行:只能用 InClusterConfig,且 Pod 必须绑对 ServiceAccount
当 Go 程序以 Pod 形式跑在集群里,rest.InClusterConfig() 是唯一合法入口。但它不认你传的任何参数,完全依赖 Pod 自身的 service account。
- Pod 的
serviceAccountName必须指向一个有 RBAC 权限的账号,否则后续所有 List/Get 都是403 Forbidden - 权限要精确匹配资源 GroupVersion:查
Deployment要apps/v1的权限,不能只靠core/v1的pods权限混过去 - CA 证书和 token 自动挂载,但如果你看到
x509: certificate signed by unknown authority,大概率是集群启用了自签名 CA,而你的 client-go 版本太老或没开启Insecure(不推荐)
查集群基本信息:用 DiscoveryClient,不是 Clientset
想拿集群支持的 API 组、版本、资源列表(比如确认 HorizontalPodAutoscaler 是否可用、Ingress 是 networking.k8s.io/v1 还是 extensions/v1beta1),别用 Clientset —— 它只管操作,不管“有什么”。
- 要用
discovery.NewDiscoveryClientForConfig(config)构建发现客户端 -
ServerGroups()返回所有已注册的 API 组;ServerResourcesForGroupVersion("apps/v1")返回该组下所有可用资源及其动词 - 这个调用本身也受 RBAC 控制:需要
discovery组下的get权限,常被忽略,导致静默失败
查节点、命名空间、Pod 等实际资源:注意命名空间语义和 GroupVersion 分离
你以为 clientset.CoreV1().Pods("default").List() 是查 default 命名空间的 Pod,没错;但 clientset.CoreV1().Pods("").List() 不是“所有命名空间”,而是空字符串命名空间——它会 404。真正查全部,得用 metav1.NamespaceAll。
- 资源不在
CoreV1?Deployment 用AppsV1(),Ingress 用NetworkingV1().Ingresses(),HPA 用AutoscalingV2().HorizontalPodAutoscalers() - 创建对象时,
ObjectMeta.Namespace字段必须显式设置,哪怕你调用的是Pods("myns")—— 接口只影响请求路径,不覆盖对象内部字段 - Watch 资源变化时,
ListOptions.ResourceVersion="0"表示从当前最新开始,但首次 List 可能漏事件;生产环境建议先 List 再 Watch,并用ResourceVersion衔接
最易被忽略的一点:所有配置初始化(BuildConfigFromFlags 或 InClusterConfig)都可能返回 error,但很多人只 check 了 NewForConfig 的 error,忘了前者——结果 config 是 nil,后面全崩在 nil pointer dereference 上。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











