在CI流水线中解决自动化测试和构建、单元测试和Docker镜像的冲突

57次阅读
没有评论

问题描述

在设置CI流水线时遇到了困惑,因为每个人给出的答案都不一样。用户的技术栈包括以下内容:
– Django API服务
– React Admin Portal服务
– React Client Portal服务
– PostgreSQL
– Redis
– Azure Kubernetes Services
– Azure DevOps Pipelines与Microsoft Hosted Agent

用户最初根据一些建议,认为CI流水线应该包括以下步骤:
1. 构建服务。
2. 运行单元测试。
3. 如果通过,将构建内容复制到Docker镜像中。
4. 将Docker镜像推送到容器注册表。
5. 在类似生产环境的Kubernetes中部署镜像(使用Kind、Minikube等)在流水线虚拟机中(Azure DevOps术语中的”Hosted Agent”)。
6. 运行集成测试。
7. 运行E2E/Selenium测试。
8. 如果通过,将特性分支合并到生产环境。

然而,用户在与其他人讨论时得到了不同的答案,其中一个人说:

单元测试 > 集成测试 > E2E测试。在每个步骤中尽可能多地进行测试,但不要惹恼开发人员。并行测试更好,因为可以减少时间。如果任何一种测试失败,流水线将中断,你只能在应用程序运行之前(单元测试、功能测试)或编译和部署之后(集成测试/E2E测试)运行测试。此外,不要将编译后的代码复制到容器中,这是一个反模式和不良实践。Dockerfile应该包含整个构建过程,并且一旦构建完成就应该保持不变。将代码复制到容器中等同于将其传递给同事并假设它将在他们的笔记本电脑上运行。使用多阶段构建和包含sdk/build-kit/其他内容的开发容器是第一步,只包含运行所需组件的运行时容器是第二步。如果平台提供商没有提供它们-.net、java、python等(它们都有)-你可以从相同的基础容器构建它们,这样可以标准化构建和运行时环境。使用多阶段Dockerfile并组合以减少步骤,以使容器保持精简。

换句话说,他的建议是:
1. 在Docker镜像中构建服务。
2. 在Docker镜像中运行单元测试。
3. 如果通过,将镜像部署到类似生产环境的Kubernetes中(使用Kind、Minikube等)在流水线虚拟机中(Azure DevOps术语中的”Hosted Agent”)。
4. 运行集成测试。
5. 运行E2E/Selenium测试。
6. 如果通过,将镜像推送到容器注册表并将特性分支合并到生产环境。

这与其他一些答案相矛盾,例如:

永远不要在Docker镜像中构建,因为这意味着我们必须在容器中安装开发工具包。生产环境中的任何Docker容器都不应该包含这些工具包,出于安全考虑。我可以理解这两种方法的价值。

用户希望对构建、单元测试和Docker镜像的过程有更多的澄清和建议。

解决方案

请注意以下操作注意版本差异及修改前做好备份。

方案1

根据用户的技术栈和需求,以下是一个可能的解决方案:
1. 在CI流水线中,首先构建服务。这可以通过使用Dockerfile来构建Docker镜像来实现。Dockerfile应该包含整个构建过程,并且一旦构建完成就应该保持不变。这可以避免将开发工具包安装到生产环境的Docker容器中。
2. 在构建的Docker镜像中运行单元测试。这可以通过在Dockerfile中添加适当的命令来实现。如果单元测试通过,流水线可以继续进行下一步;如果单元测试失败,流水线可以中断。
3. 将构建的Docker镜像部署到类似生产环境的Kubernetes中。这可以使用Kind、Minikube等工具在流水线虚拟机中进行部署。部署后,可以进行集成测试和E2E/Selenium测试。
4. 运行集成测试和E2E/Selenium测试。这些测试可以在部署的Kubernetes环境中运行,以确保服务在集成和端到端方面的正确性。
5. 如果所有测试通过,将构建的Docker镜像推送到容器注册表,并将特性分支合并到生产环境。

这个解决方案结合了两种不同的观点,既保证了构建和测试的灵活性,又避免了在Docker镜像中安装开发工具包的安全问题。

方案2

另一种方法是使用多阶段构建来减少Docker镜像的大小,并确保只包含运行所需的组件。以下是一个可能的解决方案:
1. 在CI流水线中,使用多阶段构建来构建服务。多阶段构建可以将构建过程分为多个阶段,每个阶段都可以使用不同的基础镜像和构建工具。第一个阶段可以包含开发工具包和构建工具,用于构建服务。第二个阶段可以使用更轻量级的基础镜像,并只包含运行所需的组件。
2. 在构建的Docker镜像中运行单元测试。这可以通过在Dockerfile中添加适当的命令来实现。如果单元测试通过,流水线可以继续进行下一步;如果单元测试失败,流水线可以中断。
3. 将构建的Docker镜像部署到类似生产环境的Kubernetes中。这可以使用Kind、Minikube等工具在流水线虚拟机中进行部署。部署后,可以进行集成测试和E2E/Selenium测试。
4. 运行集成测试和E2E/Selenium测试。这些测试可以在部署的Kubernetes环境中运行,以确保服务在集成和端到端方面的正确性。
5. 如果所有测试通过,将构建的Docker镜像推送到容器注册表,并将特性分支合并到生产环境。

这个解决方案使用多阶段构建来减少Docker镜像的大小,并确保只包含运行所需的组件。这可以提高镜像的性能和安全性。

以上是两种可能的解决方案,用户可以根据自己的需求和偏好选择适合自己的方法。

正文完