解读GitOps

btqszl 2020-06-15

即将开播:6月19日,互联网银行架构师魏生谈互联网开放银行实施路径的探索与思考

解读GitOps

英国作家Aldous Huxley曾说:“速度是真正的乐趣之源。”我认为生活如此,软件领域亦然。随着DevOps以及GitOps之类辅助实践的兴起,软件从架构设计到代码被部署到生产环境的速度是越来越快。

实际上,DevOps是通过定义一组实践和文化的转变,来提高我们生成代码的速度,并保证代码的可靠性。DevOps本身只是一个广义术语,不同的组织和团队在其核心原理上开发出了各种具体的实践,其中包括:ChatOps、DevSecOps、AIOps、以及一种称为GitOps的较新的实践。

GitOps的出现和兴起,主要得益于软件开发行业对于Kubernetes的广泛采用。在各类组织向Kubernetes的迈进过程中,开发团队的逐步成长,以及对于扩展集群的管理实践会变得势在必行。因此GitOps旨在将Git和Kubernetes结合在一起,为开发人员提供某种形式的操作模型、以及基于Kubernetes的基础架构和应用程序。可以说,在Kubernetes开发的过程中,GitOps能够在确保“速度”的基础上,实现软件方案的持续交付。

下面,我们来看看GitOps的工作原理,它的启动与运行,以及如何在Kubernetes中配合使用GitOps,以团队的DevOps体验。

工作原理

GitOps秉承了DevOps的核心理念--“构建它并交付它(you built it you ship it)”。它能够让开发人员在自己所选的Git工具中,提出拉式请求,触发Kubernetes集群的部署,从而使得Git成为唯一的来源。

显然,该思想是将基于推式的管道替换为基于拉式的管道,从而使得开发人员能够直接根据其拉式请求执行部署。而一旦开发人员执行合并或打开请求,该基础结构就会在部署过程中触发一系列的事件。GitOps运算符(operator)只要检测到此类变化,就会导致另一个运算符声明的更改,并将其部署到集群之中。例如,您可以使用如下工具栈来实现GitOps:

  • 将Bitbucket作为您的Git VCS(译者注:Version Control System,版本控制系统)工具。
  • 用Docker存储您的各种镜像。
  • 用Amazon S3来存储各种Helm图表。
  • 用AWS Lambda拉取图表,并提交给集群存储库。
  • 用Weaveworks Flux检测集群存储库中的更改,并做相应的调整。

当然,在您的工具栈中,实现此类功能的实际基础架构可能会有所不同,但是其机制却是相似的。

如下是可以实现的GitOps工作流:

  • 使用Bitbucket管道之类的CI(持续集成)工具,将各种Docker镜像推送到Quay之类的托管(hosting)工具处。
  • 各种云功能函数从主存储bucket处,将不同的配置和helm图表复制到主git存储库中。
  • 诸如Weaveworks Flux之类的GitOps运算符,会根据各种配置图表去更新集群,并通过Lambda函数提取不同的helm图表。

当然,上述技术栈中所描述的每个工具都有着对应的替代方案,开发团队可以选择最适合的工具,以实现DevOps的目标。例如,同属于Atlassian套件的Jira功能就能够轻松地与Bitbucket协同发挥作用。因此,如果一个拉式请求在Bitbucket中被创建,就会自动将Jira中的问题发送到自定义的“部署”上。这将大幅简化从设计到发布的DevOps实践过程。

类似地,当考虑到通过GitOps实现的持续交付机制可能出现失败时,我们可以添加其他的监控工具,以提供急需的可见性。例如,Thundra.io可被用于监控S3触发的AWS Lambda函数,以确保在将更改提交给集群存储库时,不会发生任何故障。

同理,我们也可以利用Thundra.io的集成功能,将警报发送给Opsgenie之类的报警工具,进而通知合适的值班人员,以快速解决那些由拉式请求触发的部署所引发的任何问题。

可见,我们完全可以通过向GitOps引擎添加更多的功能,以提高GitOps实践过程中的可靠性和便利性。

给带来的Kubernetes的便利性

总的说来,GitOps能够为Kubernetes的部署提供融合、幂等、确定性和自动化等方面的功能。根据Kubernetes强大的收敛机制,它将不断尝试去改变集群的状态,让各种收敛应用都具有相同的结果。而且这些都会自动而迅速地被触发。

Kubernetes的编排器(orchestrator)会持续将各种更改应用到集群中,直到集群收敛到配置更新所定义的状态为止,也就是要满足开发人员或SRE人员所期望的配置状态。这不但适用于所有的Kubernetes资源,还能够被用到自定义资源(Custom Resource Definitions,CRD)或Kubernetes的扩展。

整个GitOps的过程始于在Git存储库中定义某个所需的状态,然后Git被定位为唯一的来源。此外,我们需要保障提交过来的更改能够与群集相配,以便标记处群集是已经收敛到了所需的状态,还是已偏离了该状态。

当期望状态与实际状态不相同时,Kubernetes中的收敛运算符会主动尝试着补足这两个状态之间的差异,即:根据那些针对Git的提交,触发更改的“差异”警报,以标识处仍然需要进一步的收敛。因此,这就意味着,所有的提交都会产生对于集群的可验证的、且幂等的更改。当然,Kubernetes也可能按需产生回滚。就其机制而言,回滚可以被看作是进一步收敛到以前的状态。

最后,如果系统中不再存在“差异”警报、或仅存在“聚合”警报,那么该机制就认为实际状态已经达到了所需的状态。实际上,我们可以使用回调、或回写事件的方法,来设置此类聚合状态。

至此,我们可以认识到:GitOps依赖于IAC(译者注:基础架构即代码)的概念。即:以编程的方式定义了基础架构,而基础架构的实际状态也会随着发生相应的变化。这种就是我们在前文中提到的基于拉式的部署方式,它与传统的基于推式的部署有所不同。

相关工具

如您所知,DevOps是一个广阔的领域,它不仅仅限于软件行业。而GitOps则只是在软件行业朝着更加敏捷、可靠的方向发展过程中,一种新兴的开发实践。更准确地说,随着技术趋势的变化,开发实践必须适应可用的技术,而GitOps是团队和组织如何跟踪技术发展,持续推进开发实践的一种优秀示例。值得一提的是,诸如Weaveworks Flux之类的运算符,可以很好地帮助您在集群启用GitOps。当然,您也可以选用Spinnaker之类的其他代替方案。

此外,考虑到持续部署可能会给生成环境带来风险,我们可以通过添加诸如Thundra.io和Opsgenie之类的工具,来对系统进行全覆盖性的测试,以减少风险点,保证一定的可观察性和事件管理能力。

总结

相关推荐