Sendible 如何从 Jenkins 迁移到 Argo

Sendible

我叫 Tim Collins,是Sendible^[1]^的高级 DevOps 工程师。在 Sendible,我们正在着手一个计划,使我们的应用和开发堆栈更适合云原生,但我们很快发现我们现有的 CI 解决方案不能胜任这项工作。我们开始寻找替代方案,并认为记录我们的过程可能会帮助其他处于类似情况的人。

为什么?

Jenkins 可以说仍然是事实标准的 CI 工具。它是成熟的,在互联网上有大量知识渊博的人,他们可以帮助你从中得到最好的东西。然而,成熟也会带来挑战。

主要的是……

插件意大利面条

Jenkins 有大量的插件。缺点是,Jenkins 有大量的插件!找到适合自己需要的插件,评估插件的安全影响,然后保持更新/维护,这些开始成为一个真正令人头疼的问题。

不是云原生

当然,在 Kubernetes 中运行 Jenkins 是可能的,同样也可能在触发工作时启动动态 pod。然而,Jenkins 最初并不是为这种工作方式设计的,在使用它之后,我们开始清楚地发现它并不能与 Kubernetes 完全互操作。一个明显的例子是,Jenkins 的主安装只能在一个 pod 中运行,因此不存在 HA 部署以备排除或崩溃状况。

同样,Jenkins 运行作业(job)的自然方法是将所有需要的容器部署到一个 pod 中。这意味着在运行开始时启动所有需要的容器,直到运行结束时才释放它们。由于所有内容都在一个 pod 中,而 pod 不能跨越多个节点,因此如何使用节点来适应工作负载存在限制。

当然,有很多方法可以解决这个问题——有一段时间,我们用级联的 Jenkins 作业来欺骗它,让它为我们提供动态供应的 pod……但过了一段时间,我们意识到我们只是在与一个工具斗争,让它做一些它原本不打算做的事情。结果,流水线代码很快变得难以维护,调试工作变得复杂。

成本效率

在 Sendible,我们发现自己采用了越来越多的变通方法,尝试用我们熟悉的工具运行 CI,使用 Kubernetes,并降低成本。事实上,我们在维护成本上损失的时间和金钱比我们能节省的要多。

还有其他成本方面的考虑。一个使用良好的 Jenkins 控制器可能会消耗大量的系统资源,前面提到的“每个作业一个 pod”的问题意味着你可能需要提供大型服务器。如果你在 Kubernetes 之外运行 Jenkins,并且没有一个自动伸缩系统,那么可能会一直运行代理节点,这可能会增加你的成本。

为什么使用 Argo?

我们已经在 GitOps 中使用了 Argo CD,并且已经完成了一个关于 Argo Rollouts 的 POC 来管理未来的版本。因此,至少调查一下它们的兄弟项目 Workflows 和 Events 是有意义的。

很明显,与我们现有的 CI 解决方案相比,Argo Workflows 要快得多,由于有了重试选项,我们可以利用集群自动伸缩器和 AWS Spot 实例,这立即将我们的 CI/CD 成本降低了 90%!我们发现,只有在需要时才创建 pod,从而能够为相同的作业提供更小的服务器,从而节约了更多的成本。

我们还想要一些能够扩展到 CI 之外的东西。最终,我们追求的是一个灵活的“实干工具”,我们可以在多种情况下使用。除了常规的 CI 工作,我们已经在使用 Argo Workflows 和 Argo Events:

  • 警报补救(从 Alertmanager 接收警报并触发工作流来补救问题)。
  • 从 Slack 创建测试环境。
  • 自动测试我们的备份恢复,有问题时发出警报。

花了多长时间?

与所有 DevOps 一样,这个过程正在进行中,但在最初的项目中只有一个人,只有一些 Kubernetes 知识,没有 Argo Workflows 或 Events 知识,我们在一天内就完成了基本的概念验证和运行。然后经过两周的改进,我们制作了足够生产使用的 Workflows(使它成为 HA,添加 SSO 等),以便更广泛的团队采用它。

我们一路学到了的一些东西

与所有工具实现一样,这个过程也并非没有挑战。希望下面这个简短的列表可以帮助那些踏上类似旅程的人:

忘掉“Jenkins 式”

如果你多年来一直使用 Jenkins Pipelines,那么你可能不会自然地想到云原生流水线解决方案。尽量避免在不同的工具中重写 Jenkins 流水线。相反,花点时间去理解流水线的设计目的是什么,并对其进行改进。

Argo Workflows 的动态 pod 创建意味着你必须重新处理在工作期间保存数据的方式。正式的方法是在外部存储解决方案(如 S3)中使用工件存储库,但是对于更多的瞬态数据,你可以考虑设置一个 RWM PVC 来在几个 pod 之间共享存储卷。

同样,你可以将此迁移作为重新考虑并行性和任务排序的机会。Jenkins 流水线当然提供了并行运行的步骤,但这是一个必须有意识地选择的东西。Argo Workflows 的方法是默认情况下并行运行步骤,允许你简单地定义任务之间的依赖关系。你可以以任何顺序编写工作流,然后只需调整依赖项。我们建议你继续细化这些依赖项,以找到最适合你的。

利用工作流模板

在可能的情况下,尝试将工作流中的每个步骤视为其自身的功能。你可能会发现你的各种 CI 工作都有很多共同的功能。例如:

  • 从 Git 克隆
  • 构建容器
  • 更新票务管理系统或 Slack 的状态

将每个流程步骤编写为单独的工作流模板。这允许你通过将这些模板拼接到 DAG 中,然后将适当的参数传递给它们,从而构建一个相对地新的 CI 流程。随着时间的推移,编写新的 CI 流程主要成为将构建块组合在一起的练习。

你不需要“大爆炸”

“迁移”这个词是可怕的,而且有可能被填满 💰 符号。其实不必如此。

如果你已经有了 Jenkins,那就不要想把它撕掉,或者认为你必须一次把所有东西都换掉。你可以在 Jenkins 旁边慢慢运行 Workflows——你甚至可以让 Jenkins 触发 Workflows。当我们开始时,我们先转移自动化集成测试,然后再转移到更复杂的 CI 工作。

利用 Argo Slack 频道和 Github 讨论页面

Argo 文档很好,Github 本身也是一样的好(特别是 Github 的讨论页面),但有一群知识渊博的人以奇怪而奇妙的方式使用 Argo,他们大多在Slack 频道^[2]^中闲逛。

下一步?

随着我们每天使用 Argo Workflows,我们仍然在学习关于它的新东西,我们仍然处于不断重构我们的 Workflows 以获得绝对最好的结果的阶段。

版本 3.1 的 Argo Workflows 已经不远了,我们期待着即将到来的特性。需要特别注意的是,条件参数^[3]^将允许我们删除一些脚本步骤,容器集^[4]^将允许我们加快 CI 中的某些步骤。

如果你对我在 Argo Workflows 和 Argo Events 方面的经验有任何疑问,你可能会在 CNCF Slack 工作空间中找到我,或者你可以通过 Sendible 网站联系我。

参考资料

[1] Sendible: https://www.sendible.com/
[2] Slack 频道: https://slack.cncf.io/
[3] 条件参数: https://argoproj.github.io/argo-workflows/...
[4] 容器集: https://argoproj.github.io/argo-workflows/...

原文链接:https://mp.weixin.qq.com/s/4oH5Udc9OuScNOA...

(= ̄ω ̄=)··· 暂无内容!

请勿发布不友善或者负能量的内容。与人为善,比聪明更重要!