1.2 GitOps带给开发者的好处
GitOps为开发人员提供了许多好处,因为它允许开发者使用与管理软件开发过程大体相同的方式来处理基础设施配置和代码部署,并且使用的是熟悉的工具:Git。
1.2.1 基础设施即代码
基础设施即代码(IaC)是GitOps的基本范式。运行应用程序的基础设施的配置是通过自动化过程而非手动步骤来完成的[4]。在实践中,IaC意味着通过编码进行基础设施的变更,并将基础设施的源代码存储在版本控制系统中。让我们来看看IaC的显著好处:
□可重复性:所有有过手动配置基础设施经验的人都同意该过程既耗时又容易出错。IaC不会忘记同一过程必须得重复多次,因为应用程序通常会部署到多个环境中。如果发现问题,也可以通过可重复的过程更轻松地回滚到较早的工作配置,从而加快恢复。
□可靠性:自动化过程显著降低了发生不可避免的人为错误的可能性,进而降低了中断的可能性。当过程被编码后,基础设施的质量不再取决于执行部署的特定工程师的知识和技能。另外,基础设施配置的自动化程度也能稳步提高。
□效率:IaC提高了团队的生产力。借助IaC,工程师的工作效率更高,因为他们使用熟悉的工具,例如API、软件开发工具包(SDK)、版本控制系统和文本编辑器。工程师可以使用熟悉的流程,并利用代码审查和自动化测试带来的优势。
□节省:IaC的初始实施需要投入大量精力和时间。然而,尽管初始成本较高,但从长远来看,它更具成本效益。后续环境的基础设施置备将不再需要工程师把宝贵的时间浪费在手动配置上。由于资源置备速度快且成本低,因此无须保持未使用的环境运行。相反,每个环境都可以按需创建,并在不再需要时销毁。
□可见性:当你定义IaC时,代码本身就记录了基础设施该有的样子。
IaC使开发人员能够生产更高质量的软件,同时节省时间和金钱。为单一环境手动配置基础设施可能更容易,但维护该环境以及应用程序的其他数十个环境将变得越来越有挑战。使用自动化基础设施配置并遵循IaC原则,能够实现可重复的部署,并防止由配置漂移或缺少依赖项引起的运行时问题。
1.2.2 自服务
如前所述,在传统的运维模式中,基础设施管理由专门的团队甚至公司内的一个独立组织来负责。
然而,这种方法存在一个问题:无法规模化。无论有多少成员,这个专用团队很快就会成为瓶颈。在该方法下,应用开发人员无法自己变更基础设施,取而代之的是必须提交工单、发送电子邮件、安排会议,然后就是等待。无论过程如何都存在障碍,这将导致许多延迟,并阻碍团队主动提出基础设施变更。GitOps旨在通过自动化过程,并使其成为自服务来打破这一障碍。
相较于提交工单,当使用GitOps模型时,开发人员有一个可独立工作的解决方案,并对仓库提交基础设施声明式配置的更改(见图1.5)。基础设施的变更不再需要跨团队的沟通,这使得应用开发团队能够更快地向前推进,并有更多的自由进行试验。快速且独立地变更基础设施的能力鼓励开发人员对其应用程序基础设施拥有所有权。开发人员可以试验和发展一种能够有效解决业务需求的设计,而无须向集中式运维团队寻求解决方案。
图1.5 开发团队可以通过更新存储在Git仓库中的文件来更改系统的期望状态。这些变更由其他团队成员进行代码审查,并在批准后合并到主干分支。主干分支中的内容由部署集群期望配置的GitOps Operator来处理
开发人员在做他们想做的事情时不会被完全管控,然而,这也可能会对安全性或可靠性带来损害。因此需要对每个变更都创建一个拉取请求,拉取请求可由应用开发团队的其他成员审核。接下来会进行说明。
GitOps的优势在于它允许自服务式的基础设施变更,并在管控和开发速度之间提供合理的平衡。
1.2.3 代码审查
代码审查是一种软件开发实践,在该实践里,会有第二双眼睛主动检查代码的更改是否存在错误或遗漏,从而减少可预防的中断。执行代码审查是软件开发生命周期中的一个自然过程,从事DevOps/GitOps的软件工程师应该熟悉这个过程。当DevOps工程师可以将基础设施视为代码时,符合逻辑的下一步是在部署之前对基础设施更改执行代码审查。当GitOps与Kubernetes一起使用时,被审查的“代码”可能主要是Kubernetes YAML清单或其他声明式配置文件,而不是用编程语言编写的传统代码。
除了防止错误外,代码审查还提供以下好处:
□教授和分享知识:在审查更改时,审查者不仅有机会提供反馈,而且有机会学到一些东西。
□设计和实现的一致性:在审查期间,团队可以确保更改与整体代码结构保持一致,并遵循公司的代码风格指南。
□团队凝聚力:代码审查不仅仅是为了批评和请求更改,这也是团队成员相互称赞、拉近距离,并确保人人充分参与的绝佳方式。
在合理的代码审查过程中,只有经过验证和批准的基础设施变更才会提交给主干分支,以此防止错误和对运行环境的不正确修改。代码审查不一定需要完全由人来完成,该过程还可以运行自动化工具,例如代码linter[5]、静态代码分析和安全工具。
注 一些用于代码和漏洞分析的自动化工具在第4章中介绍。
代码审查长久以来就被认为是软件开发最佳实践的关键部分。GitOps的核心前提是:用于应用程序代码的代码审查方式,也应该同样严格地用于应用程序运行环境的变更。
1.2.4 Git拉取请求
Git版本控制系统提供了一种机制,在这种机制中,建议的更改可以提交到分支或复刻(fork),然后通过拉取请求与主干分支合并。2005年,Git引入了request-pull命令,此命令生成所有更改的可读摘要,该摘要可以人为地以邮件形式发送给项目维护人员。拉取请求收集对仓库文件的所有更改,并通过差异的展示供代码审查和批准。
拉取请求可用于强制执行合并前的代码审查。在拉取请求合并到主干分支之前,可以设置控制以要求特定的测试或审批。与代码审查一样,拉取请求是软件开发生命周期中一个软件工程师早已熟练使用的过程。
图1.6展示了典型的拉取请求生命周期:
1.开发人员创建一个新分支并开始处理更改。
2.当更改准备就绪后,开发人员会发送拉取请求以进行代码审查。
3.团队成员审查拉取请求并在必要时进一步提出更多的更改请求。
4.开发人员不断在分支中进行更改,直到拉取请求获得批准。
5.项目维护者将拉取请求合并到主干分支中。在合并后,用于拉取请求的分支可能会被删除。
图1.6 拉取请求生命周期允许多轮代码审查和修订,直到更改获得批准。之后可以将更改合并到主干分支,并删除拉取请求的分支
当用于基础设施的变更审查时,该审查步骤会特别有趣。创建拉取请求后,项目维护人员会收到通知并审查提议的更改。因此,审阅者提出问题、获得答案,并可能要求进行更多更改。这些信息通常被存储以供将来参考,因此,拉取请求现在是基础设施变更的活文档。一旦发生事故,就能直接找出谁进行了变更以及为何应用变更。