GitOps基于CICD和IaC,以一致的方式管理代码和部署,是DevOps最佳实践之一。本文完整介绍了GitOps的理念和实践,并介绍了Weave Cloud的GitOps模型和工具,从整体上提供了实践GitOps的路径和方案。原文:Guide To GitOps[1]
你是否听说过GitOps?想不想知道什么是GitOps?本文将介绍GitOps工作流的原则和模式,以及如何用来在生产中规模化运行Kubernetes。同时还将介绍GitOps和基础设施即代码(IaC, infrastructure-as-code)配置管理工具之间的差异,当然还将展示如何将GitOps最佳实践作为开发环境的一部分。
什么是GitOps?
GitOps在2017年被提出作为Kubernetes集群管理和应用交付的一种方式,利用Git作为声明性基础设施和应用程序的单一真实源(single source of truth)。在GitOps中,集群中运行的软件代理可以在运行状态和Git发生任何差异时发出告警,Kubernetes协调器会根据情况自动更新或回滚集群。Git作为交付流水线的中心,开发人员可以使用熟悉的工具发出pull request,从而加速和简化Kubernetes的应用部署和操作任务。
构建云原生应用程序的运维模型
GitOps可以概括为以下两点:
-
Kubernetes和其他云原生技术的运维模型,提供了一套最佳实践,用于统一容器化集群和应用程序的Git部署、管理和监控。 -
利用开发人员的经验管理应用程序的路径,将端到端CICD流水线和Git工作流应用于运维和开发。
GitOps原理
要开始使用GitOps工作流管理集群,必须具备以下条件:
#1. 整个系统以声明的方式描述。
有了Gitops, Kubernetes只是许多现代云原生工具中的一种,这些工具都是“声明式的”,可以被视为代码。声明式意味着配置是由一组事实而不是一组指令来保证的。在Git中对应用程序的声明进行版本化后,就有了唯一的真实来源,应用程序可以在Kubernetes上轻松部署和回滚。更重要的是,当发生问题时,集群基础设施也可以可靠的快速复制。
#2. 在Git中对系统状态进行版本控制。
通过将系统声明存储在版本控制系统中,并作为规范的真实来源,就有了唯一的地方派生和驱动所有东西。这种方式淡化了回滚,可以使用“Git revert”返回到之前的应用状态。基于Git出色的安全保证,还可以使用SSH密钥对提交进行签名,以加强对代码作者和出处的安全验证。
#3. 可自动将已批准的变更应用于系统。
将声明的状态保存在Git之后,下一步是允许在系统中自动应用状态的任何变更。重要的是,不需要认证就可以对系统进行更改。在GitOps中,环境是隔离的,状态定义位于环境之外,从而区分要做什么和要怎么做。
#4. 软件代理确保正确性并在状态不一致时发出告警。
一旦系统状态被声明并处于版本控制之下,当实际情况与期望不匹配时,软件代理就会发出通知。使用代理还可以确保整个系统能够自我修复。关于自我修复,指的不仅仅是节点或pod失效(这些由kubernetes处理),而是具有更广泛的意义,比如在人为错误等。在这种情况下,软件代理充当了操作的反馈和控制循环。
延伸阅读:
Getting Started with Weave GitOps Core[9]
GitOps: Operations by Pull Request[10]
The GitOps Pipeline - Part 2[11]
GitOps: ‘Git Push’ all the things (The New Stack)[12]
The Best CI/CD Tool for Kubernetes Doesn’t Exist[3]
The full history of GitOps 2017-2020[13]
GitOps的主要好处
当Git发生更改时,自动化的交付流水线将对基础设施进行更改。但是GitOps的思想远不止于此,GitOps使用工具来比较整个应用程序的实际生产状态与源代码控制下的状态,然后当集群状态与期望不匹配时,就会发出通知。
通过应用GitOps最佳实践,基础设施和应用程序代码都有唯一“真实来源”,允许开发团队提高速度并且提高系统可靠性。
延伸阅读:
Operate Kubernetes the GitOps Way[14]
应用GitOps最佳实践有很多好处:
-
提高生产力 集成反馈控制回路的自动化持续部署加快了平均部署时间,帮助团队将每天可交付的变更提升30-100倍以上,提高总体开发产出2-3倍。
-
增强研发体验 推送代码而不是容器,开发人员可以使用Git等熟悉的工具更快管理Kubernetes的更新和特性,而无需了解Kubernetes的内部情况。新入职的开发人员可以在几天内(而不是几个月)迅速提升速度并提高生产率。
-
增强稳定性 当我们用Git工作流来管理集群时,会自动获得Kubernetes之外的所有集群变更的审计日志。对何人、在何时、对集群做了什么进行审计跟踪,可以遵从SOC 2的要求并确保稳定性。
-
更高的可靠性 借助Git的恢复/回滚和fork功能,可以获得稳定和可重复的回滚。因为整个系统都在Git中描述,所以在崩溃后,也有唯一的真实来源来恢复,可以将恢复时间(MTTR)从几个小时减少到几分钟。
-
一致性和标准化 由于GitOps为基础设施、应用程序和Kubernetes附加组件的更改提供了统一的模型,因此可以在整个组织中拥有一致的端到端工作流。不仅持续集成和持续部署流水线都是由pull request驱动的,而且运维任务也完全可以通过Git反复触发。
-
强大的安全保障 Git强大的正确性和安全性保证,用于跟踪和管理更改的强大加密技术的支持,以及为变更签名以证明作者和来源的能力,是安全定义所需集群状态的关键。
GitOps是持续交付与云原生的结合
GitOps基于DevOps和站点可靠性工程(Site Reliability Engineering)的想法进行构建和迭代,始于Martin Fowler在2006年发表的全面的持续集成概述[2]。
自由选择需要的工具
作为CI/CD流水线的工作流,GitOps被描述为开发过程的圣杯[3]。因为没有一个工具可以完成CICD流水线中需要的所有工作,所以GitOps允许自由的为不同部分选择最佳的工具。根据特定用例,可以从开放源码生态系统或封闭源码中选择一组工具,甚至可以组合使用。创建CICD流水线最困难的部分是将所有部分融合在一起。
无论选择什么工具构建交付流水线,应用Git(或任何版本控制)的GitOps最佳实践都应该是这一流程中不可或缺的组成部分,从而更容易过渡到持续交付。不仅从技术角度看是这样,从文化角度看也是如此。
GitOps: 在声明性基础设施之上的版本化CI/CD。停止编写脚本,开始交付。https://t.co/SgUlHgNrnY - Kelsey Hightower (@kelseyhightower) 2018年1月17日
Git支持基础设施即代码(IaC)工具
Kubernetes只是许多现代云原生工具之一,这些工具都是“声明性的”,可以被视为代码。声明性意味着配置是由一组事实来保证的,而不是一组指令,例如,“有10个redis服务器”,而不是“启动10个redis服务器,然后告诉我它是否工作”。
使用声明性工具,整个配置文件集可以在Git中进行版本控制。通过使用Git作为真实的来源,应用程序更在Kubernetes上容易部署和回滚。更重要的是,当发生问题时,集群基础设施可以可靠、快速的从Git中重建。
IaC工具 vs GitOps
基础设施即代码作为可按需配置服务器的工具已经存在很长一段时间了,这些工具起源于通过代码控制工具维护基础架构配置的版本、备份和可复制的概念。
但现在Kubernetes几乎完全是声明式的,再加上不可变的容器,可以将这些概念扩展到管理应用程序及其操作系统。
Git能够管理和比较基础设施和应用程序的当前状态,从而通过完整的审计跟踪进行测试、部署、回滚和前滚,这包含了GitOps哲学及其最佳实践。由于Kubernetes几乎完全通过声明式配置进行管理,而且容器是不可变的,让这一切成为可能。
我们通过Terraform和Ansible来配置服务器,在Git中对这些配置文件进行备份和版本控制。IaC工具及其相关配置文件构成了GitOps工作流的核心,以便在发生问题时,能够近乎实时的恢复集群。可以在GitOps FAQ[4]中了解更多关于作为代码工具的基础设施与GitOps的不同之处。
如果系统偏离了真实来源怎么办?
声明性配置工具允许我们在Git中描述所需的真实状态,但是会遇到这样的问题:“现在真正正确的”状态存在于真实系统中,而这可能与版本控制中描述的不同。
-
怎么知道真实系统是否收敛到期望状态? -
当状态不同时能收到通知吗? -
遇到麻烦时,发出告警的“煤矿里的金丝雀”是什么? -
如何触发集群和源代码控制之间的聚合?
这些有现成解决方案。
像Chef, Puppet和Ansible等IaC工具支持“差异提醒”等功能,帮助运维人员理解什么时候可能需要采取行动,将真实系统“聚合”到预期的状态(由配置脚本定义)。最近,最佳实践是部署不可变镜像(例如容器),因此分化的可能性较小。
在“GitOps”模型中,使用Git来解决分歧以及收敛状态,并借助一组“diff”和“sync”工具(kubediff[5],以及terradiff和ansiblediff)来比较预期状态和实际状态。
基于不可变基础设施构建GitOps
GitOps充分利用了不可变基础设施和声明式容器编排,为了最小化部署后变更的风险,无论是有意的还是由于“配置漂移”引起的意外,都必须维护一个可重现的、可靠的部署过程。
Git描述了整个系统的期望状态(也就是“真实来源”)。我们基于容器实现不变性,使用不同的云原生工具,如terrform和Ansible来自动化和管理配置。这些工具与容器和Kubernetes的声明性特性一起帮助我们实现了当发生问题时可以完全恢复整个集群的能力。
延伸阅读:
GitOps for Kubernetes: A DevOps Iteration Focused on Declarative Infrastructure[15]
Why we use Terraform and not Chef, Puppet, Ansible, SaltStack, or CloudFormation[16]
What is GitOps Really?[17]
使用IaC工具
将GitOps原则应用于“一切”时,除了告警规则和仪表板之外,还包括机器配置、应用程序和服务,所有这些都处于源代码控制之下。
除非通过Git,否则不需要访问运行中的系统。任何一组更改都可以被原子的应用,并相应的加以区分。Git记录不仅是审计日志,也是事务日志,可以用来回回滚到任何快照。
延伸阅读:
Weaveworks & AWS; How we manage Kubernetes clusters[18]
Provisioning and Lifecycle of a Production Ready Kubernetes Cluster[19]
GitOps FAQ[4]
Weave Cloud中的持续交付和GitOps工作流
在我们的产品Weave Cloud[6]中,GitOps的核心机制集成在CI/CD工具中,关键部分是支持git集群同步[7]的持续部署(CD)。
Weave Cloud是专为版本控制系统和声明式应用程序栈设计的。团队中的每个开发人员可能都熟悉Git,可以发出pull requet,现在他们也可以使用Git来加速和简化Kubernetes的应用部署。
下面是一个典型的开发人员创建或更新新特性的工作流程:
-
一个新功能的pull request会被推送到GitHub进行审核。 -
代码由同事审核和批准。在修改代码并重新批准之后,将其合并到Git中。 -
Git合并触发CI和构建管道,运行一系列测试,最终构建一个新镜像,并存储到镜像仓库中。 -
Weave Cloud “Deployment Automator”监控镜像仓库,发现新镜像后,从仓库中提取新镜像并在配置仓库中更新YAML。 -
Weave Cloud “Deployment Synchronizer”(安装在集群中)检测到集群已过期,从配置仓库中提取更改的manifests,将新特性部署到生产环境中。
启用了GitOps的CICD流水线:
基于Operator模式实现的Kubernetes控制器
Weave Cloud实现了自定义控制器来监听和同步Kubernetes集群的部署。控制器采用Operator模式实现,Operator模式有两个优点:首先是更安全;其次,自动化了复杂的、容易出错的任务,比如手动更新YAML manifests。
通过使用Operator模式,代理代表集群侦听与自定义资源更改相关的事件,以便应用这些事件。代理负责将Git中的内容与集群中运行的内容同步,并为团队提供了一种实现持续部署的简单方法。
延伸阅读:
Comparing Kubernetes Operator Pattern with Alternatives[20]
Introducing Operators: Putting Operational Knowledge into Software[21]
CI/CD for Kubernetes: what you need to know[22]
Pull流水线 vs Push流水线
Push流水线
目前可用的大多数CI/CD工具都基于push模型。基于push的流水线意味着代码从CI系统开始,通过一系列脚本处理,或者手工使用'kubectl
'将更改推送到Kubernetes集群。
我们不希望使用CI系统触发部署或在命令行上手动进行部署的原因是,这可能需要在集群外公开验证凭据。虽然可以同时保护CI/CD脚本和命令行,但在集群的信任域之外工作,通常不是良好的实践,这就是为什么CI系统可以被认为是生产系统的攻击媒介。
集群外部具有读写权限的典型push流水线:
在Weave Cloud中,image被拉取(pull),凭据被保存在集群中:
Weave Cloud Pull流水线
Weave Cloud使用pull策略,该策略由两个关键组件组成: 监视镜像仓库的“Deployment Automator”和位于集群中维护其状态的“Deployment Synchronizer”。
Pull流水线模式的中心具有单一真实源的manifests(或配置仓库)。开发人员将更新的代码推送到代码库中,CI工具提取这些变更的代码并构建Docker镜像。Weave Cloud的“Deployment Automator”发现并从镜像仓库中提取新镜像,然后在配置文件中更新YAML。然后Deployment Synchronizer检测到集群过期,从配置仓库中提取更改后的manifests,并将新镜像部署到集群。
在集群中部署Weave Cloud代理
使用集群中的Deployment synchronizer,集群凭据不会公开到生产环境之外。一旦在集群中安装了Weave Cloud代理并连接上Git仓库,就可以通过Git pull request完成生产环境的任何变更,并且可以利用Git提供的完整的回滚以及方便的审计日志。
延伸阅读:
How secure is your pipeline?[23]
可观察性是部署的催化剂
有了Kubernetes, GitOps可以通过pull request管理基础设施和应用程序部署。但是GitOps工作流和可观察性是如何协同工作的呢?
通过将GitOps工作流与实时可观察性相结合,开发团队可以在部署任何新特性之前做出关键决策。即将发布的服务可以在发布之前在运行的集群中实时观察到,这意味着可以放心部署并更快交付质量更好的特性。
可观察性可以被视为Kubernetes持续交付[8]周期的主要驱动因素之一,描述了系统在任何给定时间的实际运行状态。观察运行中的系统是为了了解和控制它。新特性和修复被推送到git并触发部署流水线,当准备好发布时,可以在运行的集群上实时观察。此时,开发人员可以根据反馈返回到流水线的起点,或者部署镜像并将其发布到生产集群。
GitOps是面向发布的运维和特性模型。向客户交付新特性的速度,一定程度上取决于团队在这个周期中完成各个阶段的速度。
同时使用GitOps工作流和可观察性的开发人员需要回答以下问题:
-
如果一个变更是自动发布的,我们怎么知道它真的工作了? -
我们如何能确定变更真的让产品更好? -
在复杂的分布式系统中,如何理解问题、诊断问题和处理事件?
通过Weave Cloud,在部署和发布过程中集成可观察性工作负载指示板,在承诺将部署发布到预发或生产环境之前,可以一眼看出部署是否成功。不仅可以帮助我们更快识别问题,而且由于可观察性工作负载指示板是实时的,并且内置在部署流程中,因此可以每天部署多次服务,并确信部署没有重大缺陷。
延伸阅读:
GitOps Observability[24]
Monitoring Kubernetes with Prometheus[25]
GitOps的好处
更快的开发
通过采用GitOps最佳实践,开发人员可以使用类似Git这样的熟悉工具更快管理Kubernetes的更新和特性。通过不断推动功能更新,企业更加敏捷,能够更快响应客户需求,并在市场上更具竞争力。
更好的运维
有了GitOps,就有了完整的端到端流水线,不仅持续集成和持续部署流水线都是由pull request驱动,而且运维任务也可以通过Git完全重现。
如果使用Weave Cloud,部署到正在运行的集群也是安全的,不会将敏感认证凭据泄露到集群之外。
更强的安全保障
Git强大的正确性和安全性保证,用于跟踪和管理变更的强大加密技术支持,以及签名变更以证明作者和来源的能力,是正确和安全定义集群所需状态的关键。如果确实发生了安全漏洞,可以使用不可变和可审计的真实来源,独立于受损的系统重新创建新系统,减少停机时间,提供更好的问题响应。
将系统构建和生产环境发布之间的责任分离,体现了最小特权的安全原则,减少了妥协的影响并提供了更小的攻击面。
更容易遵循规范并方便审计
由于以一种安全的方式跟踪和记录更改,遵循规范和审计就变得很容易了。使用像kubediff、terradiff和ansiblediff这样的比较工具,允许将集群状态的可信定义与实际运行的集群进行比较,确保被跟踪和可审计的更改与现实相匹配。
延伸阅读:
Try GitOps out for yourself[26]
GitOps: High velocity CICD for Kubernetes[27]
GitOps workflows with Weave Cloud - Tutorial[28]
How to Boost Business Performance with GitOps: The Facts[29]
Multi-cloud Strategies with Kubernetes and GitOps[30]
References:
[1] Guide To GitOps: https://www.weave.works/technologies/gitops/
[2] Continuous Integration: https://martinfowler.com/articles/continuousIntegration.html
[3] The Best CI/CD tool for Kubernetes Doestn't Exist: https://thenewstack.io/the-best-ci-cd-tool-for-kubernetes-doesnt-exist/
[4] GitOps FAQ: http://www.weave.works/technologies/gitops-frequently-asked-questions
[5] Kubediff: https://github.com/weaveworks/kubediff
[6] Weave Cloud: https://cloud.weave.works/signup
[7] Automated Git Cluster Synchronisation: https://github.com/fluxcd/flux/blob/master/docs/introduction.md#automated-git-cluster-synchronisation
[8] Continuous Delivery: https://continuousdelivery.com/
[9] Getting Started with Weave GitOps Core: https://vimeo.com/676402260?embedded=true&source=video_title&owner=58523808
[10] GitOps: Operations by Pull Request: https://www.weave.works/blog/gitops-operations-by-pull-request
[11] The GitOps Pipeline - Part 2: https://www.weave.works/blog/the-gitops-pipeline
[12] GitOps: ‘Git Push’ all the things (The New Stack): https://thenewstack.io/gitops-git-push-all-the-things
[13] The full history of GitOps 2017-2020: https://assets.contentstack.io/v3/assets/blt300387d93dabf50e/blt326ac6188d55a84a/60643ace4f68540feec1038c/History_of_GitOps_Timeline.pdf
[14] Operate Kubernetes the GitOps Way: https://vimeo.com/315294468?embedded=true&source=video_title&owner=58523808
[15] GitOps for Kubernetes: A DevOps Iteration Focused on Declarative Infrastructure: https://thenewstack.io/gitops-kubernetes-devops-iteration-focused-declarative-infrastructure
[16] Why we use Terraform and not Chef, Puppet, Ansible, SaltStack, or CloudFormation: https://blog.gruntwork.io/why-we-use-terraform-and-not-chef-puppet-ansible-saltstack-or-cloudformation-7989dad2865c
[17] What is GitOps Really? https://www.weave.works/blog/what-is-gitops-really
[18] Weaveworks & AWS; How we manage Kubernetes clusters: https://www.weave.works/technologies/weaveworks-on-aws
[19] Provisioning and Lifecycle of a Production Ready Kubernetes Cluster: https://www.weave.works/blog/provisioning-lifecycle-production-ready-kubernetes-cluster
[20] Comparing Kubernetes Operator Pattern with Alternatives: https://medium.com/@cloudark/why-to-write-kubernetes-operators-9b1e32a24814
[21] Introducing Operators: Putting Operational Knowledge into Software: https://coreos.com/blog/introducing-operators.html
[22] CI/CD for Kubernetes: what you need to know: https://www.weave.works/technologies/ci-cd-for-kubernetes
[23] How secure is your pipeline? https://www.weave.works/blog/how-secure-is-your-cicd-pipeline
[24] GitOps Observability: https://www.weave.works/blog/gitops-part-3-observability
[25] Monitoring Kubernetes with Prometheus: https://www.weave.works/technologies/monitoring-kubernetes-with-prometheus/#deploy-new-features
[26] Try GitOps out for yourself: https://www.weave.works/product/gitops-core
[27] GitOps: High velocity CICD for Kubernetes: https://www.weave.works/blog/gitops-high-velocity-cicd-for-kubernetes
[28] GitOps workflows with Weave Cloud - Tutorial: https://www.weave.works/blog/gitops-workflows-for-istio-canary-deployments
[29] How to Boost Business Performance with GitOps: The Facts: https://go.weave.works/DORA_GitOps_WP.html?LeadSource=Web%20Content&CampaignID=7014M000001z7lD&LSD=Website
[30] Multi-cloud Strategies with Kubernetes and GitOps: https://go.weave.works/2021_multi_cloud_strategies_wp.html?LeadSource=WebContent&LSD=Website&CampaignID=7014M000001z9sV
- END -你好,我是俞凡,在Motorola做过研发,现在在Mavenir做技术工作,对通信、网络、后端架构、云原生、DevOps、CICD、区块链、AI等技术始终保持着浓厚的兴趣,平时喜欢阅读、思考,相信持续学习、终身成长,欢迎一起交流学习。
微信公众号:DeepNoMind
本文由 mdnice 多平台发布