使用Client-go动态添加标签到Kubernetes中的Pod

aurhwmvo  于 2022-11-21  发布在  Kubernetes
关注(0)|答案(2)|浏览(229)

我想创建一个控制器,并在(通过部署)创建新pod时侦听pod事件,然后将属于部署的所有标签添加到创建的pod,这在client-go的规模上是否可行?

frebpwbc

frebpwbc1#

为了观察pod事件,你需要使用通知器。通知器有内置的优化,以避免过载的API服务器。
PodInterface中提供了一种修补方法,可用于向移液器添加标签。
下面是一个示例代码供大家参考,main函数中添加了informer代码,LabelPod函数实现了标签逻辑。

package main

import (
    "context"
    "encoding/json"
    "fmt"
    "time"

    v1 "k8s.io/api/core/v1"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/apimachinery/pkg/labels"
    "k8s.io/apimachinery/pkg/types"
    "k8s.io/apimachinery/pkg/util/wait"
    "k8s.io/client-go/informers"
    "k8s.io/client-go/kubernetes"
    "k8s.io/client-go/rest"
    "k8s.io/client-go/tools/cache"
)

type patchStringValue struct {
    Op    string `json:"op"`
    Path  string `json:"path"`
    Value string `json:"value"`
}

func main() {
    clientSet := GetK8sClient()

    labelOptions := informers.WithTweakListOptions(func(opts *metav1.ListOptions) {
        opts.LabelSelector = GetLabelSelectorForDeployment("deployment-name", "namespace-name")
    })
    informers := informers.NewSharedInformerFactoryWithOptions(clientSet, 10*time.Second, informers.WithNamespace("namespace-name"), labelOptions)

    podInformer := informers.Core().V1().Pods()

    podInformer.Informer().AddEventHandler(
        cache.ResourceEventHandlerFuncs{
            AddFunc: handleAdd,
        },
    )

    informers.Start(wait.NeverStop)
    informers.WaitForCacheSync(wait.NeverStop)

}

func GetLabelSelectorForDeployment(Name string, Namespace string) string {
    clientSet := GetK8sClient()

    k8sClient := clientSet.AppsV1()

    deployment, _ := k8sClient.Deployments(Namespace).Get(context.Background(), Name, metav1.GetOptions{})

    labelSet := labels.Set(deployment.Spec.Selector.MatchLabels)

    return string(labelSet.AsSelector().String())
}

func handleAdd(obj interface{}) {
    k8sClient := GetK8sClient().CoreV1()
    pod := obj.(*v1.Pod)
    fmt.Println("Pod", pod.GetName(), pod.Spec.NodeName, pod.Spec.Containers)
    payload := []patchStringValue{{
        Op:    "replace",
        Path:  "/metadata/labels/testLabel",
        Value: "testValue",
    }}
    payloadBytes, _ := json.Marshal(payload)

    _, updateErr := k8sClient.Pods(pod.GetNamespace()).Patch(context.Background(), pod.GetName(), types.JSONPatchType, payloadBytes, metav1.PatchOptions{})
    if updateErr == nil {
        fmt.Println(fmt.Sprintf("Pod %s labelled successfully.", pod.GetName()))
    } else {
        fmt.Println(updateErr)
    }

}

func GetK8sClient() *kubernetes.Clientset {
    config, err := rest.InClusterConfig()
    if err != nil {
        panic(err.Error())
    }
    // creates the clientset
    clientset, err := kubernetes.NewForConfig(config)
    if err != nil {
        panic(err.Error())
    }

    return clientset
}
v2g6jxz6

v2g6jxz62#

这是怎么回事?
以下是手动标记前的pod:

❯ kubectl get po --show-labels
NAME                            READY   STATUS    RESTARTS   AGE   LABELS
nginx-deploy-6bdc4445fd-5qlhg   1/1     Running   0          13h   app=nginx,pod-template-hash=6bdc4445fd
nginx-deploy-6bdc4445fd-pgkhb   1/1     Running   0          13h   app=nginx,pod-template-hash=6bdc4445fd
nginx-deploy-6bdc4445fd-xdz59   1/1     Running   0          13h   app=nginx,pod-template-hash=6bdc4445fd

在这里,我用标签“test=2”标记pod“nginx-deploy-6 bdc 4445 fd-5 qlhg”:

❯ kubectl label pod nginx-deploy-6bdc4445fd-5qlhg test=2
pod/nginx-deploy-6bdc4445fd-5qlhg labeled

以下是手动标记后的pod:

❯ kubectl get po --show-labels
NAME                            READY   STATUS    RESTARTS   AGE   LABELS
nginx-deploy-6bdc4445fd-5qlhg   1/1     Running   0          13h   app=nginx,pod-template-hash=6bdc4445fd,test=2
nginx-deploy-6bdc4445fd-pgkhb   1/1     Running   0          13h   app=nginx,pod-template-hash=6bdc4445fd
nginx-deploy-6bdc4445fd-xdz59   1/1     Running   0          13h   app=nginx,pod-template-hash=6bdc4445fd

相关问题