在 dev、qa、uat 和生产中推广 docker 图像的最佳实践

Best practices to promote docker images across dev,qa,uat and production

我们的应用程序是容器化的,并使用 docker swarm 作为编排器。我想了解我们如何将 docker 图像从开发、质量检查、uat 推广到生产。例如,如果我在 dev 中创建了一个图像 test:10 (10 是 jenkins 生成的内部版本号)。我如何将相同的图像推广到 qa、uat 和生产?我们目前正在使用 NEXUS 作为 docker 存储库。我不明白的是我将如何提取在开发环境中使用的确切图像。有人可以帮忙吗?

解决此问题的一种方法是使用 CI/CD 工具,例如 Jenkins 或什至一些 CI/CD bash 脚本,并采用某种标记策略。您可能知道,您可以不同地标记同一图像。例如,您可以构建一个 ID 为 0000 的映像,并按如下方式标记多次:

Day 1:
| TAG         | IMAGE ID |
| test:10     | 00000000 |
| test:dev-latest | 00000001 |
| test:qa-latest  | 00000001 |
| test:prod-latest| 00000001 |    

Day 2:
| TAG             | IMAGE ID |
| test:10         | 00000000 |
| test:11         | 00000001 |
| test:dev-latest | 00000001 |
| test:qa-latest  | 00000001 |
| test:prod-latest| 00000001 |

并且您的编排器可以随时等待标记新图像。这种方法理论上是有用的。但是,根据您的容器编排器特定功能,您可以稍微改进此方法以使用这些特定功能。例如,图像拉取策略,或推出和回滚功能,实施blue/green策略的功能等

您可以通过重新标记图像并推送将图像从一个 docker 图像存储库提升到另一个图像:

docker build -t my-test .
docker tag my-test your-image-repository-dev/test:10
docker login "your-image-repository-url"
docker push your-image-repository-dev/test:10
# ... deploy/test your image in dev
docker pull your-image-repository-dev/test:10
docker tag your-image-repository-dev/test:10 \
           your-image-repository-qa/test:10
docker push your-image-repository-qa/test:10

然后您将在 QA docker 图像存储库中拥有相同的图像。这对于已经通过基本级别 unit/functional/user 验收测试的图像来说是有意义的,这与没有通过的图像截然不同!这里的关键概念是重新标记和推送图像的时间。此外,为每个 docker 图像存储库指定图像拉取凭据可以帮助您限制实际可以进入特定环境的图像。

上述策略的替代方法是,您可能没有单独的 docker 图像存储库,并且可以选择更改图像名称而不是存储库。在这种情况下,您可以执行以下操作。

docker build -t my-test .
docker tag my-test your-image-repository/test:10
docker login "your-image-repository-url"
docker push your-image-repository/test:10
# ... deploy/test your image in dev
docker pull your-image-repository/test:10
docker tag your-image-repository/test:10 \
           your-image-repository/test-qa:10
docker push your-image-repository/test-qa:10

关键是在图像标签中使用某种形式的元数据来指示图像对应于部署过程的哪个步骤。有很多潜在的方法可以做到这一点,但也许首先看看 SemVer,因为它是一个有据可查且广泛使用的选项。

https://semver.org/

semver 中主要要注意的是在版本中使用 - 标记,表示某物是 "pre-release" 版本。

考虑到这一点,很容易区分生产图像和非生产图像:

  • 正式版:nginx:1.2.3
  • 非生产版本:nginx:1.2.3-10

从那里,如果需要,您可以通过使用 "dot-separated pre-release identifiers"

进一步分解非生产版本
  • 开发人员:nginx:1.2.3-dev.10
  • 问答:nginx:1.2.3-qa.10
  • uat nginx:1.2.3-uat.10

您可以使用其他标记方法,但 SemVer 有据可查、应用广泛,并且可以解决问题。

最佳做法是为每个环境设置一个单独的容器存储库。 Docker Azure 容器注册表可能不需要拉入 build/release 代理。 我已经写了一篇关于这个的文章 promoting-container-images-to-production-using-azure-devops