GitOps
本文主要介绍如下内容:
GitOps是什么?
为什么GitOps很重要?
GitOps与其他方法的比较
使用GitOps的好处
Kubernetes是一个非常受欢迎的开源平台,它可以协调和自动化操作。尽管Kubernetes改进了基础设施和应用程序的管理和扩展,但Kubernetes在管理发布应用程序的复杂性方面经常遇到挑战。
Git是当今软件行业中使用最广泛的版本控制系统。GitOps是一组过程,它使用Git的强大功能在Kubernetes平台中提供修订和更改控制。GitOps战略可以在团队管理服务环境创建、推广和运营的速度和容易程度上发挥重要作用。
在Kubernetes中使用GitOps非常便捷,声明式Kubernetes清单文件的部署由常见的Git操作控制。GitOps以一种直观、可访问的方式为Kubernetes应用程序的部署、监控和生命周期管理带来了基础设施即代码和不可变基础设施的核心好处。
向GitOps的演进
管理和操作计算机系统的两项日常任务是基础设施配置和软件部署。基础设施配置是为软件应用的正常运行准备计算资源(如服务器、存储、负载均衡器等)。软件部署是使用特定版本的软件应用程序并使其能够在计算基础设施上运行的过程。管理这两个进程是GitOps的核心。然而,在我们深入研究这种管理在GitOps中是如何完成的之前,理解导致行业走向DevOps和GitOps的不可变、声明式基础设施的挑战是有用的。
传统运维
在传统的信息技术运营模型中,开发团队负责定期将软件应用程序的新版本交付给质量保证(QA)团队,后者测试新版本,然后将其交付给运营团队进行部署。新版本的软件可能每年、每季度或更短的间隔发布一次。传统的操作模型越来越难以支持日益压缩的发布周期。
操作团队负责基础架构的配置和新软件应用程序版本到该基础架构的部署。运营团队的首要重点是确保运行软件的系统的可靠性、弹性和安全性。如果没有成熟的管理框架,基础设施管理可能是一项困难的任务,需要大量的专业知识。

IT运维是由IT员工提供给内部或外部客户并由员工用于提供业务技术需求的所有流程和服务的集合。操作工作可以包括响应为维护工作或客户问题的需求。
由于涉及到多个团队,并且通常具有不同的管理报告结构,因此需要详细的切换过程和应用程序更改的完整文档,以确保应用程序得到充分的测试,对基础设施进行适当的更改,并正确安装应用程序。然而,这些需求导致部署花费很长时间,并降低了部署的频率。此外,随着团队之间的每一次转换,基本细节不被沟通的可能性也会增加,这可能会导致测试中的差距或不正确的部署。

幸运的是,大多数开发团队通过使用自动构建系统和称为持续集成(CI)的流程来编译、测试和生成可部署的构件。但是,新代码的部署通常是由操作团队执行的手动过程,包括冗长的手动过程或通过部署脚本实现的部分自动化。在最坏的情况下,工程师手动将可执行二进制文件复制到多个服务器上所需的位置,并手动重新启动应用程序,使新的二进制版本生效。这个过程很容易出错,并且为诸如审查、批准、审核和回滚等控制提供了很少的选项。
持续集成(Continuous Integration, CI)涉及软件应用程序的自动构建、测试和打包。在典型的开发工作流中,软件工程师进行代码更改,这些更改签入到中央代码存储库中。必须对这些更改进行测试,并将其与打算部署到生产环境中的主代码分支集成。CI系统有助于代码的审查、构建和测试,以确保其在合并到主分支之前的质量。
随着云计算基础设施的兴起,管理计算和网络资源的接口越来越多地基于应用程序编程接口(api),允许更多的自动化,但需要更多的编程技能来实现。这一事实,再加上许多组织都在寻找优化操作、减少部署时间、增加部署频率、提高计算系统的可靠性、稳定性和性能的方法,导致了一个新的行业趋势:DevOps。
DevOps
DevOps是一种强调自动化的组织结构和思维方式的改变。运维小组不再负责部署和行动;应用程序的开发团队承担这些责任。
DevOps是一组软件开发实践,它结合了软件开发(Dev)和IT运维(Ops)来缩短系统开发生命周期,同时频繁地交付功能、修复和更新,以与业务目标保持一致。
图3显示了在传统的运维模型中,组织是如何通过不同的开发、质量和运维团队,按照功能边界划分的。在DevOps模型中,团队是按产品或组件划分的,并且是跨学科的,包含拥有所有功能的技能集的团队成员。虽然图3表示团队成员具有特定的角色,但高功能团队中所有执行DevOps的成员都可以跨功能做出贡献;每个成员都能够编码、测试、部署和操作他们的产品或组件。

DevOps的好处包括:
开发和运营之间更好的协作
改善产品质量
更频繁的发布
缩短了新功能的上市时间
降低了设计、开发和运维成本
Netflix是DevOps流程的早期采用者之一,每个工程师都负责编码、测试、部署和支持他们的功能。Netflix的文化提倡“自由和责任”,这意味着每个工程师都可以独立推动发行,但必须确保该发行的正确运行。所有部署过程都是完全自动化的,因此工程师只需按下一个按钮就可以进行部署和回滚。一旦功能完成,所有新特性都将在最终用户手中。
GitOps
GitOps一词是在2017年8月由weaveworks联合创始人兼首席执行官亚历克西斯·理查森的一系列博客中创造出来的。从那时起,这个词在原生云计算社区,尤其是Kubernetes社区中,得到了广泛的关注。GitOps是一个DevOps进程:
用于部署、管理和监视容器化应用程序的最佳实践
以开发人员为中心的应用程序管理体验,使用Git进行开发和操作的全自动化管道/工作流
使用Git版本控制系统来跟踪和批准对应用程序的基础设施和运行时环境的更改

GitHub(以及GitLab、Bitbucket等)是现代软件开发生命周期的核心,因此它也被用于系统操作和管理。
在GitOps模型中,系统所需的配置存储在分布式控制系统中,例如Git。工程师不是通过UI或CLI直接对系统进行更改,而是对表示所需状态的配置文件进行更改。Git中存储的理想状态和系统的实际状态之间的差异表明并不是所有的更改都已经部署。这些变更可以通过标准的分布式控制过程进行审查和批准,例如拉请求、代码审查和合并到主分支。当更改被批准并合并到主分支时,操作员软件流程负责根据存储在Git中的配置将系统的当前状态更改为所需状态。
在理想的GitOps实现中,不允许手动更改系统,对配置的所有更改都必须对存储在Git中的文件进行。在极端情况下,更改系统的权限只授予操作员软件流程。在GitOps模型中,基础设施和运维工程师的角色从执行基础设施更改和应用程序部署转变为开发和维护GitOps自动化,并通过使用Git帮助团队审查和批准更改。
Git有许多特性和技术能力,这使它成为GitOps的理想选择:
Git存储每个提交。
通过适当的访问控制和安全配置,所有更改都是可审计的和防篡改的。
Git中的每一次提交都代表系统在那个时间点之前的完整配置。
Git中的每个提交对象都与它的父提交相关联,因此在创建和合并分支时,提交历史在需要时可用。
GitOps很重要,因为它支持对环境所做更改的跟踪,并支持使用Git(大多数开发人员都熟悉的工具)轻松回滚、可恢复和自修复。
Git提供了验证和审计部署的基础。尽管可以通过使用Git以外的版本控制系统来实现GitOps,但Git的分布式特性、分支和合并策略以及广泛采用使其成为理想的选择。
GitOps不需要特定的工具集,但这些工具必须提供以下标准功能:
对存储在Git中的系统的期望状态进行操作
检测期望的状态和实际状态之间的差异
在基础架构上执行所需的操作,以使实际状态与所需状态同步
GitOps对于开发人员的益处
GitOps为开发人员提供了许多好处,因为它允许他们以与管理软件开发过程相同的方式处理基础设施配置和代码部署,并且使用熟悉的工具:Git。
基础设施代码(IaC)
基础设施即代码(IaC)是GitOps的一个基本范例。运行应用程序的基础结构的配置是通过执行自动化的过程而不是手动步骤来完成的在实践中,IaC意味着对基础设施的更改进行编码,并且基础设施的源代码存储在版本控制系统中。让我们来看看最显著的好处:
可重复性—-每个有手动配置基础设施经验的人都认为这个过程是耗时且容易出错的。
不要忘记同一个过程必须重复多次,因为应用程序通常部署到多个环境中。
如果发现问题,则更容易使用可重复的流程回滚到早期的工作配置,从而允许更快的恢复。
可靠性—-自动化过程大大降低了不可避免的人为错误的机会,从而减少了中断的可能性。
当过程被编码后,基础设施质量不再依赖于执行部署的特定工程师的知识和技能。
基础设施配置的自动化可以稳步提高。
效率—-IaC提高了团队的生产力。
使用IaC,工程师的工作效率更高,因为他们使用熟悉的工具,如api、软件开发工具包(sdk)、版本控制系统和文本编辑器。
工程师可以使用熟悉的流程,利用代码评审和自动化测试。
成本—-IaC的最初实现需要大量的努力和时间投入。
尽管初始成本很高,但从长远来看,它更具有成本效益。
为下一个环境提供基础设施不需要浪费宝贵的工程师手工配置时间。
由于配置快速且便宜,所以不需要保持未使用的环境运行。
相反,每个环境都可以按需创建,并在不再需要时销毁。
可视化—-当定义IaC时,代码本身就记录了基础结构应该是什么样子。
IaC使开发人员能够在节省时间和金钱的同时生产出更高质量的软件。为一个环境手动配置基础设施可能更容易,但维护该环境以及应用程序的数十个其他环境将变得越来越具有挑战性。使用自动化的基础设施配置并遵循IaC原则,可以实现可重复的部署,并防止配置漂移或缺少依赖所导致的运行时问题。
Self-service
如前所述,在传统的运维模型中,基础设施管理是由一个专门的团队甚至是公司中的一个独立组织执行的。
然而,有一个问题:这种方法不能伸缩。无论有多少成员,专注的团队很快就会成为瓶颈。应用程序开发人员不必自己更改基础设施,而是必须提交表单、发送电子邮件、安排会议,然后等待。无论流程如何,都存在一个障碍,这会导致许多延迟,并阻碍团队主动提出基础设施更改。GitOps的目标是通过自动化流程和自助服务来打破这一障碍。
在使用GitOps模型时,开发人员不发送表单,而是独立地处理解决方案,并在存储库中提交对基础设施声明式配置的更改。基础设施的改变不再需要跨团队的交流,允许应用程序开发团队更快地向前推进,并有更多的自由进行试验。快速独立地更改基础架构的能力鼓励开发人员拥有他们的应用程序基础架构。开发人员可以试验和开发有效解决业务需求的设计,而不是向中央运维团队寻求解决方案。

然而,开发人员不能完全控制他们想做的任何事情,这可能会危及安全性或可靠性。每个更改都需要创建一个pull请求,该请求可以由应用程序开发团队的另一个成员审查。
GitOps的优势在于,它允许自助服务基础设施的更改,并在控制和开发速度之间提供了正确的平衡。
代码审查
代码审查是一种软件开发实践,在这种实践中,代码变更由第二个人主动检查错误或遗漏,从而导致较少的可预防中断。执行代码评审是软件开发生命周期中的一个自然过程,执行DevOps/GitOps的软件工程师应该熟悉这个过程。当DevOps工程师可以将基础设施视为代码时,合乎逻辑的下一步是在部署之前对基础设施更改执行代码审查。当与Kubernetes一起使用GitOps时,要检查的“代码”可能主要是Kubernetes YAML清单或其他声明式配置文件,而不是用编程语言编写的传统代码。
除了错误预防之外,代码检查还提供以下好处:
教学和分享知识—-审稿人在评审这些变化时,不仅有机会给出反馈,也有机会学到一些东西。
设计和实现的一致性—-在评审期间,团队可以确保更改与整体代码结构保持一致,并遵循公司的代码风格指导方针。
团队凝聚力—-代码评审不仅仅是为了批评和请求变更。
这个过程也是团队成员互相称赞、拉近关系、确保每个人都全身心投入的好方法。
在适当的代码审查过程中,只有经过验证和批准的基础结构更改才提交到主分支,从而防止对操作环境的错误和错误修改。代码审查并不一定要完全由人来完成。代码审查过程还可以运行自动化的工具,如代码检查器、静态代码分析和安全工具。
长期以来,代码审查一直被视为软件开发最佳实践的关键部分。GitOps的关键前提是,应用程序代码中使用的严格的代码检查应该应用于应用程序操作环境中的更改。
Git pull requests
Git版本控制系统提供了一种机制,在这种机制下,所提议的更改可以提交到一个分支,然后通过一个pull请求与主分支合并。在2005年,Git引入了一个request-pull
命令。此命令生成所有更改的可读摘要,可以手动将其邮寄给项目维护者。pull请求收集存储库文件的所有更改,并为代码审查和批准提供差异。
Pull请求可以用来执行预合并代码审查。在pull请求合并到主分支之前,可以设置控制来要求特定的测试或批准。与代码审查一样,拉请求是软件开发生命周期中一个熟悉的过程,软件工程师可能已经在使用它了。
图6演示了典型的拉取请求生命周期:
开发人员创建一个新的分支并开始处理更改。
当变更准备就绪时,开发人员发送一个pull请求以进行代码审查。
团队成员审查pull请求并请求更多的更改(如果需要)。
开发人员一直在分支中进行更改,直到pull请求被批准。
项目维护者将pull请求合并到主分支中。
合并之后,用于提取请求的分支可能会被删除。

当应用到基础设施变更审查时,审查步骤特别有趣。在创建pull请求之后,项目维护者会收到一个通知并审查所提议的变更。因此,评审员会提出问题,得到答案,并可能要求更多的更改。这些信息通常会被存储起来,以备将来参考,所以现在pull请求是基础设施更改的实时文档。如果发生事故,很容易找出是谁做出了更改,以及为什么要进行更改。
GitOps对运维的益处
将GitOps方法与Kubernetes的声明式配置和主动协调模型相结合,可以提供许多运维上的好处,从而提供更可预测和更可靠的系统。
声明式
DevOps运动产生的最突出的范例之一是声明式系统和配置模型。简单地说,通过声明式模型,可以描述想要实现什么,而不是如何实现。相比之下,在命令式模型中,描述了操作系统以达到所需状态的指令序列。
为了说明这种区别,想象一下电视遥控器的两种样式:命令式样式和声明式样式。两个遥控器都可以控制电视的功率、音量和频道。为了便于讨论,假设电视机只有三种音量设置(大声、柔和、静音)和三个频道(1,2,3)。

假设有一个简单的任务,即使用两个远程服务器更改为通道3。要使用命令式遥控器完成此任务,将使用频道上升按钮,该按钮向电视发出信号,使当前频道增加1。要到达3频道,你需要不停地按频道按钮几次,直到电视到达你想要的频道。
相反,声明式远程提供了直接跳转到特定编号通道的单个按钮。在这种情况下,要切换到3频道,你只需按一次3频道按钮,电视就会进入正确的频道。正在声明预期的最终状态(我希望将电视调到3频道)。使用命令式遥控器,将描述实现所需状态所需执行的操作(一直按频道上电按钮,直到电视调到3频道)。
在切换频道的命令式方法中,用户必须考虑是否继续按频道上升按钮,这取决于电视当前调到的频道。但是,在声明式方法中,可以毫不犹豫地按下channel-3按钮,因为声明式远程上的按钮被认为是幂等的(而命令式远程上的通道上的按钮则不是)。
幂等性是操作的一种属性,该操作可以被执行任意次并产生相同的结果。换句话说,如果一个操作可以执行任意次数,并且系统处于与只执行一次操作相同的状态,那么这个操作就是幂等的。等幂是区别声明式系统和命令式系统的属性之一。声明式系统是幂等的;命令式系统则不然。
可观测性
可观察性是检查和描述系统当前运行状态并在意外情况发生时发出警报的能力。部署的环境应该是可观察的。换句话说,应该始终能够检查环境,以查看当前运行的内容以及配置的方式。为此,服务和云提供商提供了相当多的方法来提高可观察性(包括CLIs、APIs、GUIs、仪表板、警报和通知),使用户尽可能方便地了解环境的当前状态。

尽管这些可观察性机制可以帮助回答以下问题:“我的环境中当前运行的是什么?”无法回答以下问题:“对于当前在我的环境中配置和运行的资源,它们是否应该以这种方式配置和运行?”如果曾经担任过系统管理员或操作人员,那么可能对这个问题非常熟悉。有时—-通常是在对环境进行故障排除时—-会遇到一个可疑的配置设置,并认为它似乎不正确。是有人(可能是你)不小心或错误地改变了这个设置,还是这个设置是故意的?
已经在实践GitOps的一个基本原则:在源代码控制中存储应用程序配置的副本,并将其作为应用程序所需状态的真实来源。可能不会将此配置存储在Git中以驱动持续部署—只是在某个地方复制一份副本,以便能够复制环境,例如在灾难恢复场景中。这个副本可以认为是所需的应用程序状态,除了灾难恢复用例,它另一个有用的目的:它使运营商比较实际的运行状态与期望状态在源代码控制在任何时候验证状态匹配。

验证环境的能力是GitOps的核心原则,它已经正式成为一种实践。通过将需要的状态存储在一个系统(比如Git)中,并定期将需要的状态与运行状态进行比较,就解锁了一个新的可观察性维度。不仅拥有由提供者提供的标准的可观察性机制,而且还能够检测与所需状态的差异。
偏离你想要的状态,也称为配置漂移,可能由于各种原因发生。常见的例子包括操作符错误、自动化带来的意外副作用和错误场景。配置漂移甚至是可以预期的,例如由过渡时期(例如维护模式)引起的临时状态。
但造成配置差异的最重要原因可能是恶意的。在最坏的情况下,一个糟糕的参与者可能已经破坏了环境,并重新配置了系统以运行恶意映像。因此,可观察性和可验证性对于系统的安全性至关重要。除非你有所需状态的真实源,并且没有验证该真实源收敛的机制,否则就不可能知道你的环境是真正安全的。
可审核性和合规性
对于在法律和法规影响信息管理和法规遵从性评估框架的国家开展业务的组织来说,允许遵从性和可审核性是必须的—-这是当今时代的大多数国家。有些行业比其他行业受到更多监管,但几乎所有公司都需要遵守基本的隐私和数据安全法律。许多组织不得不在他们的流程和系统上进行大量的投资,以使其符合要求并可审计。使用GitOps和Kubernetes,大多数遵从性和可审核性需求可以用最少的努力得到满足。
遵从性指的是验证组织的信息系统是否符合一组特定的行业标准,通常关注于客户数据的安全性,以及是否遵守组织关于有权访问该客户数据的人员和系统的文档化政策。
可审核性是一个被验证为符合一组标准的系统的能力。如果一个系统不能被展示给内部或外部审计师,那么就不能对系统的符合性做出任何声明。
可审核性也指审核员对组织内部控制进行全面检查的能力。在典型的审计中,审核员要求提供证据,以确保规则和策略得到相应的执行。证据可能包括限制访问用户数据的过程,个人身份信息(PII)的处理,以及软件发布过程的完整性。

Git是一个版本控制软件,可以帮助组织管理对代码的更改和访问控制。Git会在一种特殊的数据库中跟踪对代码的每次修改,这种数据库的设计目的是保持托管源代码的完整性。Git存储库中的文件内容以及文件和目录、版本、标记和提交之间的真实关系都是通过SHA校验和哈希算法保护的。该算法保护代码和更改历史,防止意外和恶意更改,并确保历史是完全可跟踪的。
Git的历史跟踪还包括作者、日期和关于每个更改目的的记录。有了编写良好的提交注释,就知道为什么要进行特定的提交。Git还可以与项目管理和bug跟踪软件集成,允许对所有更改进行全面跟踪,并支持根本原因分析和其他取证。
正如前面提到的,Git支持pull请求机制,这可以防止任何个人在未经另一个人批准的情况下更改系统。当pull请求被批准时,更改将记录在安全的Git更改历史中。Git在更改控制、可跟踪性和更改历史真实性方面的优势,以及Kubernetes的声明性配置,自然满足了可审计性和遵从性所需的安全性、可用性和处理完整性原则。

灾难恢复(Disaster recovery)
灾难的发生有许多原因和形式,灾难可能是自然发生的(地震袭击数据中心),由设备故障(存储阵列的硬盘驱动器丢失),意外(软件错误破坏关键数据库表),甚至是恶意的(造成数据丢失的网络攻击)。
GitOps通过在源代码控制下存储环境的声明式规范作为真相来源来帮助基础设施环境的恢复。对环境应该是什么有一个完整的定义,有助于在发生灾难时重建环境。灾难恢复变成了一个简单的练习,即应用存储在Git存储库中的所有配置。你可能会注意到,灾难期间遵循的过程与日常升级和部署中使用的过程之间没有太大区别。使用GitOps,实际上是在定期实践灾难恢复过程,以便在真正的灾难发生时做好充分准备。
尽管GitOps有助于简化计算和网络基础设施的灾难恢复,但持久性和有状态应用程序的恢复需要以不同的方式处理。对于与存储相关的基础设施,没有什么可以替代传统的灾难恢复解决方案:备份、快照和复制。
总结
GitOps是一个DevOps部署流程,使用Git作为记录系统来管理复杂系统中的部署。
传统的Ops需要一个独立的团队进行部署,而新版本的部署可能需要几天。
DevOps使工程师能够在代码完成后立即部署新版本,而无需等待一个集中的操作团队。
GitOps提供全面的可追溯性和释放控制。
声明式模型描述你想要实现的东西,而不是实现它所需的步骤。
等幂是操作的一种属性,该操作可以执行任意次数并产生相同的结果。
GitOps的其他好处包括
拉出代码质量和发布控制的请求
可观察的运行状态和期望的状态
具有历史真实性和可追溯性的简化遵从性和可审核性过程
简单的灾难恢复和回滚过程,与熟悉的部署经验一致
感兴趣的关注如下公众号!





