如何处理基于Git特性分支工作流的动态环境?

35次阅读
没有评论

问题描述

在一个系统中,包含了2个前端应用程序A和B(都是JavaScript/Angular),3个后端应用程序C、D和E(主API和两个微服务,都使用Go语言),以及MongoDB作为F。团队规模不断扩大,目前有10名开发人员。同时,团队正在开发2到3个新的主要功能。由于只有两个预生产环境,因此很难测试/展示同时正在构建的不同功能(还需要测试修复的bug和热修复等)。团队使用Git,并尝试遵循Git分支模型(在这里可能不相关)。为了简化问题,我们可以假设每个代码仓库都有自己的Dockerfile,以创建一个完全可用的容器。
开发人员想要实现的目标是:使得发布/切换到开发人员正在开发的特性分支变得非常简单(只需一个命令),从而使得该特性分支在一个动态创建的环境中可用。此外,希望能够通过URL轻松访问版本,例如 https://a166.preview.example.com,其中a是应用程序名称,166是应用程序版本(或分支名称)。

解决方案

在这里,我们将讨论一种方法来实现在特性分支上动态创建环境的需求,并通过Git特性分支的CI/CD流程来达到这一目标。

请注意以下操作可能会涉及版本差异,具体操作前请做好备份。

使用Review Apps的方法

一种通用的方法是借鉴Gitlab和Heroku提供的”Review Apps”功能,它依赖于一个CI/CD系统,在每个分支上运行流水线,并将分支名称作为环境变量传递给构建过程。你可以使用这个分支名称来对基础架构资源进行命名空间划分。
以下是一种实现方式,以Kubernetes为例,但同样适用于其他部署方法:
1. 在部署Docker镜像时,通常会为部署命名,例如:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
# ...
  1. 使用一些预处理工具(如Jinja、envsubst等)或工具(如Helm),可以在流水线过程中将分支名称传递给资源,使资源在创建时包含分支名称:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-${BRANCH_NAME}
# ...

通过这种方式,不同分支的部署不会相互干扰,它们的资源是隔离的。

  1. 对于API或Web应用程序,你可能希望有一种DNS名称和负载均衡器的机制。在Kubernetes中,可以使用Ingress和DNS控制器来轻松处理这个问题。
    以下是在AWS CloudFormation中的示例,创建一个特定于分支的DNS记录:
AWSTemplateFormatVersion: '2010-09-09'
Parameters:
  Branch:
    Type: String
  Environment:
    Type: String
  Zone:
    Type: String
Resources:
  # 省略了ALB资源...
  Route53:
    Type: AWS::Route53::RecordSet
    Properties:
      Name: !Sub
        - "my-app-${Branch}.${Environment}.${Zone}"
      HostedZoneName: !Ref Zone
      Type: A
      AliasTarget:
        HostedZoneId: !GetAtt ALB.CanonicalHostedZoneID
        DNSName: !GetAtt ALB.DNSName

这里我们创建了一个特定于分支的DNS记录,它会解析到一个负载均衡器,该负载均衡器应该指向由流水线部署的该分支的容器。这样,每个特性分支都会有一个专用的URL(例如 https://my-app-my-feature.dev.example.com),供开发人员进行测试和展示。

考虑事项

清理

当你合并或删除分支时,如果不进行一些清理,那些容器和DNS记录将会一直存在。你需要设置一些清理机制,可以定期运行一个简单的清理脚本,或者可以使用git服务器的Webhooks,在事件发生时删除相关资源。

数据库

一些资源可能不适合每个分支都部署,虽然这应该是例外而不是常规。你可能不希望在每次分支创建时都部署一个新的数据库(除非你有一个良好的模式管理工具和数据库填充脚本)。可以让所有部署都连接到同一个数据库,确保对模式的任何更改在至少一版本之前是向后兼容的。

在考虑上述方法时,需要根据具体情况和团队的工作流程进行调整。使用这些方法,开发人员可以轻松地在动态创建的环境中测试和展示他们正在开发的特性分支,从而提高开发效率和团队协作。

正文完