英文:
GoLang - How to get the Kubernetes modifications
问题
我是你的中文翻译助手,以下是翻译好的内容:
我对golang
还不熟悉,我有以下需求:
- 我有一个正在运行的部署,使用的镜像是
nginx:latest
。 - 然后有人手动将此镜像更新为其他镜像(例如:
nginx:1.22
)。 - 我需要获取旧的镜像版本和新的镜像版本。
因此,我在Go语言中研究了"Shared Informers"(共享通知器),并编写了以下代码:
func main() {
// 创建带有重新同步周期和命名空间的所有已知API组版本的共享通知器
factory := informers.NewSharedInformerFactoryWithOptions(clientSet, 1*time.Hour, informers.WithNamespace(namespace_to_watch))
podInformer := factory.Core().V1().Pods().Informer()
defer runtime.HandleCrash()
// 启动通知器
go factory.Start(stopper)
// 同步并调用列表
if !cache.WaitForCacheSync(stopper, podInformer.HasSynced) {
runtime.HandleError(fmt.Errorf("Timed out waiting for caches to sync"))
return
}
podInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: onAdd, // 注册添加事件处理程序
UpdateFunc: onUpdate,
DeleteFunc: onDelete,
})
}
func onUpdate(oldObj interface{}, newObj interface{}) {
oldPod := oldObj.(*corev1.Pod)
newPod := newObj.(*corev1.Pod)
for _, container_old := range oldPod.Spec.Containers {
fmt.Printf("Container Old: %s\n", container_old.Image)
}
for _, container_new := range newPod.Spec.Containers {
fmt.Printf("Container New: %s\n", container_new.Image)
}
}
根据上述代码中的onUpdate
函数,我应该得到两个值,但实际上每次更新时我得到的值都是相同的,如下所示:
Container Old: nginx:latest
Container New: nginx:latest
Container Old: nginx:1.22
Container New: nginx:1.22
Container Old: nginx:1.22
Container New: nginx:1.22
上面的输出是因为onUpdate
函数被触发了三次,但是你可以看到每次输出的值都是相同的。但是我期望的输出应该是这样的:
Container Old: nginx:latest
Container New: nginx:1.22
有人可以帮我解决这个问题吗?
英文:
I am new to golang
and I have the following requirement:
- I have a deployment running with the image
nginx:latest
- Then manually someone update this image to something else (eg:
nginx:1.22
) - I need to get the old image version and the new image version
So, I researched on the "Shared Informers" in Go Lang. And I wrote this:
func main() {
. . .
// create shared informers for resources in all known API group versions with a reSync period and namespace
factory := informers.NewSharedInformerFactoryWithOptions(clientSet, 1*time.Hour, informers.WithNamespace(namespace_to_watch))
podInformer := factory.Core().V1().Pods().Informer()
defer runtime.HandleCrash()
// start informer ->
go factory.Start(stopper)
// start to sync and call list
if !cache.WaitForCacheSync(stopper, podInformer.HasSynced) {
runtime.HandleError(fmt.Errorf("Timed out waiting for caches to sync"))
return
}
podInformer.AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: onAdd, // register add eventhandler
UpdateFunc: onUpdate,
DeleteFunc: onDelete,
})
}
func onUpdate(oldObj interface{}, newObj interface{}) {
oldPod := oldObj.(*corev1.Pod)
newPod := newObj.(*corev1.Pod)
for container_old := range oldPod.Spec.Containers {
fmt.Printf("Container Old :%s", container_old.Image )
}
for container_new := range newPod.Spec.Containers {
fmt.Printf("Container New :%s", container_new.Image )
}
}
As above, according to the onUpdate
function, I should be getting the two values, instead, I am getting the same value on each update as below:
> Container Old : nginx:latest
>Container New : nginx:latest
>Container Old : nginx:1.22
>Container New : nginx:1.22
>Container Old : nginx:1.22
>Container New : nginx:1.22
Above output is because somehow, the onUpdate
function is triggered thrice, but as you can see in all the times, the values are the same (for each output).
But I was expecting something like below:
>Container Old : nginx:latest
>Container New : nginx:1.22
Can someone help me with this?
答案1
得分: 1
当在部署中更新图像时,Pod 将使用新的图像容器重新启动,并且旧的 Pod 规范不再存在。您应该监视部署而不是 Pod,并检查旧部署和新部署对象之间的图像差异。以下是如何修改您的 onUpdate
方法的示例。
func onUpdate(oldObj interface{}, newObj interface{}) {
oldDepl := oldObj.(*v1.Deployment)
newDepl := newObj.(*v1.Deployment)
for oldContainerID := range oldDepl.Spec.Template.Spec.Containers {
for newContainerID := range newDepl.Spec.Template.Spec.Containers {
if oldDepl.Spec.Template.Spec.Containers[oldContainerID].Name == newDepl.Spec.Template.Spec.Containers[newContainerID].Name {
if oldDepl.Spec.Template.Spec.Containers[oldContainerID].Image != newDepl.Spec.Template.Spec.Containers[newContainerID].Image {
fmt.Printf("容器图像已从 %s 更新为 %s",
oldDepl.Spec.Template.Spec.Containers[oldContainerID].Image, newDepl.Spec.Template.Spec.Containers[newContainerID].Image)
}
}
}
}
}
希望对您有所帮助!
英文:
When an image is updated in the deployments, the pods restart with new image containers and there's no trace of the old pod spec remains. You should watch the deployments instead of the pods and check the image between old deployment and new deployment object. Here's a sample of how you can modify your onUpdate
method.
func onUpdate(oldObj interface{}, newObj interface{}) {
oldDepl := oldObj.(*v1.Deployment)
newDepl := newObj.(*v1.Deployment)
for oldContainerID := range oldDepl.Spec.Template.Spec.Containers {
for newContainerID := range newDepl.Spec.Template.Spec.Containers {
if oldDepl.Spec.Template.Spec.Containers[oldContainerID].Name == newDepl.Spec.Template.Spec.Containers[newContainerID].Name {
if oldDepl.Spec.Template.Spec.Containers[oldContainerID].Image != newDepl.Spec.Template.Spec.Containers[newContainerID].Image {
fmt.Printf("CONTAINER IMAGE UPDATED FROM %s to %s",
oldDepl.Spec.Template.Spec.Containers[oldContainerID].Image, newDepl.Spec.Template.Spec.Containers[newContainerID].Image)
}
}
}
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论