client-go多集群管理

背景

通常在多云环境中或者多k8s集群中,一个与k8s相关管理服务需要同事管理多个k8s集群,有很多种方法可以去实现该功能,这里主要介绍一种通过一个config文件在配合client-go代码来实现多集群client的创建,client-go中的example中都是单集群的client的实现。

实现代码

通过查看client-go创建client的内部代码后,整理出如下创建多集群的代码,我得式列代码中包含了 argo、volcano、k8s原生client

import (
	"context"
	"log"
	"os"
	"path/filepath"

	"github.com/argoproj/argo-workflows/v3/cmd/argo/commands/client"
	argoapi "github.com/argoproj/argo-workflows/v3/pkg/apiclient"
	argo "github.com/argoproj/argo-workflows/v3/pkg/client/clientset/versioned"
	"k8s.io/client-go/kubernetes"
	"k8s.io/client-go/rest"
	"k8s.io/client-go/tools/clientcmd"
	"k8s.io/client-go/util/homedir"
	"k8s.io/klog"
	"volcano.sh/apis/pkg/client/clientset/versioned"
)

type Clientset struct {
	Ctx           context.Context
	K8s           *kubernetes.Clientset
	Argo          *argo.Clientset
	ArgoAPIClient argoapi.Client
	Volcano       *versioned.Clientset
}

func NewClient(kubeconfig string) (*Clientset, error) {
	config, err := buildConfig(kubeconfig)
	if err != nil {
		return nil, err
	}
	argoClient, err := argo.NewForConfig(config)
	if err != nil {
		return nil, err
	}

	k8sClient, err := kubernetes.NewForConfig(config)
	if err != nil {
		return nil, err
	}
	// dail kubernetes cluster api server
	version, err := k8sClient.DiscoveryClient.ServerVersion()
	if err != nil {
		return nil, err
	}
	klog.Infof("connected kubernetes cluster, and version is: %s", version.String())
	// init argo api client
	ctx, apiClient := client.NewAPIClient()
	// init volcano client
	volcano, err := versioned.NewForConfig(config)
	if err != nil {
		return nil, err
	}
	return &Clientset{ctx, k8sClient, argoClient, apiClient, volcano}, nil
}

func NewClients(kubeconfig string) (map[string]*Clientset, error) {
	if kubeconfig == "" {
		kubeconfig = os.Getenv("KUBECONFIG")
	}

	if kubeconfig == "" && os.Getenv("KUBECONFIG") == "" {
		if home := homedir.HomeDir(); home != "" {
			kubeconfig = filepath.Join(home, ".kube", "config")
		}
	}

	f, err := os.ReadFile(kubeconfig)
	if err != nil {
		return nil, err
	}
	cfg, err := clientcmd.Load(f)
	if err != nil {
		return nil, err
	}

	clients := map[string]*Clientset{}
	for ctxName, ctx := range cfg.Contexts {
		clientConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
			&clientcmd.ClientConfigLoadingRules{ExplicitPath: kubeconfig},
			&clientcmd.ConfigOverrides{
				AuthInfo:       *cfg.AuthInfos[ctx.AuthInfo],
				ClusterInfo:    *cfg.Clusters[ctx.Cluster],
				Context:        *ctx,
				CurrentContext: ctxName,
				Timeout:        "5s",
			})
		restCofnig, err := clientConfig.ClientConfig()
		if err != nil {
			return nil, err
		}

		k8sClient, err := kubernetes.NewForConfig(restCofnig)
		if err != nil {
			return nil, err
		}
		// 这里一定要调用Discovery().ServerVersion(),探测Kube Apiserver是否可用,因为kubernetes.NewForConfig(restCofnig)不会去检查服务是否可用,当服务不可用时,该方法不会返回错误的
		version, err := k8sClient.Discovery().ServerVersion()
		if err != nil {
			log.Printf("connect cluster %v failed: %v\n", ctx.Cluster, err.Error())
			return nil, err
		}
		klog.Infof("connected kubernetes cluster %s succeed, and version is: %s", ctx.Cluster, version.String())
		argoClient, err := argo.NewForConfig(restCofnig)
		if err != nil {
			return nil, err
		}

		c, apiClient, err := argoapi.NewClientFromOpts(argoapi.Opts{ClientConfig: clientConfig})
		if err != nil {
			return nil, err
		}

		volcano, err := versioned.NewForConfig(restCofnig)
		if err != nil {
			return nil, err
		}
		clients[ctx.Cluster] = &Clientset{c, k8sClient, argoClient, apiClient, volcano}
	}
	return clients, nil
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值