1、Argo CD 是什么

Argo CD 是 Kubernetes 的开源 GitOps operator。该项目是 Argo 系列的一部分,Argo 系列是一组用于在 Kubernetes 上运行和管理 jobs 和应用程序的云原生工具。除了 Argo Workflows, Rollouts, and Events, Argo CD 还专注于应用程序交付用例,并可以更轻松地组合三种计算模式:服务、工作流和基于事件的处理。 2020年,Argo CD被云原生计算基金会(CNCF)接纳为孵化级托管项目。

持续部署工具应该为开发人员提供有关托管应用程序状态的见解。这假设有一个用户友好的界面,可以快速回答以下问题:

  • 应用程序配置是否与 Git 中定义的配置同步?

  • 到底什么不匹配?

  • 应用程序是否已启动并正在运行?

  • 到底是什么坏了?

2、核心理念

为了有效地使用Argo CD,我们应该理解两个基本概念:Application 和 Project。让我们先仔细看看该应用程序。

2.1、APPLICATION

该 Application 提供 Kubernetes 资源的逻辑分组,并定义资源清单的源和目标。

Argo CD Application 的主要属性是目标

  • 源指定资源清单在 Git 存储库中的位置。

  • 目标指定应在 Kubernetes 集群中创建资源的位置。

Application 源包括 Git 库的 URL 和存储库内的目录。通常,存储库包含多个目录,每个应用程序环境(例如 QA 和 Prod)一个目录。此类存储库的示例目录结构如下所示:

Application 目标定义部署资源的位置,包括目标 Kubernetes 集群的 API server URL 以及集群命名空间名称。 API server URL 标识部署所有应用程序清单的集群。跨多个集群部署应用程序清单是不可能的,但不同的应用程序可能会部署到不同的集群中。 Namespace 名称用于标识所有 Namespace 级别应用程序资源的目标 Namespace。

因此,Argo CD Application 代表了部署在 Kubernetes 集群中的环境,并将其连接到存储在 Git 存储库中的所需状态。

2.2、同步和健康状态

除了目标之外,Argo CD 应用程序还有两个更重要的属性:Sync status 和 health status。

同步状态回答观察到的应用程序资源状态是否偏离 Git 存储库中存储的资源状态。偏差计算背后的逻辑与 kubectl diff 命令的逻辑等效。同步状态的值可能是同步和不同步。同步状态意味着每个应用程序资源都已找到并且与预期资源状态完全匹配。不同步状态意味着至少一种资源状态与预期状态不匹配或未在目标集群中找到。

健康状态聚合有关组成应用程序的每个资源的观察到的健康状态的信息。每个 Kubernetes 资源类型的运行状况评估逻辑都不同,并导致以下值之一:

  • Healthy:如果所需数量的 Pod 正在运行并且每个 Pod 成功通过就绪探针和存活探针,则 Kubernetes 部署被认为是健康的。

  • Progressing:表示资源尚不健康,但仍有望达到健康状态。如果 Deployment 尚未正常运行,但仍没有达到 ProgressingDeadlineSeconds 字段指定的时间限制,则认为该 Deployment 正在进行中。

  • Degraded:健康状态的对立面。该示例是一个无法在预期超时内达到健康状态的 Deployment。

  • Missing:表示存储在 Git 中但未部署到目标集群的资源。

健康状况和同步状态回答了有关应用程序的两个最重要的问题:

  • 我的应用程序有效吗?

  • 我的运行符合预期吗?

2.3、PROJECT

Argo CD 应用程序提供了一种非常灵活的方式来管理彼此独立的不同应用程序。此功能为团队提供了有关每个基础设施的非常有用的见解,并极大地提高了生产力。但是,这不足以支持具有不同访问级别的多个团队:不同的团队有不同的访问级别。

这些问题的解决方法是为每个团队提供单独的 Argo CD 实例。这不是一个完美的解决方案,因为单独的实例意味着管理开销。为了避免管理开销,Argo CD 引入了 Project 抽象。

除了分离应用程序集之外,Project 还提供以下功能集

  • 限制项目应用程序可以使用哪些 Kubernetes 集群和 Git 存储库

  • 限制项目中每个应用程序可以部署哪些 Kubernetes 资源

2.4、架构

乍一看,GitOps 运算符的实现看起来并不太复杂。理论上,您所需要做的就是克隆带有清单的 Git 存储库,并使用 kubectl diff 和 kubectl apply 来检测和处理配置偏差。直到您尝试为多个团队自动化此过程并同时管理数十个集群的配置之前,情况都是如此。从逻辑上讲,这个过程分为三个阶段,每个阶段都有自己的挑战:

  • 检索资源清单

  • 检测并修复偏差

  • 将结果呈现给最终用户

每个阶段消耗不同的资源,并且每个阶段的实施必须以不同的方式扩展。一个单独的 Argo CD 组件负责每个阶段。

Argo CD 由三个主要组件组成,用于实现 GitOps 协调周期阶段。

  • argocd-repo-server 从 Git 检索清单。

  • argocd-application-controller 将 Git 中的清单与 Kubernetes 集群中的资源进行比较。

  • argocd-api-server 向用户呈现协调结果。

让我们详细了解一下每个阶段以及相应的 Argo CD 组件实现细节。

2.4.1、检索资源清单

Argo CD 中的清单生成是由 argocd-repo-server 组件实现的。这一阶段提出了一系列挑战。

清单生成要求下载 Git 存储库内容并生成随时可用的清单 YAML。首先,每次需要检索预期的资源清单时都下载整个存储库内容太耗时。 Argo CD 通过将存储库内容缓存在本地磁盘上并使用 git fetch 命令仅从远程 Git 存储库下载最近的更改来解决此问题。下一个挑战与内存使用有关。在现实生活中,资源清单很少存储为纯 YAML 文件。在大多数情况下,开发人员更喜欢使用配置管理工具,例如 Helm 或 Kustomize。每次工具调用都会导致内存使用量激增。为了处理内存使用问题,Argo CD 允许用户限制并行清单生成的数量并扩大 argocdrepo-server 实例的数量以提高性能。

2.4.2、检测并修复偏差

控制器加载实时 Kubernetes 集群状态,将其与 argocd-repo-server 提供的预期清单进行比较,并修补有偏差的资源。这一阶段可能是最具挑战性的阶段。为了正确检测偏差,GitOps operator 需要了解集群中的每个资源,并对数千个资源进行比较和更新。

控制器维护每个集群的轻量级缓存,并使用 Kubernetes watch API 在后台更新它。这使得控制器能够在不到一秒的时间内对应用程序执行协调,并使其能够同时扩展和管理数十个集群。每次调谐后,控制器都会获得有关每个应用程序资源的详尽信息,包括同步和运行状况。

2.4.3、将结果呈现给最终用户

最后,必须将调节结果呈现给最终用户。此任务由 argocd-server 组件执行。argocd-server 是一个无状态 Web 应用程序,用于加载有关协调结果的信息并为 Web 用户界面提供支持。该架构设计使得 Argo CD 能够以最小的维护开销为大型企业提供 GitOps 操作服务。

3、部署

要部署 Argo CD application,我们需要指定包含部署清单的 Git 存储库,并以 Kubernetes 集群和命名空间为目标。要为此练习创建 Git 存储库,请打开以下 GitHub 存储库并创建存储库分支

https://github.com/gitopsbook/sample-app-deployment

该 application 可以使用 Web 用户界面、CLI 甚至使用 REST 或 gRPC API 以编程方式创建。由于我们已经安装并配置了 Argo CD CLI,让我们使用它来部署应用程序。继续执行以下命令来创建应用程序:

应用程序创建后,我们就可以使用 Argo CD CLI 来获取有关应用程序状态的信息。使用以下命令获取有关 sample-app 应用程序状态的信息:

从命令输出中我们可以看到,应用程序不同步并且不健康。默认情况下,如果 Argo CD 检测到偏差,则不会将 Git 存储库中定义的资源推送到集群中。 Argo CD 检测到该应用程序应该有一个 deployment 和一个 service,但这两个资源都丢失了。要部署资源,我们需要配置自动应用程序同步,使用同步策略或手动触发同步。要触发同步并部署资源,请使用以下命令:

一旦触发同步,Argo CD 就会将存储在 Git 中的清单推送到 Kubernetes 集群,然后重新评估应用程序状态。同步完成后,最终的应用程序状态将打印到控制台。示例应用程序已成功同步,并且每个结果都与预期状态匹配。

使用用户界面检查应用程序:

除了 CLI 和 API 之外,Argo CD 还提供用户友好的 Web 界面。使用 Web 界面,您可以获得跨多个集群部署的所有应用程序的高级视图以及有关每个应用程序资源的非常详细的信息。打开 https://<host>:<port> URL 以查看 Argo CD 用户界面中的应用程序列表。

4、深入 Argo CD 特性

4.1、GitOps 驱动的部署

为了执行 GitOps 部署,我们需要更新资源清单并让 GitOps 操作员将更改推送到 Kubernetes 集群中。第一步,使用以下命令克隆部署存储库:

git clone git@github.com:<username>/sample-app-deployment.git
cd sample-app-deployment

接下来,使用以下命令更改 Deployment 资源的映像版本:

sed -i '' 's/sample-app:v.*/sample-app:v0.2/' deployment.yaml

使用 git diff 命令确保您的 Git 存储库具有预期的更改

最后,使用 git commit 和 git push 将更改推送到远程 Git 存储库:

git commit -am "update deployment image" 
git push

让我们使用 Argo CD CLI 确保 Argo CD 正确检测到 Git 中的清单更改,然后触发同步过程以将更改推送到 Kubernetes 集群:

使用 argocdsync 命令触发同步过程:

argocd app sync sample-app

4.2、资源 hook

资源清单同步只是基本用例。在现实生活中,我们经常需要在实际部署之前和之后执行额外的步骤。例如,设置维护页面,在新版本部署之前执行数据库迁移,最后删除维护页面。

传统上,这些部署步骤是在 CI 管道中编写的脚本。然而,这再次需要 CI 服务器的生产访问,这涉及安全威胁。为了解决这个问题,Argo CD 提供了一个称为资源挂钩的功能。这些钩子允许在同步过程中运行自定义脚本,这些脚本通常打包到 Kubernetes 集群内部的 Pod 或作业中。

该钩子是存储在 Git 存储库中的 Kubernetes 资源清单,并使用 argocd.argoproj.io/hook 注释进行注释。注释值包含应该执行挂钩的阶段的逗号分隔列表。支持以下阶段:

  • Pre-sync:在应用清单之前执行

  • sync:在所有预同步挂钩完成并成功后执行,与清单应用同时执行

  • Skip:指示 Argo CD 跳过清单的应用

  • Post-sync:在所有同步挂钩完成并成功、成功应用且所有资源处于健康状态后执行

  • sync-fai:同步操作失败时执行

同步过程包括三个主要阶段。预同步阶段用于执行数据库迁移等准备任务。同步阶段包括应用程序资源的同步。最后,后同步阶段运行后处理任务,例如电子邮件通知。