GitOps


自 2017 年 Weaveworks 推出以来,GitOps 在 Twitter 和 KubeCon 上引起了不小的轰动。 该网站汇总了 GitOps 的精髓,以帮助消除有关该主题的困惑。

gitops

我们写了一本关于 GitOps 的小书。 免费获取 PDF 或 ePub 版本,或支付少量费用获取 Kindle 电子书或平装本

GitOps 是一种实现云原生应用程序持续部署的方法。 它通过使用开发人员已经熟悉的工具(包括 Git 和 持续部署工具),专注于在操作基础设施时提供以开发人员为中心的体验。

GitOps 的核心思想是拥有一个 Git 仓库,该仓库始终包含生产环境中当前所需的基础设施的声明性描述,以及使生产环境与仓库中描述的状态相匹配的自动化流程。

如果您想部署新应用程序或更新现有应用程序,您只需更新仓库 —— 自动化流程会处理其他所有事情。 这就像使用巡航控制来管理生产中的应用程序一样。

GitOps: 在声明性基础设施之上的版本化 CI/CD。停止编写脚本并开始交付。
—— Kelsey Hightower

我们认为 GitOps 有几个主要优点,尽管它并不是适用于所有情况的灵丹妙药。 它使您能够更快、更频繁地进行部署,免费为您提供简单快速的错误恢复,并使部署更加安全和自记录。

好吧,公平地说,可能每种持续部署技术都承诺使部署更快,并允许您更频繁地部署。 GitOps 的独特之处在于您无需切换工具来部署应用程序。 无论如何,一切都发生在您用于开发应用程序的版本控制系统中。

当我们说 “高速度” 时,我们的意思是每个产品团队都可以每天多次安全地发布更新 —— 立即部署,实时观察结果,并使用此反馈来向前或向后滚动。
—— Weaveworks

不好了! 你的生产环境宕机了! 借助 GitOps,您可以随时了解环境随时间变化的完整历史记录。 这使得错误恢复就像发出 git revert 一样简单,接下来只需要观察您的环境正在恢复。

Git 记录不仅是审核日志,而且还是事务日志。您可以回滚到任何快照。
—— Alexis Richardson

GitOps 允许您完全从您的环境中管理部署。为此,您的环境只需要访问您的仓库和镜像仓库。 这样一来您不必让开发人员直接访问环境。

kubectl 是新的 ssh,限制访问并仅在没有更好的工具可用时将其用于部署。
—— Kelsey Hightower

您是否曾经通过 SSH 连接到服务器并想知道那里正在运行什么?使用 GitOps,对任何环境的每次更改都必须通过仓库进行。 您始终可以查看主分支并获得部署内容的完整描述以及对系统所做的每个更改的完整历史记录。

您还可以免费获得系统中任何更改的审计跟踪!

使用 Git 存储已部署基础设施的完整描述,使团队中的每个人都可以检查其随时间的演变。 通过大量的提交消息,每个人都可以重现改变基础设施的思维过程,并且还可以轻松找到如何设置新系统的示例。

GitOps 是自配置为代码以来最好的东西。

Git 改变了我们协作的方式,但声明式配置是大规模处理基础设施的关键,并为下一代管理工具奠定了基础。

—— Kelsey Hightower

GitOps 围绕代码仓库作为中心元素来组织部署过程,至少有两个仓库:

  • 应用程序仓库:包含应用程序的源代码和用于部署应用程序的部署清单。
  • 环境配置仓库包:含部署环境的当前所需基础设施的所有部署清单。

它描述了哪些应用程序和基础设施服务(消息代理、服务网格、监控工具等)应在部署环境中以哪种配置和版本运行。

GitOps 的部署策略有两种实现方式:Push-basedPull-based 部署。

两种部署类型之间的区别在于如何确保部署环境实际上类似于所需的基础架构。 如果可能,应首选基于 Pull 的方法,因为它被认为更安全,因此是实施 GitOps 的更好实践。

Push-based 策略

基于 Push 的部署策略由流行的 CI/CD 工具(例如 JenkinsCircleCITravis CI)来实现。

应用程序的源代码以及部署应用程序所需的 Kubernetes YAML 位于应用程序仓库中。 每当更新应用程序代码时,都会触发构建流水线,该流水线会构建容器镜像,最后使用新的部署描述符更新环境配置仓库。

注意:您还可以仅将 YAML 模板存储在应用程序仓库中。 当构建新版本时,可以使用该模板在环境配置仓库中生成YAML。

gitops-push

图 1. Push-based

对环境配置仓库的更改会触发部署流水线。 该流水线负责将环境配置仓库中的所有清单应用到基础设施。 使用这种方法时,必须向部署环境提供凭据,所以流水线已启用上帝模式。

在某些用例中,运行云基础设施的自动配置时,基于推送的部署是不可避免的。 在这种情况下,强烈建议利用云厂商的细粒度可配置授权系统来获得更严格的部署权限。

使用此方法时要记住的另一件重要事情是,仅当环境仓库发生更改时才会触发部署流水线。 它无法自动注意到环境及其所需状态的任何偏差。这意味着,它需要某种适当的监控方式,以便在环境与环境仓库中描述的不匹配时可以进行干预。

提示:想看看如何设置吗? 查看 Google 的教程,了解如何使用其 Cloud Builds 和 GKE 设置基于推送的部署。

Pull-based 策略

基于 Pull 的部署策略使用与基于推的变体相同的概念,但部署流水线的工作方式有所不同。

传统的 CI/CD 流水线由外部事件触发,例如,当新代码被推送到应用程序仓库时。

通过基于 Pull 的部署方法,引入了算子。 它通过不断将环境仓库中的所需状态与已部署基础设施中的实际状态进行比较来接管流水线的角色。 每当发现差异时,操作员就会更新基础设施以匹配环境仓库。 此外,还可以监视镜像仓库以查找要部署的新版本镜像。

gitops-pull

图 2. Pull-based

就像基于 Push 的部署一样,只要环境仓库发生更改,此变体就会更新环境。然而,对于操作员来说,也可以注意到另一个方向的变化。 每当已部署的基础架构以环境仓库中未描述的任何方式发生更改时,这些更改都会被还原。 这使得对集群进行的所有直接更改都不可能,从而保证了所有更改都可以在 Git 日志中追踪。

这种方向的改变解决了基于 Push 部署的问题,即环境仅在环境仓库更新时才触发更新。

然而,这并不意味着您可以完全不需要任何监控。如果由于任何原因无法使环境达到所需状态(例如无法提取容器镜像),大多数运营商都支持发送邮件或 Slack 通知。 此外,您可能应该为操作员本身设置监控,因为没有它就不再有任何自动化部署过程。

操作员应始终位于与要部署的应用程序相同的环境或集群中。 这可以防止出现基于 Push 的方法中出现的上帝模式,其中 CI/CD 流水线知道进行部署的凭据。 当实际部署实例位于同一环境中时,外部服务不需要知道任何凭据。

可以利用部署平台的授权机制来限制执行部署的权限。这在安全性产生方面有着巨大影响。 使用 Kubernetes 时,可以使用 RBAC 配置和服务帐户。

提示:想看看如何设置吗? 查看我们关于使用 WeaveWorks Flux 在 Google GKE 上设置基于 Pull 的 GitOps 的教程

当然,对于大多数应用程序来说,仅使用一个应用程序仓库和一种环境是不现实的。 当您使用微服务架构时,您可能希望将每个服务保留在其自己的仓库中。

GitOps 也可以处理这样的用例。 您始终可以设置多个更新环境仓库的构建流水线。 从那时起,常规的自动化 GitOps 工作流程就会启动并部署应用程序的所有部分。

gitops-multiple

图 3. multiple

只需使用环境仓库中的单独分支即可使用 GitOps 管理多个环境。 您可以设置操作员或部署流水线,通过部署到生产环境来响应一个分支上的更改,并将另一个分支部署到临时环境。

最有可能的回答:是的! GitOps 最酷的地方在于您不需要以不同的方式编写任何代码。 您需要开始的只是可以用声明基础架构作为代码工具来管理的基础架构。

是的!Gitops 不仅限于 Kubernetes。原则上,您可以使用任何可以声明和描述的基础架构,并将基础架构作为可用的代码工具。 但是,目前大多数 pull-based 的 Gitops 运维人员都优先考虑 Kubernetes。

GitOps 只是 Infra as Code 的新名称吗?
—— sholom

不是。

声明式基础设施即代码在实施 GitOps 方面发挥着巨大作用,但不仅如此。 GitOps 采用围绕 Git 的整个生态系统和工具,并将其应用于基础设施。 持续部署系统保证在生产环境中部署基础设施当前所需的状态。 除此之外,您还可以从代码审查、请求和对基础设施更改的注释中获得更多好处。

警告:首先,永远不要在 git 中以纯文本形式存储密钥! 绝不要!

话虽如此,您在环境中创建的密钥永远不会脱离环境。 密钥仍然是未知的,应用程序获得它们所需的密钥,但它们不会暴露给外界。 例如,您在环境中配置一个数据库,并仅向与该数据库交互的应用程序提供密钥。

另一种方法是向环境中添加一次私钥(可能由专门的运维团队的人员),然后您可以将由公钥加密的密钥添加到环境仓库中。 K8s 生态系统中甚至还有对此类 sealed secrets 的工具支持。

GitOps 并不提供将变更从一个阶段传播到下一个阶段的解决方案。我们建议只使用单一的环境,并完全避免阶段传播。 但是如果您需要多个阶段(例如,DEV、 QA、 PROD 等) ,并且每个阶段都需要一个环境,那么您需要处理 GitOps 范围之外的传播,例如通过一些 CI/CD 流水线。

DevOps 就是组织中的文化变革,让人们更好地合作。而 GitOps 是一种实现持续交付的技术。

虽然 DevOps 和 GitOps 共享自动化和自助服务基础设施等原则,但比较它们并没有真正的意义。 然而,当您已经在积极采用 DevOps 技术时,这些共享原则无疑会让您更轻松地采用 GitOps 工作流程。

您可以使用 GitOps 来实现 NoOps,但它的自动化不能代替当前所有的操作。 如果您正在使用云资源,GitOps 可以用来自动化这些资源。

但是,通常情况下基础设施的某些部分(例如您使用的网络配置或 Kubernetes 集群)不是由您自己分散管理,而是由某些运维团队集中管理。 因此,运维永远不会真正消失。

某种程度上,是的。

原则上,您可以使用任何您想要的版本控制系统。GitOps 的核心思想之一是让开发人员使用他们所熟悉的工具来操作您的基础设施。 如果你更喜欢 SVN 而不是 Git,当然可以!

但是,您可能需要花费更多的精力来寻找适合您的工具,甚至编写您自己的工具。所有可用的操作目前只能工作在 Git 仓库下 ーー抱歉!

不用!没有 GitOps 的工程师。GitOps 不是一个角色 (DevOps 也不是)。

GitOps 是一组实践,您可以寻找有实践 GitOps 经验的开发人员 ーー 或者让您的开发人员尝试这些实践。

Tools:

  • ArgoCD:具有 Web 界面的 Kubernetes 的 GitOps 操作员
  • Flux:GitOps 创建者的 GitOps Kubernetes 操作符 — Weaveworks
  • Gitkube:使用 git Push 在 Kubernetes 上构建和部署 docker 镜像的工具
  • JenkinsX:使用内置 GitOps 在 Kubernetes 上进行持续交付
  • TerragruntTerraform 的包装器,用于保持配置干燥并管理远程状态
  • WKSctl:基于GitOps原理的Kubernetes集群配置管理工具
  • Helm Operator:在 K8s 上使用 Helm 的 GitOps 的操作员
  • werf:一个 CLI 工具,用于构建镜像并通过基于推送的方法将其部署到 Kubernetes
  • Gimlet:Gimlet 是一个命令行工具和仪表板,它打包了一组约定和匹配的工作流程,以有效管理 gitops 开发者平台

Blog Posts and Social Media:

Talks: