1

我正在编写一个控制器来监视 kubernetes服务对象,并在它们包含某个标签时创建流量拆分。

由于原生 kubernetes go 客户端不支持 trafficsplit 对象,我不得不想办法扩展客户端,使其能够识别自定义资源。我发现这个指南很有帮助,让我可以像这样解决这个问题 -

import (
    "splitClientV1alpha1 "github.com/servicemeshinterface/smi-sdk-go/pkg/gen/client/split/clientset/versioned/typed/split/v1alpha1"
    "k8s.io/client-go/kubernetes"
    ...
)

// getting ./kube/config from file
kubehome := filepath.Join(homedir.HomeDir(), ".kube", "config")
// Building the config from file
kubeConfig, err = clientcmd.BuildConfigFromFlags("", kubehome)
if err != nil {
    return fmt.Errorf("error loading kubernetes configuration: %w", err)
}

// Creating the native client object
kubeClient, err := kubernetes.NewForConfig(kubeConfig)
if err != nil {
    return fmt.Errorf("error creating kubernetes client: %w", err)
}

// Creating another clientset exclusively for the custom resource
splitClient, err := splitClientV1alpha1.NewForConfig(kubeConfig)
if err != nil {
    return fmt.Errorf("error creating split client: %s", err)
}

我觉得必须有一种方法可以使用 trafficsplit 模式扩展 kubeClient 对象,而不是像我那样创建一个单独的客户端。有什么办法可以做到这一点?

4

1 回答 1

2

这绝对是可能的!你想使用 go 的结构扩展功能:)

基本上,我们创建一个扩展两者的结构,kubernetes.ClientsetsplitClientV1alpha1.SplitV1alpha1Client使用与您上面的代码非常相似的代码对其进行初始化。然后,我们可以在该结构上使用来自任一客户端的方法。

import (
    "fmt"
    splitClientV1alpha1 "github.com/servicemeshinterface/smi-sdk-go/pkg/gen/client/split/clientset/versioned/typed/split/v1alpha1"
    "k8s.io/client-go/kubernetes"
    "k8s.io/client-go/tools/clientcmd"
    "k8s.io/client-go/util/homedir"
    "path/filepath"
)

type MyKubeClient struct {
    kubernetes.Clientset
    splitClientV1alpha1.SplitV1alpha1Client
}

func getClient() (*MyKubeClient, error) {
    // getting ./kube/config from file
    kubehome := filepath.Join(homedir.HomeDir(), ".kube", "config")
    // Building the config from file
    kubeConfig, err := clientcmd.BuildConfigFromFlags("", kubehome)
    if err != nil {
        return nil, fmt.Errorf("error loading kubernetes configuration: %w", err)
    }

    // Creating the native client object
    kubeClient, err := kubernetes.NewForConfig(kubeConfig)
    if err != nil {
        return nil, fmt.Errorf("error creating kubernetes client: %w", err)
    }

    // Creating another clientset exclusively for the custom resource
    splitClient, err := splitClientV1alpha1.NewForConfig(kubeConfig)
    if err != nil {
        return nil, fmt.Errorf("error creating split client: %s", err)
    }

    return &MyKubeClient{
        Clientset:           *kubeClient,
        SplitV1alpha1Client: *splitClient,
    }, nil
}

func doSomething() error {
    client, err := getClient()
    if err != nil {
        return err
    }

    client.CoreV1().Pods("").Create(...)
    client.TrafficSplits(...)
}

如果您需要将自定义客户端传递给只需要原始的函数kubernetes.ClientSet,您可以这样做:


func doSomething() error {
    client, err := getClient()
    if err != nil {
        return err
    }

    useClientSet(&client.Clientset)
}

func useOriginalKubeClientSet(clientSet *kubernetes.Clientset) {
    # ... do things
}
于 2021-05-19T07:34:32.017 回答