GitOps 云原生持续交付方式

大家比较熟知DevOps、AiOps概念,也听说过GitOps。但是GitOps究竟是个什么东西,可能不是太了解。所以本篇文章主要介绍GitOps的一些基础知识以及核心思想。

什么是GitOps ?

GitOps是一种进行Kubernetes集群管理和应用交付的方式。它通过将Git用作声明性基础结构和应用程序的单一事实来源来工作。将Git作为交付流水线的核心,每个开发人员都可以提交拉取请求(Pull Request)并使用Gi​​t来加速和简化Kubernetes的应用程序部署和运维任务。通过使用像Git这样的简单工具,开发人员可以更高效地将注意力集中在业务开发而不是运维相关任务上。

GitOps的主要优势

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

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

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

  • 安全的云原生CI/CD pipeline 模型
  • 更快的平均部署时间和平均恢复时间
  • 稳定且可重现的回滚(例如,根据Git恢复/回滚/ fork)
  • 与监控和可视化工具相结合,对已经部署的应用进行全方位的监控

运用GitOps的基本前提

没有单一工具可以完成流水线中所需的所有工作,因此可以为流水线的不同部分选择最佳工具。但是多工具部件组合使用,使得所有部件粘合在一起变成了创建流水线最难的一部分。不管如何选择构造自己的交付流水线,将基于Git(或者其他版本控制工具)的GitOps最佳实践应用在交付流水线中都是一个不二选择,这将使构建持续交付流水线,以及后续的推广变得更加容易,这不仅从技术角度而且从文化角度来看都是如此。同时gitOps也不是银弹,发挥它的最大作用需要一些基本前提。

不可变基础设施

在容器尚未普及的时代,很多公司运维采用各种自动化框架做自己的运维平台来使得相同应用能在测试生产等环境安全稳定运行,但是长期运行后依旧会出现同一集群中的机器的环境不一致的问题,进而引发各种故障和问题的发生。容器技术通过将应用环境与应用打包成镜像使其变成一种不可变单元,进而实现了不可变基础设施。如何高效的使用不可变基础设施资源呢,这时候k8s的诞生解决了该问题。

声明性容器编排

Kubermetes作为一个云原生的工具,可以把它的“声明性”看作是“代码”,声明意味着配置由一组事实而不是一组指令组成,例如,“有十个redis服务器”,而不是“启动十个redis服务器,告诉我它是否有效”。借助Kubermetes的声明性特点,应用系统的整个配置文件集可以在Git库中进行版本控制。通过使用Git库,应用程序更容易部署到Kubernetes中,以及进行版本回滚。更重要的是,当灾难发生时,群集的基础架构可以从Git库中可靠且快速地恢复。

GitOps的基本原则

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

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

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

  • 不应直接使用Kubectl

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

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

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