GitOps | 一种云原生的持续交付模型

你可能已经据说过“GitOps”,但并不知道它究竟是什么,除了GitOps,你可能还据说过DevOps,或者AIOps、GOps等,是的,如今是“Ops”盛行的时代。html

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

GitOps,90%的最佳实践,10%有意思的新东西须要咱们去构建。 —— 《​ GitOps - Operations by Pull Request》来自: www.weave.works

这篇文章是根据Weave Cloud的几篇关于GitOps的文章翻译整理而来:github


主要内容:redis

  • 什么是GitOps?
  • GitOps的主要优势
  • GitOps的应用场景——适合云原生的持续交付
  • GitOps的基本原则
  • 最佳实践
  • 拉式流水线——Pull Request操做
  • GitOps工做流
  • 可视化
  • 应用交付的合规性和安全的CI/CD
  • GitOps带来的价值

什么是GitOps?

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

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

GitOps: versioned CI/CD on top of declarative infrastructure. Stop scripting and start shipping. t.co/SgUlHgNrnY — Kelsey Hightower (@kelseyhightower) January 17, 2018

GitOps的主要优势

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

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

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

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

GitOps应用场景——知足云原生环境下的持续交付

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

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

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

不可变基础设施

应用都须要运行在多台机器上,它们被组织成不一样的环境,例如开发环境、测试环境和生产环境等等。须要将相同的应用部署到不一样的机器上。一般须要系统管理员确保全部的机器都处于相同的状态。接着全部的修改、补丁、升级须要在全部的机器中进行。随着时间的推移,很难再确保全部的机器处于相同的状态,同时愈来愈容易出错。这就是传统的可变架构中常常出现的问题。这时咱们有了不可变架构,它将整个机器环境打包成一个单一的不可变单元,而不是传统方式仅仅打包应用。这个单元包含了以前所说的整个环境栈和应用全部的修改、补丁和升级,这就解决了前面的问题。 —— 摘自InfoQ的《关于不可变架构以及为何须要不可变架构》做者 百占辉

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

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

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 模式(什么是Operator 模式?),集群的状态和Git库中的配置文件等要保持一致,而且查看分析它们之间的状态差别。

最佳实践

以Git做为事实的惟一真实来源

Git是每一个开发人员工具包的一部分。学习起来感受天然并且不那么使人生畏,并且工具自己也很是简单。 经过使用Git做为应用系统的事实来源,几乎能够操做全部东西。例如,版本控制,历史记录,评审和回滚都是经过Git进行的,而无需使用像kubectl这样的工具。

因此,Git是GitOps造成的最基础的内容,就像第一条原则“任何可以被描述的内容都必须存储在Git库中 ”描述的那样:经过使用Git做为存储声明性基础架构和应用程序代码的存储仓库,能够方便地监控集群,以及检查比较实际环境的状态与代码库上的状态是否一致。因此,咱们的目标是描述系统相关的全部内容:策略,代码,配置,甚至监控事件和版本控制等,而且将这些内容所有存储在版本库中,在经过版本库中的内容构建系统的基础架构或者应用程序的时候,若是没有成功,则能够迅速的回滚,而且从新来过。

拉式流水线——Pull Request操做

推送流水线

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

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

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



  • CI运行测试,输出传递到容器映像存储库。
  • CD系统自动部署容器(或根据请求,即手动)。


拉式流水线

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



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

GitOps的流水线

在上节中介绍了GitOps采用拉式模式构建交付流水线,本节将详细地介绍在构建GitOps流水时须要注意哪些事情,有哪些最佳实践。

GitOps流水线



这是一个新图,显示部署上游的全部内容都围绕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库中配置文件集最新的状态与线上环境最新的状态保持一致。





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

固然,您能够根据具体的设计,赋予各类其余的功能,可是自动同步是必定须要的,确保若是对存储库进行任何更改,这些更改将自动部署到线上环境中

仅部署容器和配置

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

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

GitOps的可观察性

“可观察性就像生产中的驱动测试同样。若是你不知道如何肯定它是否正常工做,请勿接受 pull request。@mipsytipsy “ - Adriano Bastos复制代码

在GitOps中,使用Git库来存储应用系统的配置文集和应用程序,它确保开发人员将全部对于应用系统的配置和程序的新增、修改等都经过Git库进行版本控制,使Git成为配置和程序的惟一真实来源。而GitOps的可观察性则是确保线上环境的真实状态与Git库中的保持一致性。本章节将给你们介绍GitOps的可观察性。

可观察性是另外一个真理来源

在GitOps中,咱们使用Git做为系统所需状态的真实来源。例如,若是应用系统宕机,GitOps能够回滚到以前正确状态。而可观察性是系统实际运行状态的真实来源,系统开发人员或者运维人员能够监控系统的状态。这是一张显示流程的图片。




经过观察需寻找问题的答案

若是你们使用Kubernetes做为云原生环境和容器编排工具,相信你们会有这样的感触,虽然Kubernetes是一个很是棒的编排容器平台,可是随之而来的缺少友好的可视化管理界面给开发人员或者运维人员带来诸多不便。例如:

  • 个人部署成功了吗?个人系统如今处于工做的状态,我如今能够回家吗?
  • 个人系统与之前有什么不一样?我可使用Git或咱们的系统历史记录来检查吗?
  • 个人改变是否改善了总体用户体验?(与系统正确性相对)
  • 我在信息中心找不到个人新服务(例如RED指标)
  • 这个故障是否与我上次的服务更新事件有关,仍是和其余操做有关系?


你们可能会想到经过监控服务器的CPU、内存、网络等,以及应用的日志,甚至微服务的调用链等来解决问题。是的,这个没有错,可以获得一些反馈信息,可是使用过相似监控的开发人员或者运维人员也会感受,这些监控仪表盘给咱们大量冗繁的信息,须要认真地甄别,并且有不少信息在这些仪表盘中是得到不到的。这意味着须要建立新的仪表盘,用于监控新的指标和内容。

GitOps的可观察性

可观察性可被视为Kubernetes 持续交付周期的主要驱动因素之一,由于它描述了在任何给定时间系统的实际运行状态。观察运行系统以便理解和控制它。新功能和修复程序被推送到git并触发部署管道,当准备好发布时,能够实时查看正在运行的集群。此时,开发人员能够根据此反馈返回到管道的开头,或者将映像部署并释放到生产集群。

在这里GitOps引入一个新的工具:Diffs,用来监控对比系统状态。即:

  • 验证当前线上系统的状态是否和Git库中描述的状态一致,例如,我上一次发布是否符合指望?
  • 提醒开发人员不一致状态,以及相应的明细信息。

在文章前面讲过,在Git库中存储的其实是“声明性基础设施”,例如Kubernetes的YAML文件,用以构建应用系统所需的各类组件、域名、网络等配置信息。Diffs须要读取Git库中配置信息,同时,经过API等读取集群的相应信息,并进行比对。

例如,Kubernetes集群:所需的Kubernetes状态多是“有4个redis服务器”。Diffs按期检查群集,并在数量从4变化时发出警报。通常而言,Diffs将YAML文件转换为运行状态查询。

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等比较工具还能够将集群状态的可信定义与实际运行的集群进行比较,从而确保跟踪和可审计的更改与实际状况相符。

关于Choerodon猪齿鱼

Choerodon猪齿鱼是一个开源企业服务平台,是基于Kubernetes的容器编排和管理能力,整合DevOps工具链、微服务和移动应用框架,来帮助企业实现敏捷化的应用交付和自动化的运营管理的开源平台,同时提供IoT、支付、数据、智能洞察、企业应用市场等业务组件,致力帮助企业聚焦于业务,加速数字化转型。

相关文章
相关标签/搜索