写点什么

GitOps 自问自答

作者:俞凡
  • 2022 年 5 月 28 日
  • 本文字数:4830 字

    阅读完需:约 16 分钟

GitOps 自提出以来受到很多关注,被认为是云原生最佳实践之一。这篇文章回答了关于 GitOps 的常见问题,帮助感兴趣的相关人员更好理解这一实践。原文: GitOps


自从 Weaveworks 在 2017 年提出 GitOps 以来,已经在 Twitter 和 KubeCon 上引发了不少争议。这篇文章汇集了关于 GitOps 的常见问题,以帮助澄清关于这一主题的困惑。

GitOps 是什么?

GitOps 是为云原生应用实现持续部署的一种方法,通过使用 Git 和 CD 工具等开发人员已经熟悉的工具,从而在操作基础设施时提供以开发人员为中心的体验。


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 是实践配置即代码(configuration as code)的最佳工具。Git 改变了我们的协作方式,但声明式配置是处理大规模基础设施的关键,并为下一代管理工具奠定了基础。

Kelsey Hightower

GitOps 如何工作?

环境配置即 Git 存储库

GitOps 以代码存储库为中心组织部署过程,至少有两个存储库: 应用程序存储库和环境配置存储库。应用程序存储库包含应用程序源代码和用于部署应用程序的部署清单。环境配置存储库包含部署环境当前所需基础设施的所有部署清单,描述了应该在部署环境中运行哪些版本的应用程序和基础服务(消息代理、服务网格、监控工具……)。

基于 Push 的部署 vs. 基于 Pull 的部署

GitOps 的部署策略有两种: 基于 Push 的部署和基于 Pull 的部署。这两种部署类型的区别在于如何确保部署环境实际上符合预期。如果可能的话,应该首选基于 Pull 的方法,因为这样更安全,是实现 GitOps 的更好实践。

基于 Push 的部署

基于 Push 的部署策略是由流行的 CI/CD 工具实现的,如JenkinsCircleCITravis CI。应用程序源代码与部署应用所需的 Kubernetes YAML 一起保存在应用程序存储库中。每当应用程序代码更新时,都会触发流水线,构建容器镜像,最后用新的部署描述符更新环境配置存储库。


提示: 也可以只将 yaml 模板存储在应用程序存储库中。在构建新版本时,可以使用模板在环境配置存储库中生成 YAML。



对环境配置存储库的更改会触发部署流水线,该流水线负责将环境配置存储库中的所有清单(manifests)应用到基础设施上。使用这种方法,向部署环境提供凭证必不可少,这意味着流水线启用了上帝模式(god-mode)。在某些用例中,当运行云基础设施提供的自动化配置时,基于 Push 的部署不可避免。在这种情况下,强烈建议使用云供应商的细粒度可配置授权系统,从而更严格的控制部署权限。


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


想看看怎么设置吗? 查看谷歌的教程,了解如何使用 Cloud Builds 和 GKE 设置基于 Push 的部署。

基于 Pull 的部署

基于 Pull 的部署策略与基于 Push 的部署策略使用相同的概念,但在部署流水线的工作方式上有所不同。传统的 CI/CD 流水线由外部事件触发,例如,当新代码被推送到应用程序存储库时。结合基于 Pull 的部署方式,引入了 operator,它通过不断比较环境存储库中的期望状态与部署的基础设施中的实际状态来接管流水线的角色。一旦发现差异,operator 就更新基础设施以匹配环境存储库。此外,还可以监视镜像仓库,以查找要部署的新版本镜像。



与基于 Push 的部署一样,每当环境存储库发生更改时,就会更新环境。然而,通过 operator,也可以监控另一个方向的变化。每当部署的基础设施以环境存储库中没有描述的方式发生更改时,这些更改将被恢复,从而确保 Git 日志中所有的变更都可跟踪,从而避免对集群进行任何直接更改。


这种方向上的改变解决了基于 Push 的部署问题,即只有在环境存储库更新时才更新环境。然而,这并不意味着可以在没有任何监视的情况下完全做到这一点。如果由于任何原因无法保证环境符合预期的状态(例如无法获取容器镜像),大多数 operator 都支持发送邮件或 Slack 通知。另外,因为没有 operator 就没有任何自动化部署过程,所以应该为 operator 本身设置监控。


operator 应该始终处于与要部署的应用相同的环境或集群中,从而防止基于 Push 的方法所出现的上帝模式(god-mode),即 CI/CD 流水线需要获取执行部署的证书。当部署实例位于完全相同的环境中时,外部服务不需要任何凭证。可以利用部署平台的授权机制来限制执行部署的权限,这对安全有很大影响,当使用 Kubernetes 时,可以利用 RBAC 配置和服务帐户。


想看看怎么设置吗? 查看在谷歌GKE上使用weveworks Flux设置基于Pull的GitOps的教程

在多应用环境中使用

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


GitOps 也可以处理这样的用例,总是可以设置多个构建流水线来更新环境存储库,从而通过常规的自动化 GitOps 工作流启动并部署应用程序的所有部分。



只需在环境存储库中使用独立分支,就可以利用 GitOps 管理多个环境。可以设置 operator 或部署流水线,对某一个分支上的变更部署到生产环境上,对另一个分支上的变更部署到预发环境上。

FAQ

我的项目为 GitOps 做好准备了吗?

大部分情况下,是的!GitOps 最酷的地方在于,不需要编写任何特殊代码,所需要的只是使用声明式基础设施作为代码工具进行管理的基础设施。

不用 Kubernetes,还能使用 GitOps 吗?

是的!GitOps 并不仅限于 Kubernetes。原则上,可以使用任何提供可观察性和声明性描述的基础设施,并拥有可用的基础设施作为代码工具。然而,目前大多数基于 Pull 的 GitOps operator 都是基于 Kubernetes 实现的。

GitOps 只是将基础设施版本化为代码吗?

GitOps 只是基础设施即代码的新名字吗?

sholom


不是。声明性基础设施即代码在实现 GitOps 中扮演着重要角色,但不仅仅是这样。GitOps 采用了 Git 周围的整个生态系统和工具,并将其应用于基础设施。持续部署系统保证在生产环境中基于期望的状态部署基础设施。除此之外,还可以获得代码审查、pull request 和基础设施变更注释等其他好处。

如何在环境中获取密钥但不存储在 git 中?

首先,永远不要在 git 中以明文形式存储密钥!永远不要!


也就是说,你在环境中创建了一些密钥,这些密钥永远不会离开环境,应用程序获取需要的密钥,但不向外界暴露。例如,环境中有数据库,只将密钥提供给与该数据库交互的应用程序。


另一种方法是在环境中添加私钥(可能是由专门的运维团队执行),然后可以在环境存储库中添加由公钥加密的密钥。在 K8S 生态系统中,甚至有工具支持这种加密密钥

GitOps 如何处理研发环境到生产环境的发布?

GitOps 没有提供将更改从一个阶段传播到下一个阶段的解决方案。我们建议只使用一个环境,避免分阶段部署。但是如果需要多个阶段(例如研发、QA、生产等),每个阶段都有一个环境,就需要处理 GitOps 范围之外的发布,也许可以通过 CI/CD 流水线实现。

我们已经在做 DevOps 了,和 GitOps 有什么不同?

DevOps 的核心是改变组织文化,让人们更好的一起工作。GitOps 是一种实现持续交付的技术。虽然 DevOps 和 GitOps 共享自动化和自助服务基础设施等原则,但对它们进行比较并没有意义。然而,如果你已经在积极使用 DevOps 技术,这些共同原则肯定会使你更容易采用 GitOps 工作流程。

那么,GitOps 基本上是 NoOps 吗?

可以使用 GitOps 来实现 NoOps,但它不会自动使所有运维任务过时。如果你正在使用云资源,那么可以使用 GitOps 来实现自动化。但是,通常情况下,使用的某些基础设施,如网络配置或 Kubernetes 集群,不是由你自己去中心化的管理,而是由运维团队集中管理,所以运维永远不会消失。

还有 SVNOps 吗?

在某种程度上,是的,原则上可以使用任何想要的版本控制系统。GitOps 的核心思想之一是让开发人员使用熟悉的工具来操作基础设施。如果你更喜欢 SVN 而不是 Git,那也很酷!但是,你可能需要花更多精力寻找合适的工具,甚至需要编写自己的工具,当前所有可用的 operator 只基于 Git 存储库,抱歉!

应该为团队雇佣 GitOps 工程师吗?

不!没有 GitOps 工程师。GitOps 不是一种角色(DevOps 也一样)。GitOps 是一组实践。你可以寻找有 GitOps 实践经验的开发人员,或者让团队内的开发人员尝试这些实践。

工具、文章和讨论

工具

  • ArgoCD: 具有 web 界面的 Kubernetes 的 GitOps operator

  • Flux: 由 GitOps 的提出者 Weaveworkks 提供的 GitOps Kubernetes operator

  • Gitkube: 基于git push在 Kubernetes 上构建和部署 docker 镜像的工具

  • JenkinsX: 内置 GitOps 的 Kubernetes 持续交付工具

  • Terragrunt: Terraform的包装器,保持配置简洁、可复用,并管理远程状态

  • WKSctl: 基于 GitOps 原则的 Kubernetes 集群配置管理工具

  • Helm Operator: 在 K8S 上通过 Helm 使用 Git 的 operator

  • werf: 用于构建镜像并通过 push 方式部署到 Kubernetes 的 CLI 工具


更多工具请查看 Weavework 的Awesome-GitOps

博客文章和社交媒体

讨论


作者


Florian Beetz,目前在班贝格大学(University of Bamberg)学习国际软件系统科学,对云计算、clean code 和软件工程技术感兴趣,空闲时间欢去攀岩。


Anja Kammer,INNOQ 顾问,构建云原生网络应用程序。擅长处理部署自动化和 CI/CD 系统,专注于 DevOps、云基础设施和 Kubernetes 等主题。业余时间为 Kubernetes 开发了名为anya的开源云原生 CI/CD 系统。


Simon Harrer博士,在 INNOQ 工作,充满好奇心,喜欢分享知识,是Java by ComparisonRemote Mob ProgrammingGitOps以及最近的Data Mesh的共同作者之一。


你好,我是俞凡,在 Motorola 做过研发,现在在 Mavenir 做技术工作,对通信、网络、后端架构、云原生、DevOps、CICD、区块链、AI 等技术始终保持着浓厚的兴趣,平时喜欢阅读、思考,相信持续学习、终身成长,欢迎一起交流学习。

微信公众号:DeepNoMind

发布于: 2022 年 05 月 28 日阅读数: 3
用户头像

俞凡

关注

公众号:DeepNoMind 2017.10.18 加入

俞凡,Mavenir Systems研发总监,关注高可用架构、高性能服务、5G、人工智能、区块链、DevOps、Agile等。公众号:DeepNoMind

评论

发布
暂无评论
GitOps自问自答_最佳实践_俞凡_InfoQ写作社区