直接调用 clientset.CoreV1().Endpointses(metav1.NamespaceAll).List(ctx, metav1.ListOptions{}) 可列出所有命名空间的 Endpoints,需注意函数名拼写为 Endpointses、传非 nil ListOptions、指定 NamespaceAll 且导入 corev1 包;Subsets 为空主因是 Service 无就绪 Pod 匹配,推荐优先使用 EndpointSlice 替代以提升性能与扩展性。

用 client-go 列出所有命名空间的 Endpoints
直接调用 CoreV1().Endpointses().List() 即可,但注意函数名带复数且拼写是 Endpointses(不是 Endpoints 或 Endpointses),这是 client-go 的固定命名规则。需要传入 metav1.ListOptions{},空结构体表示不限制条件。
常见错误是漏掉 corev1 包导入,或误写成 Endpoint(单数)导致编译失败;也有人传 nil 当作 ListOptions,这在较新版本 client-go(v0.25+)会 panic,必须传非 nil 值。
- 确保已初始化
*kubernetes.Clientset,通常通过rest.InClusterConfig()或clientcmd.BuildConfigFromFlags()获取配置 - 调用时指定命名空间为
metav1.NamespaceAll才能跨命名空间获取;若只写"",默认只查 default 命名空间 - 返回的
*corev1.EndpointsList中,每个Items是corev1.Endpoints类型,其Subsets字段才是实际 IP+端口列表
endpointsList, err := clientset.CoreV1().Endpointses(metav1.NamespaceAll).List(context.TODO(), metav1.ListOptions{})
if err != nil {
log.Fatal(err)
}
for _, ep := range endpointsList.Items {
fmt.Printf("Endpoints %s/%s has %d subsets\n", ep.Namespace, ep.Name, len(ep.Subsets))
}
为什么 Subsets 里地址经常为空?
Endpoints 对象本身不存地址,它只是 Service 的“下游映射快照”;Subsets 字段为空,说明对应 Service 没有匹配到任何 Pod —— 常见原因包括:Service 的 selector 标签不匹配、Pod 还没就绪(Ready=False)、Pod 在不同命名空间未被 Service 覆盖。
不要试图从 Endpoints 反推 Service 是否健康,而应结合 kubectl get endpoints 看状态,或直接检查对应 Service 的 selector 和目标 Pod 的 label 和 phase。
- Endpoints 的
Subsets是只读快照,不会实时更新;Kube-proxy 和 endpoint-slice 控制器异步同步,延迟通常在秒级 - 如果 Service 类型是
ExternalName,Subsets永远为空,因为不指向集群内 Pod - 1.22+ 集群默认启用 EndpointSlice,但 Endpoints 对象仍存在且保持同步,只是不再作为主要分发依据
用 EndpointSlice 替代 Endpoints 获取更细粒度数据
从 Kubernetes 1.21 开始,EndpointSlice 是推荐方式,尤其当一个 Service 后端 Pod 超过 100 个时,Endpoints 对象会因体积过大触发 API Server 限流;EndpointSlice 按 100 条/片切分,支持拓扑感知(如 zone、node),且字段更清晰。
client-go 中需导入 discoveryv1 "k8s.io/client-go/applyconfigurations/discovery/v1" 并使用 DiscoveryV1().EndpointSlices(),注意 API 组是 discovery.k8s.io/v1,不是 core。
- 筛选特定 Service 的 EndpointSlice:用
LabelSelector匹配endpoints.kubernetes.io/service-name= - 每个
EndpointSlice的Endpoints字段含Addresses(IP)、Conditions.Ready、Topology等,比 Endpoints 的 Subsets 更易解析 - 旧版 client-go(v0.22 之前)不支持 discovery/v1,需升级或降级用 discovery/v1beta1(已废弃)
权限不足时 get endpoints 返回空列表而非报错
RBAC 配置错误时,list endpoints 很可能静默返回空 Items 列表,而不是抛出 403 Forbidden 错误——这是因为 Kubernetes 默认允许“无资源匹配”,避免信息泄露。调试时容易误判为逻辑问题。
验证权限是否生效,最直接的方式是手动执行 kubectl auth can-i list endpoints --all-namespaces,或看 kubectl get endpoints -A 是否真能列出数据。
- 最小 RBAC 规则需包含:
resources: ["endpoints"], verbs: ["get", "list"];若要跨命名空间,resourceNames不能限定具体名称 - 使用
ClusterRoleBinding绑定到 ServiceAccount 时,确认该 SA 确实在 Pod 的serviceAccountName字段中指定 - 如果代码运行在本地(非 in-cluster),还要检查 kubeconfig 中 context 使用的 user 是否有足够权限,而非仅看 cluster 配置
EndpointSlice 和 Endpoints 的差异不是功能取舍,而是演进路径;生产环境建议双路采集:用 Endpoints 做兼容兜底,用 EndpointSlice 做主数据源——尤其当服务规模增长后,前者会成为性能瓶颈点。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











