在 JFrog,我们依靠 Kubernetes 和 Helm 来编排我们的系统并保持我们的工作负载运行并保持最新状态。 我们的 JFrog Cloud 服务最初使用 Helm v2 和 Tillerless 插件部署以增强安全性,但现在我们已成功将数千个版本迁移到 Helm v3。
与许多 SaaS 服务提供商一样,JFrog Cloud 在不同地区的许多 Kubernetes 集群中运行,包括 AWS、Azure 和 Google 云提供商。
我们在此过程中学到了一些重要的经验教训,很高兴与大家分享。
为什么迁移到 Helm v3
Helm v3 的第一个版本于 2019 年 11 月发布, Helm v2 在一年内仍然有更新版本。 但是随着 Helm 2.17.0 的最终版本于 2020 年 11 月发布,Helm v3 现在已经是 Helm 开发者社区支持的唯一标准。
Helm v3 提供了一些重大改进,最显着的是删除了 Tiller。 这个集群内的服务器与 Helm v2 客户端交互的需要管理员权限才能执行其职责,这被认为是共享 K8S 集群中的安全风险。 这可以通过 Tillerless 插件来克服,但 Helm v3 不再需要这样做。
此外,Helm v3 提供了一些新功能和更高的稳定性。 它现在也是唯一一个会在未来获得有效性和安全性更新的版本。
迁移策略
为了更轻松地将集群从 Helm v2 迁移到 v3,Helm 开发人员社区创建了 helm-2to3 插件以与 helm3 客户端一起使用。 这里有一篇Helm 博客文章提供了有关如何使用它的一些很好的信息。
安装插件很简单:
$ helm3 plugin install https://github.com/helm/helm-2to3
但是您接下来如何执行任务可能会根据您需要迁移的版本数量而有所不同。
手动迁移
如果您只需要迁移几个版本,您可以通过客户端在命令行上进行一一迁移。
首先,您可以使用 helm list 命令列出当前命名空间的所有已部署或失败的版本:
$ helm2 list
NAME REVISION UPDATED STATUS CHART APP VERSION NAMESPACE
postgres 1 Thu Nov 14 15:01:00 2019 DEPLOYED postgresql-7.1.0 11.5.0 postgres
然后,您可以通过迁移插件执行每个命名版本的转换。 我们建议首先使用 --dry-run 标志来做一下预演,以确保之后的转换运行没问题。
$ helm3 2to3 convert --dry-run postgres
$ helm3 2to3 convert postgres
您可以对所有版本重复此过程,您就完成了!
企业级的自动化迁移
要将多个 Helm v2 版本迁移到 v3,您需要使用 shell 脚本自动化该过程。
您的脚本将需要转换的所有版本的列表。 您可以使用 Helm v2 客户端生成一个列表,在本例中生成一个名为 release.log 的文件。
$ helm2 tiller run -- helm2 ls --max=0 | sed -n '1!p' | awk 'FNR > 1 { print $1 }' > releases.log
对于相对较少的版本(最多约 200 个),这会产生快速的结果。
然而,更多的情况下,Helm 客户端需要很长时间才能获取所有版本。
此外,我遇到了 AWS EKS 集群的 Kubernetes API 限制。
JFrog Cloud 服务在每个 Kubernetes 集群上运行数千个 Helm 版本,因此需要一种替代的、更快的方法。
由于所有 Tiller secrets都被标记了,我们发现我们可以使用 kubectl 命令将它们提取到releases.log 文件中:
$ kubectl -n kube-system get secret -l OWNER=TILLER,STATUS=DEPLOYED | awk 'FNR > 1 { print $1 }' | cut -f1 -d"." > releases.log
使用我们在releases.log 中的Helm v2 版本列表,我们可以使用bash 脚本自动执行迁移步骤:
#!/bin/bash
# Get releases list
RELEASES=$(cat releases.log )
for r in $RELEASES
do
echo
echo "Processing release $r"
helm3 2to3 convert --tiller-out-cluster --release-versions-max=5 \
--delete-v2-releases --dry-run 2>&1 | tee -a convert.log
done
在此脚本中,您可能想要或需要更改这些标志:
--tiller-out-cluster 如果你没有在 Kubenetes 集群中运行 Tiller,则使用; 如果安装了 Tiller,则应将其删除。
--delete-v2-releases 在迁移到 Helm v3 后删除Helm v2 版本
--dry-run 用于测试迁移脚本是否工作,不真正执行,执行实际迁移时需要删除此参数
如果您选择省略标志 --delete-v2-releases 并保留 Helm 2 版本,您可以稍后使用以下命令清理它们:
$ helm3 2to3 cleanup --tiller-out-cluster --releases-cleanup --skip-confirmation
该脚本在文件 convert.log 中查看迁移结果,您应该查看该文件以了解可能遇到的任何迁移问题。
在我们迁移 JFrog Cloud 服务时,并非所有版本都在同一 chart 版本上——它们使用了首次部署时有效的 charts。 所以一些迁移的旧版本无法使用 Helm v3 升级。
问题是一些 Helm v3 标签和注释没有被添加到迁移的 Kubernetes 对象中。 当检查显示它们不存在时,通过将它们添加到 Helm 升级步骤很容易解决这个问题:
$ kubectl -n ${NAMESPACE} label deployment -l "app.kubernetes.io/instance=${RELEASE}" "app.kubernetes.io/managed-by=Helm"
$ kubectl -n ${NAMESPACE} annotate deployment -l "app.kubernetes.io/instance=${RELEASE}" "meta.helm.sh/release-name=${RELEASE}" "meta.helm.sh/release-namespace=${NAMESPACE}"
让我们开心迁移吧🙂
这就是将您的版本迁移到 Helm v3 所需的全部内容!
这个过程很简单,但请记住,它不一定很快。
当有数千个版本时——就像在大多数企业级组织中一样——迁移过程确实需要时间来完成。
使用这些步骤,您可以创建一个自动化工具,帮助您将在 Kubernetes 中运行的大量版本从 Helm v2 迁移到 Helm v3,并使您的 Kubernetes 基础设施保持最新。
有疑问加站长微信联系(非本文作者)