最近碰到这样一种情况:在我执行 helm install/upgrade
失败后,通过 helm list
可以获取到对应的 release 为 failed
状态。
此时我再执行 helm upgrade
想更新 release 让它恢复正常但一直报如下错误:
a release named xxx already exists
查遍全网发现所有的解决方案都是先执行 helm delete
删除这个 release,然后重新安装。
可是这样有一个问题,就是实际在 k8s 中有部分资源(如 deployment
)其实已经处于运行状态了而且业务不可中断,而 helm delete
在删除 release 的同时会同步删除掉对应的 k8s 资源,这样的话业务就中断了。
在官网也有一个很坑的解决方案:
经测试,该方案完全不可行。比如有一个 deployment 属于将要删除的 release,此时添加注解 "helm.sh/resource-policy": keep
到该 deployment,然后执行 helm delete
操作。
执行完毕后该 deployment 依然会被删除。。。
最后我去看了下 Helm 源码,发现该注解必须在 release 渲染阶段就已存在,也就是说在执行 helm install/upgrade
的时候你就必须添加该注解到相应资源,然后在下次执行 helm uninstall
时指定 release 的某些资源中已存在该注解时这些资源才会继续保留。
到这里其实已经能大致知道该怎么解决了。
方案一
我们可以在执行 helm uninstall
删除 release 之前,手动修改 release 的元信息,在需要保留的 k8s 资源添加上这个注解 "helm.sh/resource-policy": keep
,然后执行 helm uninstall
操作即可。
但是我们要知道 release 信息实际上是以 secrets 的方式保存在 k8s 对应的命名空间下,所以要修改它我们需要先做解码操作,然后修改完后再做编码操作,最后把编码后的数据又 patch 到 secrets。
而且即便是做完了解码操作,那些资源信息文本数据在命令行下看起来也是一团糟。。所以这种方案我放弃了,不过这里还是贴一下手动修改 helm release 方法:
方案二
修改源码扩展 Helm 功能,为 Helm 添加一个仅删除 release 而不删除关联的 k8s 资源的选项。修改部分如下:
修改完毕后重新编译输出二进制程序,该二进制程序中就会支持 helm uninstall --only-release
选项,编译步骤如下:
git clone https://github.com/zze326/helm.git
# for current os
cd helm && make build
# for linux
cd helm && make build-linux-amd64
编译后生成的二进制程序在 ./bin
目录下。
评论区