如何使用client-go(6.0.0)回滚apps/v1beta2 Deployment至指定版本?
你说得对,apps/v1beta2版本的Deployment API确实没有.spec.rollbackTo字段——这个字段在更早的apps/v1beta1里存在,但在v1beta2中被移除了,回滚逻辑也换成了基于ReplicaSet历史的方式。下面是具体的实现步骤:
步骤1:获取目标Deployment关联的所有历史ReplicaSet
每次Deployment更新时,Kubernetes都会创建新的ReplicaSet来保留历史版本。你可以通过标签筛选出和目标Deployment绑定的ReplicaSet:// 构造标签选择器,匹配Deployment对应的ReplicaSet labelSelector := labels.SelectorFromSet(labels.Set{"deployment.kubernetes.io/name": "your-deployment-name"}) listOpts := metav1.ListOptions{LabelSelector: labelSelector.String()} // 列出指定命名空间下的ReplicaSet rsList, err := clientset.AppsV1beta2().ReplicaSets("your-namespace").List(listOpts) if err != nil { // 处理错误 }每个ReplicaSet的
metadata.annotations里会有deployment.kubernetes.io/revision字段,这个就是对应的修订版本号,你可以根据这个找到你要回滚到的目标ReplicaSet。步骤2:提取目标ReplicaSet的Pod模板
找到目标修订版本的ReplicaSet后,取出它的.spec.template——这就是该版本Deployment使用的Pod模板:var targetRS *appsv1beta2.ReplicaSet for _, rs := range rsList.Items { revision, ok := rs.Annotations["deployment.kubernetes.io/revision"] if ok && revision == "your-target-revision-number" { targetRS = &rs break } } if targetRS == nil { // 未找到目标修订版本,处理错误 } targetPodTemplate := targetRS.Spec.Template步骤3:更新Deployment的Pod模板完成回滚
将目标Deployment的.spec.template替换为上面获取到的模板,然后调用Update接口完成回滚:// 获取当前Deployment deploy, err := clientset.AppsV1beta2().Deployments("your-namespace").Get("your-deployment-name", metav1.GetOptions{}) if err != nil { // 处理错误 } // 替换Pod模板 deploy.Spec.Template = targetPodTemplate // 更新Deployment updatedDeploy, err := clientset.AppsV1beta2().Deployments("your-namespace").Update(deploy) if err != nil { // 处理错误 }
补充说明
你提到的相关讨论里也印证了这个思路:在apps/v1beta2中,rollbackTo字段被移除,官方推荐通过复用历史ReplicaSet的Pod模板来实现回滚。这种方式本质上和kubectl rollout undo命令的逻辑一致——kubectl底层也是找到对应版本的ReplicaSet,然后用它的模板更新Deployment。
内容的提问来源于stack exchange,提问作者Anumantha Raja

