如何使用Go客户端获取K8s指定命名空间下的所有资源
问题说明
需要使用K8s Go客户端实现与以下命令完全等效的查询能力:
kubectl get all -n kontrol-migration-helper -o json
原有实现代码仅能查询命名空间对象本身,无法返回命名空间下的资源集合,错误实现代码如下:
func (srv *Service) GetAllResouce(projectName string) (interface{}, error) { projectDatas, err := srv.client.CoreV1().Namespaces().Get(context.TODO(), projectName, v1.GetOptions{}) if err != nil { return nil, err } return projectDatas, nil }
错误原因
CoreV1().Namespaces().Get()接口的作用是查询指定名称的命名空间元数据对象,不会返回该命名空间下部署的Pod、服务、工作负载等任何其他类型资源,和kubectl get all的逻辑完全不匹配。
需要特别说明:kubectl get all不会返回命名空间下所有类型的资源,仅会返回K8s预设的核心常用资源集合,包含Pod、Service、Deployment、StatefulSet、DaemonSet、ReplicaSet、Job、CronJob,不包含ConfigMap、Secret、Ingress、PVC等资源。
正确实现方案
实现逻辑分为两步:
- 明确
kubectl get all覆盖的资源类型范围 - 遍历对应资源类型,在目标命名空间下批量查询,最终汇总结果
实现需要使用动态客户端完成多类型资源的查询,完整可运行代码如下:
import ( "context" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/dynamic" ) // 对齐kubectl get all默认覆盖的资源类型列表 var kubectlDefaultAllResources = []schema.GroupVersionResource{ // 核心API组资源 corev1.SchemeGroupVersion.WithResource("pods"), corev1.SchemeGroupVersion.WithResource("services"), corev1.SchemeGroupVersion.WithResource("replicationcontrollers"), // apps API组资源 {Group: "apps", Version: "v1", Resource: "deployments"}, {Group: "apps", Version: "v1", Resource: "statefulsets"}, {Group: "apps", Version: "v1", Resource: "daemonsets"}, {Group: "apps", Version: "v1", Resource: "replicasets"}, // batch API组资源 {Group: "batch", Version: "v1", Resource: "jobs"}, {Group: "batch", Version: "v1", Resource: "cronjobs"}, } func (srv *Service) GetAllResouce(namespace string) (map[string]interface{}, error) { // 基于已有客户端初始化动态客户端 restConfig := srv.client.CoreV1().RESTClient().Config() dynClient, err := dynamic.NewForConfig(restConfig) if err != nil { return nil, err } resourceMap := make(map[string]interface{}) for _, gvr := range kubectlDefaultAllResources { list, err := dynClient.Resource(gvr).Namespace(namespace).List(context.TODO(), metav1.ListOptions{}) if err != nil { // 集群不支持当前资源类型时直接跳过,和kubectl容错逻辑对齐 continue } resourceMap[gvr.Resource] = list } return resourceMap, nil }
补充说明
- 如果需要完全对齐kubectl的输出过滤规则,可以在
ListOptions中增加对应的标签选择器,过滤已完成的Job、终止中的Pod等资源 - 如果需要查询命名空间下所有类型的资源(而非kubectl默认的all范围),可通过DiscoveryClient获取集群所有支持的资源类型,过滤出命名空间级别的资源后逐个遍历查询即可
- 原有代码中方法名存在拼写错误:
GetAllResouce正确拼写为GetAllResource,不影响功能运行但建议修正
内容的提问来源于stack exchange,提问作者GeunSam2
相关产品推荐
相关产品推荐

