05 GitOps:开启基础架构自动化新篇章
你好,我是潘野。
前面几讲,我们一起探索了IaC的发展脉络、相关工具的原理分析以及多云异构的管理方式。
不知道你是否发现一个问题?这些内容基本都是从单一维度来审视基础架构自动化,而真正维护基础设施自动化的时候,我们还会面临其他的问题,例如持续集成与自动化部署、版本控制,文档与团队协作规范等等。
而今天我们要学习的GitOps模式,就可以把这些零散的点合理组织起来,帮我们真正落地实现基础架构自动化。
持续集成和持续部署
我们依然从一个小场景出发。
Tom和Jerry是公司平台组的工程师。有一天Tom接到一个需求,需要在AWS中部署一套业务环境。但是,当Tom快要完成时,被抽调去支援其他紧急项目,于是Jerry接手了Tom的工作。
Jerry拿着Tom用邮件发过来的Terraform代码,继续完成部署环境的任务。不过,在运行terraform apply时他发现,Tom提供的代码可能并不是最新的,因为代码中缺少一些配置,实际状态和他代码中的描述不一致。
此时Jerry犯愁了,贸然执行可能会导致整个环境损坏。所以,Jerry只能先手动更改线上环境配置,以免影响业务上线进度,等Tom从其他项目回来之后再将问题反馈给他。
上面的情况想必你并不陌生,无论我们在工作里扮演的是Tom还是Jerry,都不难发现前面例子暴露的问题。
- Terraform的代码可能有遗漏。
- 一旦Terraform代码有问题,我们可能很难回退到更改前的状态。
- 在Jerry手动更改了线上环境之后,线上环境的状态与Terraform代码中表述的不一样了。实际状态和代码描述之间的差别更大了,这让基础设施环境变得更加不一致。
很明显,用文件分享代码这种管理方式带来的问题,Terraform或者Pulumi这些工具也无法解决。Tom从紧急项目回来之后,Jerry和Tom就开始讨论如何应对。DevOps组的Mike听到两人对话,提出了用 持续集成和持续部署 的方式来管理Terraform代码。
这种方式的具体要求如下。
- Terraform的代码应该放在Git中管理,所有对环境的更改都应该通过提交Pull Request(PR)到Git仓库来完成。这个PR需要被团队其他成员审查并批准。
- 一旦PR被合并,Git仓库的变化就会通过推送API,自动送进自动化工具,并自动将新的目标状态应用到实际环境中。这通常由持续集成和持续部署(CI/CD)工具来完成。
- 选择Jenkins、GitHub Actions等适合团队使用的CI/CD的工具,这些工具将用于自动执行代码构建、测试和部署等任务。
- 在Git的log以及持续集成和持续部署的工具中会记录所有的构建、测试和部署活动,以便在出现问题时进行故障排除和根因分析。
- 监控线上环境的状态,并在检测到与Git仓库中描述的目标状态不一致时,自动修复这些不一致,或者给团队发送报警。
Mike提出来的这种基于Git的管理代码的方式,我们就称为GitOps。接下来,我再围绕GitOps里提交代码、CI/CD和安全这几个方面带你深入了解。
GitOps之Pull Request
在GitOps中,Git中的IaC代码被看成“唯一的事实来源”,因此对这个代码的所有改动都需要经过一定的测试、审核,以确保更改是正确、安全的。
这种方式不仅提高了代码质量,也增加了代码更改的透明度,能帮助团队更好地协作和管理代码。一旦PR被合并,自动化工具会检测到Git仓库的更改,并自动将新的目标状态应用到实际环境中,确保环境的一致性。
GitOps之CI/CD
现在我们可以选择的持续部署和持续集成的工具有很多,比较老牌的有Jenkins、Github自带的Github Action,还有Kubernetes社区推出的Tekton等工具。
这些持续集成的工具各有千秋,不要在工具选型上太过于纠结,根据实际情况来决定即可。比如团队成员大多熟悉Github Action,就可以选择Github Action作为持续集成的工具。
一般来说,持续集成的工具都会由Webhook与代码仓库Github或者Gitlab集成。在GitOps中,当Git仓库中有新的更改(例如,合并了一个新的Pull Request)时,Git仓库可以通过Webhook通知CI/CD工具,再由CI/CD工具拉取新的代码更改并启动构建和部署流程。
这样,Webhook就实现了Git仓库和CI/CD工具之间的实时通信,使得CI/CD能够快速响应Git仓库的更改,确保生产环境始终与Git仓库中描述的目标状态保持一致。
有些接触过GitOps的同学,可能会认为GitOps等同于CI/CD。其实并非如此,虽然CI/CD贯穿了自动化管理流程中一大部分,但是这并不意味者GitOps等于CI/CD,如果使用不当,就可能带来一些安全问题。我们这就来聊聊GitOps如何解决这方面的问题。
GitOps之安全
我们在管理基础设施的时候,难免要遇到一些需要认证的场景,比如容器的私有镜像仓库使用用户名密码方式来验证。显然,你不能在Git仓库中直接写 docker login --username=xx --password=xx
, 这会泄漏出密码和敏感信息。
那么遇到这种情况你应该怎么解决呢?我先给你分享两种常见做法。
第一种做法,使用开源安全工具 git-crypt 对Git仓库中的文件进行加密和解密。Git-crypt工作原理是在提交时自动加密文件,并在git checkout时自动解密文件。这种方式无缝地集成到Git中,使得敏感数据的保护变得易如反掌。
虽然Git-crypt这个工具很有用,但它仅限于Git中的加密解密,不能取代全面的安全策略。所以我们应该把它看作敏感数据保护方面的一个额外层次,而不是唯一的防线。
第二种做法,使用密钥管理工具,比如HashiCorp Vault、AWS Secret Manager等工具。这些工具提供了一个中心化的位置供我们存储、访问和分发密钥,并提供精准的访问控制策略,供我们限制不同用户的访问权限,为每个客户端生成独特的短期访问凭证。这些工具还支持我们对数据进行高级别的加密,并提供详细的审计日志功能,这样一来,我们就能安全地存储和管理敏感数据了。
除此之外,Git作为唯一真实数据源的同时,我们需要确保对Git仓库有适当的访问控制,防止仓库中的代码被非法更改。
Example
了解了GitOps中持续集成和持续部署,我们不妨继续思考,前面Tom和Jerry遇到的问题要怎么通过GitOps方式解决呢?
后面是一张基于GitOps的IaC过程图,你可以结合图示继续听我分析。
整个过程大致经历这五个步骤。
- Tom向 仓库 提交一个Pull Request,将AWS的EC2实例从原来的t2.micro更换成m4.xlarge。
- CI流水线会检查Tom的代码,并执行Terraform plan,将结果返回给Github的Pull Request中。
- 接下来,同组Jerry会审核代码的变化,并检查Terraform plan的输出是否如代码所写。
- 所有代码检查通过之后,Tom将PR合并进代码主分支,利用持续部署工具部署代码。
- 如果代码有问题,可以通过git revert的方式回滚代码。接下来,持续部署工具会再次运行terraform apply来完成回滚操作。
总结
今天的内容告一段落,让我们来总结一下。
GitOps是一种创建和管理基础设施的方法,其中Git被用作“事实的唯一来源”。在GitOps中,Git仓库包含环境的所有信息,并且所有更改都通过Pull Request(PR)进行。
这种方法的主要优点是 提供了一种声明性方法来管理基础设施。这意味着你只需要在Git仓库中描述你想要的环境状态,就能凭借自动化工具来实现这个状态。
此外,由于所有更改都在Git中进行版本控制,因此我们可以轻松跟踪和审计更改。这对于满足合规性要求以及故障排查方面都非常有用。
总之,GitOps提供了一种简单、可扩展和可审计的方式来管理基础设施,因此它在许多现代DevOps团队中已经成为首选的基础设施管理方法。
课程中的例子用到了GitOps的IaC管理模式,无论是基础设施的部署,还是Kubernetes的集群管理,我们都会遵循GitOps模式。在后续的课程中,我们也会将今天学到的理论知识转化成实践,敬请期待。
思考题
GitOps并不是一种万能的解决方案,它同样存在一些挑战和限制,你能想到有哪些限制吗?
欢迎你和我在评论区一起讨论。如果这一讲对你有帮助,别忘了分享给身边更多同事、朋友。