问题描述
最近,我的团队开始采用基于敏捷交付的Git工作流,我们使用JIRA、TeamCity和其他各种CI工具来完成流程。这个工作流在JAVA的单体应用或SOA应用中运行良好。
然而,在面向企业环境(如Openshift)的微服务交付流程中存在问题。
在Git工作流中,期望是将开发和测试完成的“feature”分支合并到“develop”分支。然而,当有多个功能正在开发时,开发人员需要一个平台来测试他刚刚构建的服务功能,然后再提交拉取请求。
在Openshift/Kubernetes中,我们暴露一个服务,假设每个基于“feature”分支构建的服务如下所示:
myapplication-MIM-158848-feature1.myco.internal.aumyapplication-MIM-158849-feature2.myco.internal.au
在内部,Openshift应该能够为测试服务分配专用的Pod,并在合并到“develop”分支后将其销毁。这种方法的另一个问题是运行集成测试或者如果服务与消费者API有依赖关系。根据“feature”分支修改服务名称不是一个好主意。
有没有人知道在基于微服务的平台中处理这种交付模型的更好方法?谢谢。
解决方案
请注意以下操作注意版本差异及修改前做好备份。
方案1
在你的CI流水线中添加一个后置构建步骤,用于创建Pod(或者更准确地说是DeploymentConfig)。具体如何创建和放置这个文件取决于你的架构。如果你的每个微服务都具有相同的端口(即所有服务都监听80或443),那么你只需要一个中央模板,然后注入名称(包含微服务名称和feature分支名称)和git源URL。该文件当然可以包含多个OpenShift对象(例如DeploymentConfig和Route)。
然后使用oc apply
命令将其应用到OpenShift上,OpenShift将构建镜像并启动Pod。
在合并到develop
分支后,添加一个后置合并步骤,以相反的方式进行操作,即对原始.yaml
的每个组件执行oc delete ...
操作。如果为每个组件添加了基于分支的标签,那么这可能是最简单的方法,这样你就不需要跟踪首先应用了哪些组件。
如果涉及到集成测试的服务具有状态,那么你确实需要为每个测试运行启动一个新的Pod/Volume。如果你的集成测试依赖于外部状态,那么你也需要以某种方式管理它。无论你如何设计解决方案,这两个方面都是真实存在的。
在这些情况下,你可能最好不要直接从各个CI流水线启动部署,而是在开始集成测试时进行“大规模”部署(即像上面描述的那样部署所有单独的微服务,但还要将当前集成测试运行的ID注入到它们所有的名称中,以确保一切都保持唯一)。
方案2
我们正在将我们在GitHub上称为OCD的Openshift持续部署设置开源化。它实际上是由git标签和git中的Helmfile yaml驱动的。由于它是由git标签驱动的,因此它对使用的分支是不可知的。它也对你使用的CI/CD工具是不可知的。
这个想法是开发人员可以通过更改git中的yaml文件来“自助式”地在Openshift上启动新的应用程序。因此,设置功能分支的开发人员可以通过简单地标记代码并更改一些yaml来启动该代码。
它可以用以下方式满足你的需求:
1. OCD从git标签(或git发布)事件构建,并创建源代码的容器镜像,并使用相同的标签对容器镜像进行标记。它不需要知道这些标签属于哪些分支。
2. 需要新的功能分支部署的团队将在git存储库中添加一个新的文件夹,其中包含构建和运行其标记代码的所有配置。
OCD是以通用Helm charts的形式实现的。一个设置了从git标签构建并使用相同标签标记镜像的BuildConfig。另一个设置了运行标记图像的DeploymentConfig。另一个管理在git中加密的Secrets。另一个管理ConfigMaps。这些都是使用Helmfile安装的,Helmfile允许在一个yaml文件中声明一组helm release。这是通过adnanh/webbook运行的,它是一个可以捕获git webhook事件并运行shell脚本的小型go应用程序。
OCD是为微服务而设计的。其思想是团队可以非常容易地启动新的服务。使用它来临时启动测试应用程序也很容易。如果从git中删除应用程序,它目前不会删除应用程序。在测试时删除应用程序只需要一个命令行。
免责声明:它目前是预发布状态,但功能完整,我们正在将自己的应用程序迁移到其中。
以上是在Openshift/Kubernetes中处理Git工作流和测试短期功能分支的两种解决方案。希望对你有帮助!