GitOps 简介
在本系列文章中,我们将解释一些 GitOps 理论,然后深入使用 Terraform、Azure 和 GitHub 进行动手实践。我们将首先看一下 GitOps——它的起源、它实际上是什么,以及它与术语基础设施即代码 (IaC) 以及持续集成 (CI) 和持续部署 (CD) 的管道概念之间的关系。
在本文中,我们将探讨软件工程实践的历史以及它们如何导致 GitOps 的发展。
曾经,有瀑布
很长一段时间以来,软件都是使用瀑布方法开发的——这种方法将整个软件开发生命周期作为一个单一的大型工作完成。在这个模型中,客户第一次使用该软件是在发布日。由于周期如此之长,开发团队需要很长时间才能获得反馈并有机会发布新版本。
这对于当时可用的软件分发方法来说效果很好——更短的周期是不切实际的。这种工作方式为运营团队提供了充足的时间来为发布日配置基础设施。
然后是敏捷
可以说,在软件开发中采用敏捷方法的主要好处是进行较小的更改并更频繁地发布的想法——这得益于新的分发方法变得广泛可用——远离实体媒体。
这种方法绝对能够更快地发布代码,但运营团队正在使用的工具和实践无法始终支持不断增加的更改频率。
DevOps 成为一件事
这是 DevOps 发展的原因之一——推动一种开发人员和运营团队更紧密合作的文化。通过合作,他们能够自动化构建、测试和部署,以支持敏捷提高的发布节奏。
然而,随着系统由大量微服务构建而成,应用程序的规模和复杂性已经增长——对这些系统的需求也在增长。因此,基础架构解决方案需要能够根据负载动态扩展和减少基础架构资源。这就是云做得很好的地方。
开发人员从与运营部门的密切合作中受益匪浅,但由此产生的所有云服务都需要管理很多。而且,使用旧方法,很容易忘记我们拥有哪些基础设施,我们需要哪些基础设施,以及两者是否匹配。
然后,出现了 GitOps
事后看来,这似乎很明显。为了让运营活动跟上开发人员的节奏,他们应该采用与应用程序开发相同的 DevOps 最佳实践,并将其应用于自动化基础设施配置。
这种方法的核心是 Git 源代码控制,用作当前部署的基础设施的单一事实来源。在此基础上,我们拥有三个核心组件:IaC(基础架构即代码)、拉取请求和 CI/CD。
基础设施即代码
GitOps 的显着变化是 Git 的使用。Git 是一个版本控制系统,可以跟踪代码随时间的变化。要使用 Git,我们现在需要以代码形式表示我们的基础设施。这是 GitOps 的关键组件之一,称为基础设施即代码 (IaC),我们使用代码来描述我们的基础设施的所需状态。
拉取请求作为变更门
运营团队使用 Git 工作流在共享的事实来源上协作工作。拉取请求是 Git 工作流程的关键部分。这是一种方法,让从事存储库克隆工作的人请求将他们在克隆中所做的更改拉入主存储库。
打开拉取请求时,需要进行代码审查是正常的。这是其他团队成员检查新代码、编写建议更改的评论并授予他们批准的机会(存储库将被设置为阻止任何未经批准的传入代码,就像对我们基础设施的所有更改的“门”)。
由于 Git 会保留所有更改的历史记录,因此它也可以作为一个清晰的审核日志。
持续集成和部署
持续集成 (CI) 是从 DevOps 借鉴的另一个最佳实践。它指的是自动化我们如何将代码更改与存储库集成。它可以帮助多个贡献者将更改合并到一个共享的中央存储库中,以通过破坏事物的更改来降低不利影响的风险。这是通过在添加新代码时自动运行以执行测试的工具来实现的,通常是在拉取请求中。在上图所示的流程中,我们可以看到我们的基础设施更新只有在满足两个条件后才会从拉取请求中合并:
- 团队批准的代码审查
- 自动检查(或测试)全部通过
持续部署 (CD) 是指将所有拉入存储库的新更改自动部署到生产环境(如果它们通过拉取请求检查)的设置。这是一个理想的目标,它要求您的所有流程,尤其是您的测试,都必须非常出色。一些团队也选择通过手动批准来控制生产环境。无论您的 CD 处于何种成熟度级别,一个共同的主题是用于自动化所有基础设施供应步骤的“管道”(或工具)。
CD 也可以指持续交付,其中存储库始终保持可发布状态——即使您没有部署每个更改。虽然您的发布节奏是应用程序开发中的偏好问题,但较短的发布周期和较小的更改可以降低风险。最纯粹的人可能会争辩说,对于 GitOps,这是不可协商的,因为存储库应该反映当前的生产状态。但是我们可以争辩说,如果从部署管道到存储库的审计跟踪到位,那么我们的存储库是在任何时间点反映当前状态还是未来所需状态总是很清楚的。
关于推送与拉取部署的快速说明
GitOps 部署可以是推式或拉式的。它们在将环境保持在所需状态的方式上有所不同。拉式是首选,因为它更安全并且为持续交付提供更好的支持,但基于推式更容易上手,并且 Terrform 专为基于推式的部署而设计。
来自应用程序开发的人会更熟悉基于推送的方式。当应用程序代码在存储库中更新时,会触发构建管道,最终将更改推送到生产环境。它不会自动注意到直接对环境进行的任何更改。
基于拉的部署不会由代码更改触发。我们需要一个“操作员”服务,它不断地将存储库代码中的所需状态与部署的基础设施中的实际当前状态进行比较。如果它发现更改,它会拉入更改,更新基础架构以匹配存储库。