英文:
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服务器的负载。
以下是一些入门链接:
- 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
英文:
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:
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论