深入探讨 Argo CD 和企业规模经营的最佳实践
作者:Yuan Tang[1] (Akuity), Hong Wang[2] (Akuity), and Alexander Matyushentsev[3] (Intuit)
这是2021 年中国 KubeCon 演讲[4]的回顾。如果你有兴趣了解更多关于 Argo 或Akuity[5]的产品和服务,你可以在我们的网站[6]上找到我们所有过去和即将举行的会议。
与功夫熊猫的汤面没有秘方不同,企业级的 Argo CD 已经下了不少功夫。你知道 Argo CD 可以支持成千上万的应用吗?你试过连接上百个 Kubernetes 集群吗?那么在一个应用程序中有数千个对象呢?在本文中,我们将深入探讨 Argo CD,回答这些问题,并展示在企业规模上使用 Argo CD 的最佳实践。
Argo 项目[7]是一组 Kubernetes 原生工具,用于部署和运行作业和应用程序。它使用 GitOps 范例,如持续交付和渐进交付,并在 Kubernetes 上实现 MLOps。它由 4 个独立的 Kubernetes 原生项目组成。我们看到团队使用这些产品的不同组合来解决他们独特的挑战。如果你想分享你的 Argo 之旅,请通过CNCF Argo Slack 频道[8]与我们联系,我们将邀请你出席我们的社区会议、相关会议和聚会。
我们有一个非常强大的社区,产品已经被很多公司认可和使用。它被用作事实上的 Kubernetes 原生 GitOps 解决方案和数据处理引擎。
我们获得 CNCF 接纳为孵化阶段项目。该项目已经积累了 2 万多颗 GitHub 星星,600 多名贡献者,以及 350 家最终用户公司。我们对目前的进展感到非常自豪,并享受成为开源社区的一部分。我们正在积极地为 CNCF 毕业阶段而努力。
在我们深入探讨可伸缩性挑战之前,让我们先从总体上讨论一下 GitOps。首先,什么是 GitOps?其中一个定义是:GitOps 是一组使用 Git 管理基础设施和应用程序配置的实践。
这意味着任何 GitOps 操作器都需要按顺序自动化以下步骤:
这正是 Argo CD 所做的。GitOps 的工作流程似乎不太困难,但是关键在于细节。让我们继续,并找出在执行这个 GitOps 工作流时可能出现的问题,以及你可以对此做些什么。
首先,让我们看看 Argo CD 架构。它有三个主要组件:每个对应 GitOps 操作器一个:
现在你可能想知道——为什么有这么多组件?为什么不把所有的东西都打包到一个小应用程序中,执行所有三个 GitOps 功能呢?
原因是 Argo CD 将 GitOps 的功能作为一种服务提供给多个团队。它能够管理多个集群,从多个 Git 仓库检索清单,并为多个独立团队提供服务。
换句话说,你可以为你公司的应用程序工程师启用 GitOps,而不必要求他们运行和管理任何其他软件。
这是非常重要的,特别是当你的组织正在采用 Kubernetes,而应用程序开发人员还不是 Kubernetes 专家的时候。GitOps 即服务不仅允许执行最佳实践,而且还减少了支持团队从开发人员那里收到的问题数量,从而支持自助服务。
这也意味着 Argo CD 需要管理潜在的数百个 Kubernetes 集群,从数千个 Git 仓库中检索清单,并将结果呈现给数千个用户。这时候事情可能会变得更复杂。
好消息是 Argo CD 开箱即用的扩展性非常好。Argo CD 经过优化,可以在 Kubernetes 上运行,使用户能够充分利用 Kubernetes 的可伸缩性。
上面的截图显示了由现有的 Argo CD 实例暴露的指标。正如你所看到的,它管理着跨越 26 个集群部署的近 2300 个应用程序,清单存储在 500 个 Git 仓库中。这意味着数百个应用程序开发团队正在使用该实例和利用 GitOps,而没有太多的开销。
不幸的是,没有应用程序可以无限扩展,在某些边缘情况下,你可能需要调优配置以节省资源和获得更好的性能。让我们开始并浏览一些你可能需要调整的 Argo CD 配置。
Argo CD 的控制器与多个 worker 一起运行。worker 形成一个流水线,一个接一个地协调应用程序。默认进程数为 20。这通常足以处理数百个应用程序。但是,如果你有 1000 个或更多的应用程序,你可能会开始看到几百毫秒的延迟。随着你搭载的应用程序越来越多,延迟可能会增加。
提高性能和减少延迟的一种策略是增加控制器中 worker 的数量。你可以在你的 Argo CD 配置映射中的 controller.status.processors 中修改它。大量的 worker 意味着 Argo CD 将在同一时间处理更多的应用程序。注意,这也需要更多的内存和 CPU,所以不要忘记相应地更新控制器资源请求和限制。
随着应用程序的增多,控制器将消耗更多的内存和 CPU。在某些情况下,运行多个控制器实例可能有意义,其中每个实例使用较少的计算资源。为此,你可以利用控制器分片特性。
与无状态的 web 应用程序不同,仅仅运行 Kubernetes 控制器的多个实例是不可能的。Argo CD 的挑战部分是控制器需要知道整个托管 Kubernetes 集群的状态,以正确地协调应用程序资源。但是,你可能会运行多个控制器实例,其中每个实例负责 Kubernetes 集群的一个子集。
可以通过增加 argocd-application-controller stateful set 中的副本数量来启用分片。不要忘记用相同的值更新 ARGOCD_CONTROLLER_REPLICAS。这需要控制器实例知道副本的总数,并根据更新的配置触发重启以重新平衡工作。因此,每个控制器实例将执行更少的工作,消耗更少的内存和 CPU 资源。
下一个可能需要调优的组件是 Argo CD 仓库服务器。如前所述,仓库服务器负责从 Git 仓库中检索资源清单。这意味着 Argo CD 需要克隆仓库并从克隆的仓库中检索 YAML 文件。
克隆 Git 仓库并不是最具挑战性的任务。GitOps 的最佳实践之一是将应用程序源代码和部署清单分开,因此部署仓库通常很小,不需要很多磁盘空间。因此,如果你有一个仓库,里面有一堆纯 YAML 文件,那么你应该没问题,不需要对 repo 服务器配置做任何更改。
然而,问题是部署库通常不单单是有普通的 YAML 文件。相反,用户更喜欢使用配置管理工具,如 Kustomize、Helm 或 Jsonnet。这些工具帮助开发人员避免重复 YAML 内容,并允许更有效地引入更改。当然,你可能会要求用户将生成的 YAML 存储在部署库中,但是 Argo CD 有一个更好的解决方案:它可以动态地运行清单生成。
Argo CD 支持多个配置管理工具开箱即用,并允许配置任何其他配置管理工具。在清单生成期间,Argo CD repo-server 将执行/fork 配置管理工具的二进制文件并返回生成的清单,这通常需要内存和 CPU。为了保证清单的快速生成,建议增加 repo-server 副本的数量。
通常情况下,运行 3 到 4 个 repo 服务器实例就足够处理数百甚至数千个 Git 仓库了。Argo CD 主动缓存生成的清单,不需要频繁地重新生成清单。
但是,如果将部署清单存储在所谓的 mono 仓库中,可能会遇到一些性能问题。mono 仓库是包含大量应用程序的仓库。
现实世界的 mono 仓库可能有数百个应用程序,包括基础设施组件和多个微服务。通常,单个仓库用于表示整个集群的期望状态。
这将导致一些性能挑战。每次提交到 mono 仓库,都会使该仓库中所有应用程序的现有缓存失效。这意味着 Argo CD 需要突然为数百个应用程序重新生成清单,从而导致 CPU/内存峰值。一些配置管理工具不允许并发生成清单。例如,依赖于带有条件依赖关系的 Helm chart 的多个应用程序必须按顺序处理。
生成大量清单将引入 CPU 和内存峰值。内存峰值是最大的问题,因为它可能会导致内存不足(OOM)死亡。要解决这个问题,你可以通过 reposerver.parallelism.limit 限制每个 repo 服务器实例并发生成清单的数量。这个数字取决于你准备给仓库服务器多少内存,以及配置管理工具使用多少内存。
接下来,我们将介绍另一种性能优化技术,它可能会帮助你完全避免出现生成峰值。Argo CD 使所有应用程序的清单缓存无效,因为它不假设生成的清单仅依赖于应用程序相关目录中的文件。然而,情况经常是这样的。
为了避免在更改无关文件时不必要的缓存无效,你可以配置提交 webhook 并使用 argocd.argoproj.io/manifest-generate-paths 注释来注释 Argo CD 应用程序。每次当 webhook 通知 Argo CD 一个新的提交时,它会检查 webhook 负载中列出的更改文件,如果新的提交没有触及任何与该应用程序相关的文件,就会重用之前提交的任何生成的清单。
API 服务器是一个无状态的 API,可以很好地水平扩展,并且不需要太多的计算资源。API 服务器为所有 Argo CD 应用程序保持内存缓存。因此,如果你使用一个 Argo CD 实例管理超过 5000 个应用程序,你可能需要考虑增加额外的内存限制。
Argo CD 暴露了众多的 Prometheus 指标[9]。下面是几个例子:
你可以使用社区维护的 Grafana 仪表板[10],并查看相关指标的高可用文档[11]。
我们希望这篇文章能让你对你的开发/运营团队在使用 Argo CD 时可以实现的功能有一个大致的了解(这只是我们提供的 Argo 套件中的一个产品)。欲了解更多信息,请访问Akuity 网站[12],并查看下面其他与社区相关的链接。
鸣谢 Wojtek Cicho。
[1]Yuan Tang: https://terrytangyuan.github.io/about/
[2]Hong Wang: https://www.linkedin.com/in/hwang8/
[3]Alexander Matyushentsev: https://www.linkedin.com/in/amatyushentsev/
[4]2021 年中国 KubeCon 演讲: https://github.com/terrytangyuan/public-talks/tree/main/talks/unveil-the-secret-ingredients-for-argo-cd-at-enterprise-scale-kubecon-china-2021
[5]Akuity: https://akuity.io/
[6]网站: https://akuity.io/resources
[7]Argo 项目: https://argoproj.github.io/
[8]CNCF Argo Slack 频道: https://argoproj.github.io/community/join-slack/
[9]众多的 Prometheus 指标: https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/metrics.md
[10]社区维护的 Grafana 仪表板: https://github.com/argoproj/argo-cd/blob/master/examples/dashboard.json
[11]高可用文档: https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/high_availability.md
[12]Akuity 网站: https://akuity.io/
[13]与 Argo 相关的很棒的项目和资源列表: https://github.com/terrytangyuan/awesome-argo
[14]Argo 社区日历: https://calendar.google.com/calendar/embed?src=argoproj@gmail.com
[15]ICS 文件: https://calendar.google.com/calendar/ical/argoproj%40gmail.com/public/basic.ics
[16]Argo 项目的 GitHub 组织: https://github.com/argoproj
[17]社区治理: https://github.com/argoproj/argoproj/blob/master/community/GOVERNANCE.md
[18]Argo 参与了的会议: https://docs.google.com/document/d/1VWiwmintCq7cdoZaW8D49JpEWbLJ6PrOWQNELRg1ALg/edit?usp=sharing
[19]ArgoCon: https://argoproj.github.io/argocon21/
[20]Slack: https://argoproj.github.io/community/join-slack
[21]Twitter: https://twitter.com/argoproj
[22]Reddit: https://www.reddit.com/r/argoproj/