容器镜像版本控制的最佳实践

80次阅读
没有评论

问题描述

想要了解关于容器镜像版本控制的最佳实践,并且对于现有的最佳实践指南还存在一些模糊不清的地方。用户理解大多数容器镜像使用稳定的版本控制,当框架、包、库等更新时,版本标签将保持不变,但是用户不清楚这种策略如何确保从镜像部署的容器是一致的。例如,如果用户今天构建了一个标签为v1.0.0的镜像,然后下个月镜像更新了包括框架、包、库等的更新,但是应用程序保持不变,根据稳定版本控制策略,新的镜像将保持标签为v1.0.0。在这种策略下,用户如何确保一致部署相同版本的镜像?开发人员、测试环境和生产环境都可能认为他们使用的是相同版本的镜像,因为标签仍然设置为v1.0.0,但是底层框架、包和库的更改可能会在环境之间引入不稳定性,而这些更改是所有人都不知道的。如果有一个运行多个容器实例的集群,这种情况可能会更糟糕。另外,框架、包和库可能在父镜像中,而应用程序镜像本身没有任何更改。虽然可以在应用程序镜像和包含框架、包和库的父镜像的标签中包含构建号,但是这样做会增加很大的维护负担,因为每次父镜像更新时,都需要为应用程序镜像创建一个新的Dockerfile,以便父镜像的标签现在包含构建号,例如from parent-image:v1.0.0-build123。用户想知道是否有更好的策略来解决这个问题,或者是否接受在使用相同稳定版本标签的镜像之间存在一些差异。用户目前没有使用Kubernetes,但将来可能会使用,因此希望选择一个适用于Kubernetes的版本控制策略,并确保在节点上部署的容器实例从相同的镜像版本中没有“隐藏”的差异。

解决方案

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

方案1

对于可以在未来重新构建并接收安全更新的内容,通常希望依赖于可变但稳定的标签。这在没有一种自动更新Dockerfile的方式时尤为重要。但是,如果您控制构建流程的各个端点,您可能希望依赖于摘要以实现相对可重复的构建,并在基础镜像流程完成后自动注入该摘要。
一般来说,Docker标签中的语义版本控制是通过构建一个持久的标签来处理的,该标签在图像创建者有意不更改的情况下保持不变。因此,当1.0.0在git中发布并打上标签时,该git标签不会更改,并且生成的镜像为v1.0.0,也永远不会更改(根据策略)。并且通过推送多个标签,同一构建还会推送v1.0v1。然后,当1.0.1在git中打上标签时,将构建镜像v1.0.1,并修改v1.0v1的标签指向该新镜像。
这种语义版本控制策略允许其他人在他们的Dockerfile中依赖所需的版本,例如FROM base-image:v1,这样他们将获得次要更新、错误修复和安全补丁,而无需修改Dockerfile,他们只需要定期重建和拉取更新的基础镜像。
当上游进行重大更改时,他们在git中发布2.0.0,为其镜像打上标签v2.0.0v2.0v2。任何依赖于v1的人在更新Dockerfile以使用新的主要版本之前不会受到该重大更改的影响。

方案2

为了确保部署一致的镜像,最稳定的方法是使用摘要而不是标签。摘要类似于容器镜像的git sha。这样可以确保如果有人上传一个新的镜像并使用现有版本标签进行标记,无论是意外还是恶意,您都将继续拉取已知的良好镜像。缺点是摘要不够用户友好。
为了确保部署一致的镜像,最稳定的方法是使用摘要而不是标签。摘要类似于容器镜像的git sha。这样可以确保如果有人上传一个新的镜像并使用现有版本标签进行标记,无论是意外还是恶意,您都将继续拉取已知的良好镜像。缺点是摘要不够用户友好。
以下是两种解决方案的比较:
| 方案 | 优点 | 缺点 |
| — | — | — |
| 方案1 | – 可以依赖于可变但稳定的标签
– 可以通过推送多个标签来支持语义版本控制
– 允许其他人依赖所需的版本 | – 需要定期重建和拉取更新的基础镜像
– 无法避免在更新Dockerfile之前受到重大更改的影响 |
| 方案2 | – 确保部署一致的镜像
– 避免意外或恶意的镜像更改 | – 摘要不够用户友好
– 无法接收更新的镜像 |
根据您的具体需求和控制能力,您可以选择适合您的方案。如果您希望依赖于可变但稳定的标签,并且能够自动更新Dockerfile,那么方案1可能更适合您。如果您更关注部署一致性,并且不介意摘要不够用户友好,那么方案2可能更适合您。

正文完