我想使用客户端-go Kubernetes SDK持续观察Pods的变化。我使用下面的代码来观察这些变化:
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: %vn", 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服务器带来了多少负载,以及运行控制循环以查找更改的最佳方式是什么。
在Watch中,与API服务器建立长轮询连接。在建立连接后,API服务器发送初始批事件和任何后续更改。超时后,连接将被丢弃。
我建议使用Informer而不是设置手表,因为它更优化,更容易设置。在创建通知器时,您可以注册特定的函数,这些函数将在创建、更新和删除pod时调用。即使在通知器中,您也可以使用labelSelector(类似于watch)来定位特定的pod。您还可以创建共享的通知器,这些通知器在集群中的多个控制器之间共享。这将减少API服务器上的负载。
下面是一些链接,让你开始:
- https://aly.arriqaaq.com/kubernetes-informers/
- https://www.cncf.io/blog/2019/10/15/extend-kubernetes-via-a-shared-informer/
- https://pkg.go.dev/k8s.io/client-go/informers