GitOps是软件交付的近期热门趋势,遵循并扩展了DevOps、基础架构即代码和CI/CD等趋势。GitOps的优势可简要概括如下:审计变更的自由持续集成和交付更好地控制变更管理然而,现实情况是构建GitOps管道并非易事,涉及许多大大小小的决策变更给实施工作带来很多麻烦。我们将这些决策称为“GitOps架构”,它可能会在实施过程中带来许多挑战。好处是,通过一些规划和经验,可以大大减少过渡到GitOps交付模型的痛苦。在本文中,我将通过一家公司的故事来解释其中的一些挑战。该公司已经从一家采用GitOps的小型、零散的初创公司发展成为一家监管良好的跨国企业。虽然这种加速增长很少见,但它确实反映了大型组织中许多团队从概念验证到最小可行产品再到成熟系统的经历。简单的开始如果您刚刚开始,最简单的事情就是创建一个Git存储库并将您需要的所有代码放入其中。这些可能包括:应用程序代码用于构建应用程序镜像的Dockerfile一些CI/CD管道代码(例如GitLabCI/CD或GitHubActions)Terraform用于配置运行应用程序所需的资源此外,所有更改都直接对master进行更改,因此更改可以直接生效。这种方法的主要优点是您拥有单一参考点并且所有代码都紧密集成。如果您的所有开发人员都得到完全信任并且速度就是一切,那么这种方法将继续有效。不幸的是,随着您的业务增长,这种方法的缺点很快就会显现出来。首先,随着越来越多的代码被添加到代码库中,代码库的大小会让工程师感到困惑,因为他们会遇到更多必须解决的变更之间的冲突。如果团队大幅增长,随之而来的重新分配或合并可能会导致进一步的混乱。其次,如果你需要单独控制管道运行,你会遇到困难。有时您只想快速测试对代码的更改,而不是部署以实现完整的端到端交付。这种方法会产生越来越多的问题,需要以整体方式解决,并且随着这些变化的发生,它们可能会影响其他人的工作。第三,随着您的成长,您可能希望工程师和团队之间的责任界限更加细化。这可以通过单个repo来实现,而repo通常是一个更干净、更干净的边界。SeparateRepository随着业务的增长,pipeline会越来越拥挤,merge也会变得痛苦。此外,您的团队需要专业化,将不同的职责分配给不同的成员。所以你需要分叉出Repo。在这一点上,你首先要面对很多决定,比如repo应该如何分离?您是否需要为应用程序代码创建一个单独的存储库?看起来合理吗?然后将Docker构建在一起?这种分离真的没有意义。团队的所有Terraform代码如何?它应该在新的回购协议中吗?听起来很有道理,但是:新创建的中央“平台”团队要控制AWS访问中核心IAM(身份和访问管理)规则的定义,团队RDS配置代码也包含在内,开发团队需要调整经常。因此,您决定将Terraform分成两个存储库:一个“平台”存储库和一个“特定于应用程序”的存储库。这带来了另一个挑战,因为您现在还需要分离Terraform的状态文件。这不是无法解决的问题,但不是您习惯的快速功能交付,因此产品经理将不得不解释为什么功能请求比以前花费的时间更长。不幸的是,这些GitOps决策没有既定的最佳实践或模式。分离的问题不止于此。以前,在管道中构建的组件之间的协调是微不足道的(因为所有需要的组件共存),现在您必须协调存储库之间的信息流。例如:当构建一个新的Docker镜像时,这可能需要在集中式平台repo中触发部署,将新的镜像名称作为触发器的一部分传递。同样,这些不是无法解决的问题,但这些挑战在构建GitOps管道的早期更容易实施。后来,当程序、政策和流程更加成熟时,需要更多的时间来进行更改。分布式与集中式您的业务在增长,您正在构建越来越多的应用程序和服务。越来越明显的是,您在构建和部署应用程序时需要某种结构上的一致性。中央平台团队需要努力执行这些标准。但是您可能会遇到开发团队的反对意见,他们认为与DevOps和GitOps之前的集中式IT相比,他们被赋予了更多的自主权和控制权。如果以上内容对您来说听起来很熟悉,那可能是因为GitOps与应用程序架构世界中关于单体应用程序与微服务的争论存在相似之处。正如您在这些争论中看到的那样,随着系统的成熟、规模和范围的增加,分布式IT和集中式IT之间的紧张关系出现得越来越频繁。在某种程度上,您的GitOps进程就像任何其他分布式系统一样,如果您设计不当,一个部分的问题可能会产生无法预料的问题。环境 环境在您决定分离存储库的同时,您意识到您需要一种一致的方式来管理不同的部署环境。直接推出不再可行,因为需要QA团队在上线前测试更改。现在您需要在测试和QA环境中为您的应用程序镜像指定不同的Docker标签,并且您可能还希望在不同的环境中启用不同的实例大小或复制功能。您如何在源代码中管理这些不同环境的配置?更直接的方法是为每个环境创建一个单独的Git存储库(例如:super-app-dev、super-app-qa、super-app-live)。正如我们在上面划分Terraform代码时所看到的,分离repo具有“清洁度”的好处。然而,很少有人最终喜欢这个解决方案,因为大多数团队不具备Git知识和专业知识来移植不同repo之间的更改。更复杂的是,repos之间肯定会有很多重复的代码,而且随着时间的推移也会有很多偏差。如果你想把东西放在一个单一的repo中,你至少有三个选择:每个环境一个目录每个环境一个分支一个标签同步步骤选项如果你严重依赖YAML生成工具或模板,你可以考虑另一种方式。例如,Kustomize强烈鼓励基于目录的环境分离。如果您使用原始YAML,分支或标记方法将更适合您。运行时环境粒度然而,在您的运行时环境中,您可以选择您想要的分离级别。在集群级别,如果您使用的是Kubernetes,您可以选择:一个集群来管理所有环境每个环境一个集群每个团队一个集群在极端情况下,您可以将所有环境放在一个集群中间。不过,通常情况下,在大多数组织中至少有一个单独的集群用于生产。一旦您牢记集群策略,在命名空间级别,您仍然有以下选择:每个环境一个命名空间每个应用程序/服务一个命名空间每个工程师一个命名空间每个构建一个命名空间命名空间平台团队通常以“dev”、“在意识到他们想要更精细地区分团队的工作之前,测试”、“prod”命名空间设置。您还可以混合搭配这些选项-例如,为每个工程师提供一个“桌面测试”命名空间,为每个团队提供一个命名空间。总结我们在这里仅简要介绍了成熟的GitOps流程所需的决策领域。如果你的企业真的成长为那个跨国企业,你也可以考虑RBAC/IAM等需求。很多时候,推出GitOps感觉像是一项投资,但最终可能不会产生令人满意的输出。但在GitOps之前,团队经常会遇到混乱和延迟,因为没有人确定任何事情应该是什么状态。这些会导致二次成本,因为审计员会进行抽查,而由于意外和未记录的变更而造成的中断会占用员工的大量注意力,这是一笔高昂的成本。然而,随着GitOps流程的成熟,好处会成倍增加,解决许多预先存在的问题。但通常情况下,您面临着更快发挥GitOps流程优势的压力。目前GitOps面临的最大挑战是没有既定的模式或最佳实践来指导您的选择。GitOps顾问通常只是指导团队找到最适合自己的解决方案,并根据经验引导团队朝某些方向发展。但我观察到的是,因为看起来“太复杂”而在早期被放弃的选择往往后来会后悔。这并不意味着你应该直接跳到为每个构建创建一个命名空间,为每个团队创建一个Kubernetes集群,原因有二:每次你增加GitOps架构的复杂性,你最终都会增加一个可行的GitOps解决方案你可能真的永远不需要这个设置在我们接受该领域的有效方法之前,正确的GitOps架构将永远是一门艺术,而不是一门科学。
