GitOps——一种实现云原生的持续交付模型

GitOps——一种实现云原生的持续交付模型_第1张图片
作者 | 甘闪闪
编辑 | 张婵
你可能已经听说过“GitOps”,但并不知道它到底是什么,除了 GitOps,你可能还听说过 DevOps,或者 AIOps、GOps 等,是的,现在是“Ops”盛行的时代。

GitOps 是一种实现持续交付的模型,它的核心思想是将应用系统的声明性基础架构和应用程序存放在 Git 的版本控制库中。俗话说“兵马未动,理论先行”,在本文中,将重点阐述 GitOps 工作流程的原理和模式,以及将它们应用在生产和大规模运行 Kubernetes 中的一些实践经验。

什么是 GitOps?

GitOps 是一种持续交付的方式。它的核心思想是将应用系统的声明性基础架构和应用程序存放在 Git 版本库中

将 Git 作为交付流水线的核心,每个开发人员都可以提交拉取请求(Pull Request)并使用 Git 来加速和简化 Kubernetes 的应用程序部署和运维任务。通过使用像 Git 这样的简单工具,开发人员可以更高效地将注意力集中在创建新功能而不是运维相关任务上(例如,应用系统安装、配置、迁移等)。

GitOps 的主要优点

通过 GitOps,当使用 Git 提交基础架构代码更改时,自动化的交付流水线会将这些更改应用到应用程序的实际基础架构上。但是 GitOps 的想法远不止于此——它还会使用工具将整个应用程序的实际生产状态与基础架构源代码进行比较,然后它会告诉集群哪些基础架构源代码与实际环境不匹配

通过应用 GitOps 最佳实践,应用系统的基础架构和应用程序代码都有“真实来源”——其实是将基础架构和应用程序代码都存放在 gitlab、或者 github 等版本控制系统上。这使开发团队可以提高开发和部署速度并提高应用系统可靠性。

将 GitOps 理论方法应用在持续交付流水线上,有诸多优势和特点:

  • 安全的云原生 CI/CD 管道模型

  • 更快的平均部署时间和平均恢复时间

  • 稳定且可重现的回滚(例如,根据 Git 恢复 / 回滚 / fork)

  • 与监控和可视化工具相结合,对已经部署的应用进行全方位的监控

GitOps 应用场景

作为 CI / CD 流水线的方案,GitOps 被描述为软件开发过程的“圣杯”。 由于没有单一工具可以完成流水线中所需的所有工作,因此可以自由地为流水线的不同部分选择最佳工具。可以从开源生态系统中选择一组工具,也可以从封闭源中选择一组工具,或者根据使用情况,甚至可以将它们组合在一起,其实,创建流水线最困难的部分是将所有部件粘合在一起

不管如何选择构造自己的交付流水线,将基于 Git(或者其他版本控制工具)的 GitOps 最佳实践应用在交付流水线中都是一个不二选择,这将使构建持续交付流水线,以及后续的推广变得更加容易,这不仅从技术角度而且从文化角度来看都是如此。

当然,GitOps 也不是万能的,它也有相应的应用场景。

不可变基础设施

“不可变基础设施”这一概念不是刚刚冒出来的,它也不是必须需要容器技术。然而,通过容器,它变得更易于理解,更加实用,并引起了业内广泛注意。“不可变基础设施”让我们以全新的方式理解和面对应用系统,尤其是使以微服务为代表的分布式系统在部署、运营等方面变得不那么复杂,而有很好的可控性。

那么,如何比较方便地在实际的生产过程中应用“不可变基础设施”,这给业界也提出了另外一个问题。

GitOps 是在具体 Kubernetes 的应用实践中出现的,GitOps 需要依托于“不可变基础架构”才能发挥其作用。在一定程度上说,“不可变基础架构”为 GitOps 的出现创造了必要的条件,反过来 GitOps 应用 Kubernetes 的容器编排能力,能够迅速的使用镜像搭建出应用系统所需的组件。

声明性容器编排

Kubermetes 作为一个云原生的工具,可以把它的“声明性”看作是“代码”,声明意味着配置由一组事实而不是一组指令组成,例如,“有十个 redis 服务器”,而不是“启动十个 redis 服务器,告诉我它是否有效”。

借助 Kubermetes 的声明性特点,应用系统的整个配置文件集可以在 Git 库中进行版本控制。通过使用 Git 库,应用程序更容易部署到 Kubernetes 中,以及进行版本回滚。更重要的是,当灾难发生时,群集的基础架构可以从 Git 库中可靠且快速地恢复。

GitOps 充分利用了不可变基础设施和声明性容器编排,通过 GitOps 可以轻松地管理多个部署。为了最大限度地降低部署后的变更风险,无论是有意还是偶然的“配置偏差”,GitOps 构建了一个可重复且可靠的部署过程,在整个应用系统宕机或者损坏情况下,为快速且完全恢复提供了所需条件。

GitOps 的基本原则

以下是在云原生环境中 GitOps 的原则:

  任何能够被描述的内容都必须存储在 Git 库中

通过使用 Git 作为存储声明性基础架构和应用程序代码的存储仓库,可以方便地监控集群,以及检查比较实际环境的状态与代码库上的状态是否一致。所以,我们的目标是描述系统相关的所有内容:策略,代码,配置,甚至监控事件和版本控制等,并且将这些内容全部存储在版本库中,在通过版本库中的内容构建系统的基础架构或者应用程序的时候,如果没有成功,则可以迅速的回滚,并且重新来过

  不应直接使用 Kubectl

作为一般规则,不提倡在命令行中直接使用 kubectl 命令操作执行部署基础架构或应用程序到集群中。还有一些开发者使用 CI 工具驱动应用程序的部署,但如果这样做,可能会给生产环境带来潜在不可预测的风险。

  调用 Kubernetes 的 API 的接口或者控制器应该遵循 Operator 模式

调用 Kubernetes 的 API 的接口或者控制器应该遵循 Operator 模式,集群的状态和 Git 库中的配置文件等要保持一致,并且查看分析它们之间的状态差异。

GitOps 最佳实践
以 Git 作为事实的唯一真实来源

Git 是每个开发人员工具包的一部分。学习起来感觉自然而且不那么令人生畏,而且工具本身也非常简单。 通过使用 Git 作为应用系统的事实来源,几乎可以操作所有东西。例如,版本控制,历史记录,评审和回滚都是通过 Git 进行的,而无需使用像 kubectl 这样的工具。

拉式流水线——Pull Request 操作
  推送流水线

目前大多数 CI / CD 工具都使用基于推送的模型。基于推送的流水线意味着代码从 CI 系统开始,通过一系列构建测试等最终生成镜像,最后手动使用“kubectl”将任何更改推送到 Kubernetes 集群。

很多开发人员不愿意在 CI 中启动 CD 部署流程,或者使用命令行工具操作启动 CD 部署流程的原因可能是这样做会将集群的用户和密码等公布出去。虽然可以有措施保护 CI / CD 脚本和命令行,但是这些操作毕竟还是在集群外部非可信区工作的。所以,类似做法是不可取的,会给系统安全带来潜在的风险。

具有集群外读 / 写(R/W)权限的典型推送流水线:

GitOps——一种实现云原生的持续交付模型_第2张图片

  • CI 运行测试,输出传递到容器映像存储库。

  • CD 系统自动部署容器(或根据请求,即手动)。

  拉式流水线

在 GitOps 中,镜像被拉出并且凭证保留在集群中:

GitOps——一种实现云原生的持续交付模型_第3张图片

Git 库是拉式流水线模式的核心,它存储应用程序和配置文件集。开发人员将更新的代码推送到 Git 代码库 ; CI 工具获取更改并最终构建 Docker 镜像。GitOps 检测到有镜像,从存储库中提取新镜像,然后在 Git 配置仓库中更新其 YAML。然后,GitOps 会检测到群集已过期,并从配置库中提取已更改的清单,并将新镜像部署到群集。

GitOps 的流水线
  GitOps 流水线

GitOps——一种实现云原生的持续交付模型_第4张图片

这是一个新图,显示部署上游的所有内容都围绕 Git 库工作的。在“拉式流水线”中讲过,开发人员将更新的代码推送到 Git 代码库,CI 工具获取更改并最终构建 Docker 镜像。GitOps 的 Config Update 检测到有镜像,从存储库中提取新镜像,然后在 Git 配置仓库中更新其 YAML。然后,GitOps 的 Deploy Operator 会检测到群集已过期,并从配置库中提取已更改的清单,并将新镜像部署到群集。

使用群集内部的 Deploy Operator,群集凭据不会在生产环境之外公开。一旦将 Deploy Operator 安装到集群与 Git 仓库建立连接,线上环境中的任何更改都将通过具有完全回滚的 Git pull 请求以及 Git 提供的方便审计日志完成。

  自动 git→集群同步

由于没有单一工具可以完成流水线中所需的所有工作,可以从开源生态系统中选择一组工具,也可以从封闭源中选择一组工具,或者根据使用情况,甚至可以将它们组合在一起,其实,创建流水线最困难的部分是将所有部件粘合在一起。要实现 GitOps,必须要开发出新的组件,用于粘合这些工具,实现拉式交付流水线

部署和发布自动化是应用落实 GitOps,并使交付流水线工作的基础。GitOps 不仅要保证,当开发人员通过 Git 更新配置文件集的时候,GitOps 流水线要自动根据最新的配置文件状态更新线上环境,而且 GitOps 还要能够实时比对 Git 库中配置文件集最新的状态与线上环境最新的状态保持一致。

GitOps——一种实现云原生的持续交付模型_第5张图片

在上节中提到了两个名词:Config UpdateDeploy Operator,根据 GitOps 的实践,Config Update 和 Deploy Operator 是需要进行设计开发的,它们是实现 GitOps 流水线必须的关键组件。GitOps 赋予了它们神奇的魔法,它们既是自动化容器升级和发布到线上环境的工具,可能也要负责服务、部署、网络策略甚至路由规则等任务。因此,Config Update 和 Deploy Operator 是映射代码,服务和运行集群之间所有关系的“粘合剂”

当然,您可以根据具体的设计,赋予各种其他的功能,但是 自动同步是一定需要的,确保如果对存储库进行任何更改,这些更改将自动部署到线上环境中

  仅部署容器和配置

GitOps 建议不直接将应用程序部署到线上环境中,而是将应用程序和相关配置打包成镜像,并存储到镜像库中,最后,通过镜像的方式生成容器,并部署到线上环境中。

容器为什么如此重要?在 GitOps 模型中,我们使用不可变基础架构模式。一旦代码在 Git 中提交,GitOps 就不希望任何其他内容发生变化,这样可以最大限度地降低系统潜在不确定性、不一致性风险。例如,需要将相同的应用部署到不同的机器上。通常需要系统管理员确保所有的机器都处于相同的状态。接着所有的修改、补丁、升级需要在所有的机器中进行。随着时间的推移,很难再确保所有的机器处于相同的状态,同时越来越容易出错。然而,容器是比较完美地解决了这个问题,当然,使用虚拟机是可以的,显然使用容器更加方便。

应用交付合规性和安全性

由于以安全的方式跟踪和记录更改,因此合规性和审计变得微不足道。使用 Diffs 等比较工具还可以将 Git 库中定义的集群状态与实际运行的集群进行比较,从而确保更改与实际情况相符。

在 Git 中记录所有的操作日志

开发人员或者运维人员通过 Git 操作系统配置和应用程序的新建和更新等,通过 Git 客户端 git commit /git merge 的所有操作都会 Git 库记录下来,审计员可以查看 Git,看看谁做了任何更改,何时以及为何以及如何影响正在运行的系统部署。当然,可以根据自身的需求定制不同的交付合规性。相较于直接进入服务器操作或者通过 Kubctl 操作集群,Git 记录了每一个操作步骤,这些可以为合规性和审计提供完整的操作日志。

角色和权限控制

几乎所有的 Git 库都提供角色和权限控制,与开发和运维无关的人员没有权限操作 Git 库。而不是直接把服务器或者集群的操作权限散发出去,这样特别容易引起安全泄露。

GitOps 带来的好处
更加快速地开发

借助 GitOps 的最佳实践,开发人员可以使用熟悉的 Git 工具,便捷地将应用程序和其对应的配置文件集持续部署到 Kubernetes 等云原生环境,提高业务的敏捷度,快速地相应用户的需求,有助于增加企业市场的竞争力。

更好地进行运维

借助 GitOps,可以实现一个完整的端到端的交付流水线。不仅可以实现拉式的持续集成流水线和持续部署流水线,而且系统的运维操作可以通过 Git 来完成。

更强大的安全保证

几乎所有的 Git 库都提供角色和权限控制,与开发和运维无关的人员没有权限操作 Git 库。而不是直接把服务器或者集群的操作权限散发出去,这样特别容易引起安全泄露。

更容易合规的审计

由于以安全的方式跟踪和记录更改,因此合规性和审计变得微不足道。使用 Diffs 等比较工具还可以将集群状态的可信定义与实际运行的集群进行比较,从而确保跟踪和可审计的更改与实际情况相符。

参考链接:

https://coreos.com/blog/introducing-operators.html

https://www.weave.works/technologies/gitops/


作者简介

甘闪闪,主要从事软件开发和 IT 服务,目前就职于上海汉得信息技术股份有限公司,现在主要是做 Choerodon 猪齿鱼的产品运营工作。在工作中主要使用 Spring Cloud 微服务、容器等技术,熟悉 Agile/DevOps 思想理论、流程和工具链等。


今日推荐

近几年,微服务架构热度虽高,但对于很多中小型公司来说微服务却遥不可及,因为团队规模和能力又反过来制约了他们采用新技术的步伐。《从 0 开始学微服务》专栏希望能够用通俗易懂的语言帮助你理解决中小团队的微服务架构问题,同时也是希望能够由浅入深,系统为你讲解微服务的各个关键环节,帮你上手微服务。

GitOps——一种实现云原生的持续交付模型_第6张图片

你可能感兴趣的:(GitOps——一种实现云原生的持续交付模型)