原文链接:https://www.gitops.tech/

什么是GitOps

GitOps是云原生应用持续发布的实现方式。它以开发者体验为中心,开发者使用自己熟悉的工具(包括git)和持续发布工具来操作基础设施。 GitOps的核心思想包含以下方面:

  1. git 仓库必须包含对基础设置在生成环境中期望状态的声明式描述
  2. 使生产环境匹配期望状态的一个自动化进程

如果你想部署一个新的应用,或更新已存在的应用,你需要更新仓库,然后自动化进程会帮你处理一切。

我为什么需要使用GitOps

部署更加快速和频繁

一般任何持续发布技术都能实现快速频繁的部署,但GitOps的特点是你不需要切换工具,一切变化都发生在版本控制系统中。

轻易快速的错误回滚

如果生产环境宕机,由于版本库存放了完整的变更历史,所以使用git revert可以轻松回滚。

凭证管理更加容易

GitOps允许你从环境内部管理发布,你的环境仅需要访问代码仓库和镜像仓库。不需要开发者直接访问你的环境。

Self-documenting Deployments

你或许曾经远程到主机查看上面允许这什么?使用GitOps,任何变化都必须通过版本库。你可以检出master分支,查看完整的系统改变历史。你可以轻松的审计系统的每个变化。

组内知识分享

使用Git存储基础设施部署的完整描述,组内成员可以查看系统的演变过程。如果提交信息描述足够,每个成员都能复现基础设施的变化过程。每个人都能根据示例搭建一个新的系统。

GitOps如何工作

环境配置加入git版本库

GitOps以代码仓库为中心单元组织部署过将至少需要两个仓库:应用仓库和环境配置仓库。代码仓库包含应用的源代码和应用部署的清单文件。环境配置仓库包含了所有的用于描述当前期望基础部署状态的 清单文件。它描述了某个配置及配置的版本应该被哪个应用以及基础设施服务(message broker, service mesh, monitoring tool, …)来使用一起运行。

Push-based vs. Pull-based Deployments

对于部署策略,GitOps实现了两种方式:基于push的部署和基于pull的部署。这两种部署类型的不同在于,如果保证部署环境与期望的基础设施一致。如果可以推荐使用pull-based的实现方式,因为其更安全。

基于push的部署方式

基于push的部署方式的实现,是使用当今比较流行的CI/CD工具,如 Jenkins, CircleCI, or Travis CI. 源代码和用于部署app的kubernetes yaml文件都在同一个代码库中。任何时候,应用代码更新后,就会 触发build pipeline,这个流水线会构建镜像,最终使用新的部署描述更新环境配置仓库。

Tips:你也可以在应用代码库中存储yaml模板,当有新的版本构建的时候,yaml模板文件可用来生成环境配置仓库中的yaml文件。

环境配置仓库的改变,会触发部署流水线。这个流水线负责将环境配置仓库中的所有清单文件部署到基础设施中。这种方式不可避免的需要给部署环境提供凭证,因此这个pipeline需要有无敌模式。但有些情况下 基于push的部署方式是不可避免的,如需要自动扩容云基础设施的时候。这种情况下强烈建议使用云提供商的权限细分系统来限制部署的权限。

使用这种方式需要牢记的另一点是:部署流水线只有在环境配置仓库有变化的时候触发。因为他不能自动识别环境的变化,这意味着需要一种监控机制,当环境与环境配置仓库不一致的时候,有人可以干扰环境。

这个链接给出了使用Google云搭建基于push的部署实现。

基于pull的部署

基于pull的策略与基于push的策略概念类似,只是在部署流水线如何工作的方面不同。传统的CI/CD流水线式由外部事件触发,比如将代码push到代码库。当使用基于pull的部署方式时,会引入operator的 概念,它接管了pipeline的角色,持续的将环境配置仓库的状态与实际基础设施的状态进行比较。当比较出变化后,operator将更新基础设施状态来达到与环境仓库一致。并且可以同时监控镜像仓库,来发现 可用于部署的新版本。

如同基于push的部署,任何环境仓库的变化都会更新环境。然而使用operator可以监控另一个方向的变化。即任何时候如果基础设施的状态与环境仓库期望的状态不一致,则基础设施的这种变化都会被回滚。 这就保证了所有的变化都会在git log中可追溯。这样就避免了直接对集群的修改。

这种在方向上的改变,解决了基于push部署的问题。但这并不意味着你不需要监控而完全放开手脚干。大多数operator都支持无论何种原因导致的环境不能达到期望的状态进行的邮件发送或Slack通知,如 不能拉取镜像。并且应该监控operator本省,如果没有它,也就没有了自动部署。

operator应该总是至于应用部署的同一环境或集群。这就避免在push部署方式中的无敌模式,无敌模式中用于部署的凭证是在CI/CD的pipeline中显示的。当部署示例处于同一环境时,外部服务是不需要 知道凭证的。所以可以使用部署平台的认证机制来限制部署活动的权限。因为这会影响到安全。当使用kubernetes集群的时候,可是配置RBAC和service account来使用。

Want to see how to set it up? Check out our Tutorial about setting up Pull-based GitOps on Google’s GKE with WeaveWorks Flux

### 多应用和很多环境的情况

实际中的大多数应用并不是简单的一个应用仓里,一个环境。当使用微服务架构的时候,一般是每个服务有自己独立的代码仓库。GitOps也可以处理这种情况,你可以设置多个构建流水线,然后更新每个 环境配置仓库。

通过在环境配置仓库中设置独立的分支,GitOps就可以管理多种环境。你可以设置operator或者部署流水线来应对多个分支的变化,一个部署到生成环境,一个部署到测试环境。

## FAQ

### 我的项目适合GitOps吗

大多数情况下都可以。GitOps最酷的事情之一就是你不需要写不同的代码,你要做的是基础设施可以通过declarative Infrastructure as Code 工具进行管理即可。

### 我没有使用kubernetes,还能使用GitOps吗

当然可以。GitOps并不局限于kubernetes,原则上任何可以使用声明式描述或观测的基础设施,且具有Infrastructure as Code工具的基础设施均可。不过目前大多数基于pull模式的GitOps的operator实现 都是基于kubernetes的。

### GitOps只是infra as code的新名词吗

不是的,声明式基础设施即代码在GitOps确实起巨大作用,但不仅仅是这些。GitOps围绕git的整个生态和工具链,并将其用于基础设施。持续发布系统保证了生产环境中当前期望的基础设施状态。 除了这些,还得益于代码审查,pull request,注释等关于基础设施变化的便利。

### 如何不通过git存储的方式将敏感信息注入环境

首先用于不要讲明文密码存储于git中。 可以参考用于kubernetes的工具,项目地址https://github.com/bitnami-labs/sealed-secrets

### GitOps如何处理DEV环境到PROD环境的扩展

GitOps不提供将变更从一个环境扩展到另一个环境的解决方案。推荐使用一个环境,避免一起多个环境一起扩展。如果每个阶段如DEV,QA, PROD一个环境的话,你需要处理GitOps的边界,比如使用CI/CD流水线。

### 我们已经在使用Devops,与GitOps的不同是什么

Devops是使人们更好协同工作的文化。而GitOps是实现continues delivery的技术。然而两者的共同原则是自动化,自服务基础设施。单纯的比较两者的真正区别没什么意义。正是由于这些共同的原则,如果你 现在正采用devops,当采用GitOps工作流的时候会显得更加容易。

### GitOps本质上市NoOps吗

你可以使用GitOps实现NoOps。但并不会绝对使所有东西都自动化。如果你使用云资源,GitOps可以自动化,但是一般情况下,还是需要ops的。

### 我的团队需要雇佣gitops工程师吗

不需要。没有GitOps工程师这个职位。GitOps只是一种实践。

Tools, Articles, and Talks

Tools

Also check out Weavework’s Awesome-GitOps.

Blog Posts and Social Media

Talks