Argo CD 是什么?

Argo CD 是一个持续交付(CD)工具,但是目前大部分项目中,已经有 Jenkins、GitLab CICD 等 CD 解决方案,为什么又出来另一个 CD 工具呢?Argo CD 和它们有什么区别呢?Argo CD 是不是有什么特别之处,会取代它们吗?接下来我会一一解答这些疑问。
我们先来看看目前大部分项目中是怎么玩 CICD 的。假设项目采用了微服务架构,所有微服务运行在 Kubernetes 集群中。开发人员往代码库 push 了一个特性或者一个 bug fix,Jenkins 持续集成流水线(CI pipeline)会被自动触发,流水线步骤包括有自动化测试,构建 Docker 镜像和推送到镜像仓库,然后是 CD pipeline,把最新的镜像部署到 Kubernetes 集群中,卖个关子,这一步是如何做的呢?
Argo CD - 图1
是的,最常见的方法就是直接更新应用的部署 yaml 文件,然后将它 apply 到 Kubernetes 集群。

image.png

调整一下 CICD 流水线图,现在应该是下面这样子的。Jenkins 作为 CICD 服务器起到非常关键的作用,这也是大部分项目实施 CICD 的现状。注意,这里的 CD 是 Continuous Delivery
Argo CD - 图3
但是,你有没有考虑过这些问题呢?

  • 必须在 Jenkins 上面安装和设置一些工具,例如 kubectl,helm 等
  • 在 Jenkins 上配置 credentials,这些工具才可以访问 Kubernetes 集群
  • 如果是EKS,那还得配置 Jenkins credentials 以访问 AWS 云平台
  • 因为需要把 Kubernetes cluster credential 提供给外部服务和客户端工具,这就引发了安全问题。尤其是部署多个项目的应用到集群,为了只允许访问特定的 Kubernetes 集群,每个项目有自己的 Kubernetes credentials。更有甚者,如果是很多个集群呢?那这个配置工作就变得繁琐了,安全隐患也更大。
  • 最重要的是,Jenkins 执行完 CD 流水线后,部署状态是不可见的。也就是,kubectl apply 之后,Jenkins 是不知道它的执行状态的,资源是否被创建,服务是否更新成功且为健康状态,你只能通过接下来的测试步骤去确认。

所以,CD 这一部分是有提升空间的。这时候,就该 Argo CD 入场了,以上这些痛点,它都有自己的解决方案,让持续交付到 Kubernetes 集群更有效率。Argo CD 就是基于 GitOps 的原则为 Kubernetes 而诞生的。

Argo CD 是如何工作的?

那么 Argo CD 是如何提高 CD 效率的呢?我们换位思考一下,把 kubectl apply 到集群这个步骤反转过来,不再从外面去访问 Kubernetes 集群。以前是在集群外面通过 push 的方式去更新资源,现在是集群中有一个 Argo CD agent它作为集群的一部分使用拉取(pull)的方式,从 git repo 上面拉取 yaml 文件,然后更新资源
Argo CD - 图4
现在来看看用 Argo CD 替代 Jenkins 后,CD 流水线应该是怎样的。概括起来,有下面这几个步骤。

  1. 部署 Argo CD 到 Kubernetes 集群
  2. 配置 Argo CD 以监控 Git repository 的更新
  3. 如果 Argo CD 监控到有更新,自动拉取这些更新,然后更新到 Kubernetes 集群

这里有个关于 Git repository 的最佳实践
Argo CD - 图5
为什么要把业务代码和 Kubernetes yaml file 单独放在不同的 git 仓库呢?其中一个主要的原因是,配置代码不仅仅有 k8s deployment yaml 文件,还有 ConfigMap,Secret,Service,Ingress 等等其它 Kubernetes 资源,当我们只需要更新这些 yaml 文件时,可以独立于业务代码,不会触发 CI pipeline,因为业务代码本身并没有任何更新。也不需要,在 CI pipeline 中写一些复杂的逻辑去检查有哪些更新。这个配置代码库也被称之为 GitOps Repository
现在整个 CICD 流水线是下面这样子的。
Argo CD - 图6
Argo CD 支持 Kubernetes YAML 文件,Helm Charts,Kustomize(kustomize.io) ,还有其它最终会生成为 YAML 格式的模版文件。
我们最终拥有了单独的CI 流水线和 CD 流水线。一般情况下,CI 流水线由开发者或者 DevOps 负责,CD 流水线由 Ops 或者 DevOps 负责(使用 Argo CD)。这样的好处是,不仅有自动化的 CICD 流水线,还能达到关注点分离的目的,不同的团队负责流水线的不同部分。

Argo CD 优势

配置即代码(CasC)

这是其最大的优势(DevOps 最佳实践)。整个 k8s 集群通过代码被定义,用 git 做版本控制,避免团队成员手动在本地 apply,例如在本地命令行执行 kubectl apply 或者 helm install。采用这种实践之后,团队只能通过这唯一入口更新 Kubernetes 集群,即 git commit 到 GitOps Repository,Kubernetes 集群中的 Argo CD agent 检测到有更新,立即执行更新动作。
但总会有一些例外。有些人觉得,每次我要在集群里更新点东西,都得按照这个步骤 commit -> push -> MR/PR -> code review -> merged,好繁琐,还要花费很多时间,不如直接在本地一敲 kubectl apply,哦了,打完收工。
那么,如果有人用这种方式手动更新了集群会怎么样呢?
Argo CD 不仅仅监测配置库(git repo)的变化,同时也监测 Kubernetes 集群中的任何变化。也就是,配置库中定义的期望状态与集群中的实际状态进行比较,如果发现不匹配,那么它将会把配置库的期望状态同步到集群,最终以配置库中定义的期望状态为准。
举例说明,有人将 replicas 原本为 2 的 deployment 手动在本地通过 kubectl apply 的方式更新为 replicas: 1,Argo CD 很快会发现集群状态偏离了期望状态,然后马上同步为期望状态,覆盖手动更改。
Git as Single Source of Truth.
该实践确保了配置库和其定义的任何内容在任何时候都是集群状态的单一事实来源,并且还提供了集群的完全透明性,因为你知道在该配置库中定义的配置代码就是集群状态。当然,团队需要时间来适应这个工作流实践。有时候,工程师在更新配置代码之前,确实需要更快的方式去更新集群。这种情况下,ArgoCD 是可以被配置为不自动覆盖和撤销这些手动变更,而是发出警报通知团队成员集群中有手动变更,需要提交配置代码。
总结,git 作为 Kubernetes 集群更新的唯一入口,以版本控制的方式记录了每个更改,便于审计。这也为团队提供了一种更优的协作方式(C&C - Communication and Collaboration),例如,提交 MR 或者 PR (分支合并请求,简称合并请求),大家可以在这个合并请求中讨论,当请求 reviewed and approved,则自动合并到主分支。

易回滚

使用 git 作为配置库的另一个优势就是易于回滚。如果新的 git commit 导致集群出现了问题,我们可以通过 git revert 非常快捷方便地将集群回滚到上一个可工作的版本。尤其是大规模集群(成百上千)都是同步的同一个 git repo,这效率是非常之高的,因为你不用手动按照文档敲 kubectl delete 或者 helm uninstall。

大规模集群灾难恢复(DR)

假设某一天,Kubernetes 集群崩溃了,我们可以快速新建一个新的集群,将其同步到同一个 git repo,它将重新创建与之前状态完全相同的集群,而无需任何干预,因为我们通过声明式代码描述了整个集群。

以上这些实际上是 GitOps 原则和使用 GitOps 工具去实现这些原则所获得的好处,这些不是 Argo CD 自身的优势,但是它帮助实现了 GitOps 原则。

Kubernetes 访问控制

当然,你并不想所有团队成员都有权限对 Kubernetes 集群做更改,尤其是生产环境。使用 GitHub 或者 GitLab 就能很轻松的配置权限访问规则。团队成员可以提交分支合并请求,只有少数资深工程师可以批准和合并这些请求,这提供了一种通过 git 间接管理集群权限的简洁方式,无需为每个团队成员创建不同访问权限的集群角色和用户。由于 ArgoCD 采用的是 pull 方式,只需要给每个团队成员 git repo 的对应权限,而不是直接给集群的访问权限。
除了团队成员(human user),还为 Jenkins 这样的 CICD 工具(non-human user,也称为 service account)提供更简单的集群访问管理,所以在这种情况下,你不需要提供集群外部访问权限给 Jenkins 或者其它工具,因为有 Argo CD agent 运行在集群中,且只有它才能对集群做变更。同时,不会有集群 credentials 暴露给外部的安全风险,这使得管理所有 Kubernetes 集群的安全性变得更容易。

Kubernetes 扩展

Argo CD 实际上是 Kubernetes api 的扩展,它利用了 Kubernetes 已有的一些功能,例如使用 etcd 来存储数据,使用 controllers 来监控和比较期望状态和实际状态。这样做的最大优势是集群可见性(Visibility),Argo CD 为我们提供了应用状态的实时更新(UI console),它能够监控应用部署后的状态和集群配置更新后的状态(Healthy or Failing)。


总结,git 是集群在任何时候的期望状态(desired state),Kubernetes 集群是实际状态(actual state),Argo CD 是中间代理(agent),它确保这两个状态始终一致(in sync),一旦它们出现偏离,就将实际状态更新为期望状态。
Argo CD - 图7
这一节都是在说 Argo CD 的优势,你也可以想一想,Argo CD 有没有什么缺点呢?如果你实在没有一点头绪,可以看一看这两篇文章
参考:

配置 Argo CD

Argo CD 是 CNCF(云原生计算基金会)的孵化项目,可以使用自定义资源对象(CRD)扩展 Kubernetes api,允许使用 Kubernetes 原生 YAML 文件来配置 Argo CD,其主要资源对象是 Application
Argo CD - 图8
需要注意的是定义的源 git repo 与目标 Kubernetes 集群同步的配置信息。该集群可以是运行 Argo CD 的Kubernetes 集群,也可以是 Argo CD 管理的外部集群。
为 Kubernetes 集群的不同的微服务配置多个这样的 Application 时,可以使用另外一个资源对象 AppProject,对微服务进行逻辑分组和设置限制(restrictions)。

Argo CD 与 Kubernetes 多集群

如何把前面的工作流应用到 Kubernetes 多集群呢?
假如 Development 环境有三个集群副本,分别在不同的地区(AWS region),Argo CD 运行在其中一个集群中,它被配置为将任何更改同时部署到所有三个集群副本中,我们只需要配置和管理一个 Argo CD 实例。
Argo CD - 图9
如果有三个环境分别是 Development、Staging、Production,每个环境有多个集群副本,那么我们可以在每个环境中都运行一个 Argo CD agent,但仍然只有一个定义集群配置的 Git repo。

Argo CD - 图10

在实际工作中,我们不会一次将相同的配置应用到所有这三个环境,而是先在 development 环境测试通过后,再应用到 staging 环境测试,所以每个环境有自己的配置。那如何管理这些配置 YAML 文件呢?这里介绍两种方法:

  1. 每个环境拥有自己的 git 分支,这是最常用的方法,但增加了分支维护的困难,不推荐使用。
  2. 另外一个更好的方法是用 Kustomize overlays。Kustomize 中有基准(bases)和覆盖(overlays)这两个概念。base 是包含 kustomization.yaml 文件的一个目录,其中包含一组资源及其相关的定制。base 可以是本地目录或者来自远程仓库的目录,只要其中存在 kustomization.yaml 文件即可。overlay 也是一个目录,其中包含将其他 kustomization 目录当做 bases 来引用的 kustomization.yaml 文件。base 是不知道 overlay 的存在的,且可被多个 overlays 所使用。overlay 则可以有多个 bases,且可针对所有 bases 中的资源执行组织操作,还可以在其上执行定制。

    Argo CD - 图11
    例如,development CI pipeline 更新 development overlay,每个环境都有对应的 overlay。

    会取代其他 CICD 工具吗?

    我们现在已经了解了 GitOps 和 Argo CD 的很多优势,那么这意味着 Argo CD 会取代像 Jenkins 和 GitLab CI 这样的 CICD 工具吗?答案是
    Argo CD - 图12
    我们仍然需要 CI pipeline。
    Argo CD - 图13
    从名字上来看,Argo CD 只负责 CD pipeline,并且专门针对 Kubernetes,注意这里的 CD 是指 Continuous Delivery。所以如果你的应用没有运行在 Kubnernetes 中,那么你就需要其他的 CD 工具。
    Argo CD 不是针对 Kubernetes 唯一的 GitOps CD 工具,还有其它可替代的 CD 工具,随着趋势变化,可能会有更多类似的 CD 工具被创建出来并且会变得更加流行。现在其他较流行的还有 Flux CD 和 JenkinsX,它们和 Argo CD 类似都实现了 GitOPs 原则。