使用golang SDK在Kubernetes中持续监视Pods

huangapple go评论82阅读模式
英文:

Continuously Watch Pods in Kubernetes using golang SDK

问题

我想使用client-go Kubernetes SDK持续观察Pod的变化。我正在使用以下代码来观察这些变化:

func (c *Client) watchPods(namespace string, restartLimit int) {
	fmt.Println("Watch Kubernetes Pods")
	watcher, err := c.Clientset.CoreV1().Pods(namespace).Watch(context.Background(),
		metav1.ListOptions{
			FieldSelector: "",
		})
	if err != nil {
		fmt.Printf("error create pod watcher: %v\n", err)
		return
	}

	for event := range watcher.ResultChan() {
		pod, ok := event.Object.(*corev1.Pod)
		if !ok || !checkValidPod(pod) {
			continue
		}
		owner := getOwnerReference(pod)
		for _, c := range pod.Status.ContainerStatuses {
			if reflect.ValueOf(c.RestartCount).Int() >= int64(restartLimit) {
				if c.State.Waiting != nil && c.State.Waiting.Reason == "CrashLoopBackOff" {
					doSomething()
				}
				if c.State.Terminated != nil {
					doSomethingElse()
				}
			}
		}
	}
}

这段代码可以观察Pod的变化,但是在一段时间后会退出。我想要持续运行这段代码。我还想知道它对API服务器的负载有多大,并且如何以最佳方式运行控制循环以查找变化。

英文:

I want to watch changes to Pods continuously using the client-go Kubernetes SDK. I am using the below code to watch the changes:

func (c *Client) watchPods(namespace string, restartLimit int) {
	fmt.Println("Watch Kubernetes Pods")
	watcher, err := c.Clientset.CoreV1().Pods(namespace).Watch(context.Background(),
		metav1.ListOptions{
			FieldSelector: "",
		})
	if err != nil {
		fmt.Printf("error create pod watcher: %v\n", err)
		return
	}

	for event := range watcher.ResultChan() {
		pod, ok := event.Object.(*corev1.Pod)
		if !ok || !checkValidPod(pod) {
			continue
		}
		owner := getOwnerReference(pod)
		for _, c := range pod.Status.ContainerStatuses {
			if reflect.ValueOf(c.RestartCount).Int() >= int64(restartLimit) {
				if c.State.Waiting != nil && c.State.Waiting.Reason == "CrashLoopBackOff" {
					doSomething()
				}
				if c.State.Terminated != nil {
					doSomethingElse()
				}
			}
		}
	}
}

The code is watching changes to the Pods, but it exits after some time. I want to run this continuously. I also want to know how much load it puts on the API Server and what is the best way to run a control loop for looking for changes.

答案1

得分: 1

在Watch中,与API服务器建立了一个长轮询连接。建立连接后,API服务器会发送一批初始事件和任何后续更改。在超时发生后,连接将被断开。

我建议使用Informer而不是设置Watch,因为它更加优化和易于设置。在创建Informer时,您可以注册特定的函数,当Pod被创建、更新和删除时将被调用。即使在Informer中,您也可以使用labelSelector来定位特定的Pod,类似于Watch。您还可以创建共享的Informer,这些Informer在集群中的多个控制器之间共享。这可以减轻API服务器的负载。

以下是一些入门链接:

  1. https://aly.arriqaaq.com/kubernetes-informers/
  2. https://www.cncf.io/blog/2019/10/15/extend-kubernetes-via-a-shared-informer/
  3. https://pkg.go.dev/k8s.io/client-go/informers
英文:

In Watch, a long poll connection is established with the API server. Upon establishing a connection, the API server sends an initial batch of events and any subsequent changes. The connection will be dropped after a timeout occurs.

I would suggest using an Informer instead of setting up a watch, as it is much more optimized and easier to setup. While creating an informer, you can register specific functions which will be invoked when pods get created, updated and deleted. Even in informers you can target specific pods using a labelSelector, similar to watch. You can also create shared informers, which are shared across multiple controllers in the cluster. This results in reducing the load on the API server.

Below are few links to get you started:

  1. https://aly.arriqaaq.com/kubernetes-informers/
  2. https://www.cncf.io/blog/2019/10/15/extend-kubernetes-via-a-shared-informer/
  3. https://pkg.go.dev/k8s.io/client-go/informers

huangapple
  • 本文由 发表于 2023年1月3日 15:27:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/74990181.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定