侧边栏壁纸
博主头像
张种恩博主等级

一个能运维的 JPG 搬运工

  • 累计撰写 703 篇文章
  • 累计创建 60 个标签
  • 累计收到 24 条评论

Helm 删除 Release 时保留已有的 Kubernetes 资源

张种恩
2022-04-12 / 0 评论 / 0 点赞 / 52 阅读 / 1,443 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2022-04-12,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

最近碰到这样一种情况:在我执行 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 目录下。

0

评论区