有关对容器映像进行标记和版本控制的建议Recommendations for tagging and versioning container images

将容器映像推送到容器注册表,然后部署这些映像时,需要为映像标记和版本控制制定一个策略。When pushing container images to a container registry and then deploying them, you need a strategy for image tagging and versioning. 本文介绍两种方法,其中的每种方法在容器生命周期内都适用:This article discusses two approaches and where each fits during the container lifecycle:

  • 稳定标记 - 可重复使用的标记,例如,这些标记可指示类似于 mycontainerimage:1.0 的主要版本或次要版本。Stable tags - Tags that you reuse, for example, to indicate a major or minor version such as mycontainerimage:1.0.
  • 唯一标记 - 对要推送到注册表的每个映像使用不同标记,例如 mycontainerimage:abc123Unique tags - A different tag for each image you push to a registry, such as mycontainerimage:abc123.

稳定标记Stable tags

建议:使用稳定标记维护容器版本的基础映像。Recommendation: Use stable tags to maintain base images for your container builds. 请避免在部署中使用稳定标记,因为这些标记会持续接收更新,并可能导致生产环境出现不一致情况。Avoid deployments with stable tags, because those tags continue to receive updates and can introduce inconsistencies in production environments.

稳定标记意味着开发人员或生成系统可以持续提取特定的标记,从而持续获取更新。Stable tags mean a developer, or a build system, can continue to pull a specific tag, which continues to get updates. “稳定”并不意味着内容已冻结。Stable doesn't mean the contents are frozen. 相反,“稳定”表示该映像应该根据该版本的意图保持稳定。Rather, stable implies the image should be stable for the intent of that version. 为了保持“稳定”,可对映像进行维护,以应用安全修补程序或框架更新。To stay "stable", it might be serviced to apply security patches or framework updates.


某个框架团队交付了版本 1.0。A framework team ships version 1.0. 他们知道,将来他们将会提供更新,其中包括次要更新。They know they'll ship updates, including minor updates. 为了支持给定主要版本和次要版本的稳定标记,它们创建了两组稳定标记。To support stable tags for a given major and minor version, they have two sets of stable tags.

  • :1 - 主要版本的稳定标记。:1 - a stable tag for the major version. 1 表示“最新的”1.* 版本。1 represents the "newest" or "latest" 1.* version.
  • :1.0 - 版本1.0 的稳定标记,可让开发人员绑定到 1.0 的更新,而不会在 1.1 发布时前滚到 1.1。:1.0- a stable tag for version 1.0, allowing a developer to bind to updates of 1.0, and not be rolled forward to 1.1 when it is released.

该团队还使用了 :latest 标记,无论当前主要版本是什么,该标记都会指向最新的稳定标记。The team also uses the :latest tag, which points to the latest stable tag, no matter what the current major version is.

有基础映像更新可用,或者发布了框架的任何类型的维护版本时,使用稳定标记的映像将更新到最新摘要(代表该版本的最新稳定版本)。When base image updates are available, or any type of servicing release of the framework, images with the stable tags are updated to the newest digest that represents the most current stable release of that version.

在这种情况下,会继续维护主要和次要标记。In this case, both the major and minor tags are continually being serviced. 在基础映像方案中,这使得映像所有者可以提供经过维护的映像。From a base image scenario, this allows the image owner to provide serviced images.

删除未标记的清单Delete untagged manifests

如果更新具有稳定标记的映像,则以前标记的图像将取消标记,这会导致映像变成孤立映像。If an image with a stable tag is updated, the previously tagged image is untagged, resulting in an orphaned image. 上一个映像的清单和唯一层数据将保留在注册表中。The previous image's manifest and unique layer data remain in the registry. 若要维护注册表大小,可定期删除因稳定映像更新而生成的未标记清单。To maintain your registry size, you can periodically delete untagged manifests resulting from stable image updates. 例如,自动清除早于指定持续时间的未标记清单,或者为未标记的清单设置保留策略For example, auto-purge untagged manifests older than a specified duration, or set a retention policy for untagged manifests.

唯一标记Unique tags

建议:对部署使用唯一标记,尤其是可在多个节点上缩放的环境中。Recommendation: Use unique tags for deployments, especially in an environment that could scale on multiple nodes. 你可能想要特意部署一致的组件版本。You likely want deliberate deployments of a consistent version of components. 如果容器重启或者业务流程协调程序横向扩展了多个实例,则主机不会意外地提取与其他节点不一致的较新版本。If your container restarts or an orchestrator scales out more instances, your hosts won't accidentally pull a newer version, inconsistent with the other nodes.

唯一标记仅仅表示推送到注册表的每个映像具有唯一的标记。Unique tagging simply means that every image pushed to a registry has a unique tag. 不会重复使用这些标记。Tags are not reused. 可以遵循多种模式来生成唯一标记,其中包括:There are several patterns you can follow to generate unique tags, including:

  • 日期时间戳 - 此方法相当常见,因为使用它可以清楚地判断映像的生成时间。Date-time stamp - This approach is fairly common, since you can clearly tell when the image was built. 但是,如何将它关联到生成系统呢?But, how to correlate it back to your build system? 是否需要查找同时完成的生成?Do you have to find the build that was completed at the same time? 处于哪个时区?What time zone are you in? 所有生成系统是否已校准为 UTC 时间?Are all your build systems calibrated to UTC?

  • Git 提交 - 在开始支持基础映像更新之前可以使用此方法。Git commit - This approach works until you start supporting base image updates. 如果基础映像更新已发生,则会使用与上一生成相同的 Git 提交来启动生成系统。If a base image update happens, your build system kicks off with the same Git commit as the previous build. 但是,基础映像包含新内容。However, the base image has new content. Git 提交通常提供半稳定标记。In general, a Git commit provides a semi-stable tag.

  • 清单摘要 - 推送到容器注册表的每个容器映像关联到某个清单,该清单由唯一的 SHA-256 哈希或摘要标识。Manifest digest - Each container image pushed to a container registry is associated with a manifest, identified by a unique SHA-256 hash, or digest. 尽管摘要是唯一的,但它很长且难于阅读,并且与生成环境不相关联。While unique, the digest is long, difficult to read, and uncorrelated with your build environment.

  • 生成 ID - 这可能是最佳选项,因为此 ID 可能是增量式的,使你能够关联到特定的生成来查找所有项目和日志。Build ID - This option may be best since it's likely incremental, and it allows you to correlate back to the specific build to find all the artifacts and logs. 但与清单摘要一样,用户很难阅读它。However, like a manifest digest, it might be difficult for a human to read.

    如果组织使用多个生成系统,此选项的一种变通方式是使用生成系统名称作为标记的前缀:<build-system>-<build-id>If your organization has several build systems, prefixing the tag with the build system name is a variation on this option: <build-system>-<build-id>. 例如,可将 API 团队的 Jenkins 生成系统与 Web 团队的 Azure Pipelines 生成系统中的生成区分开来。For example, you could differentiate builds from the API team's Jenkins build system and the web team's Azure Pipelines build system.

锁定部署的图像标记Lock deployed image tags

最佳做法是建议你锁定任何已部署的图像标记,方法是将其 write-enabled 属性设置为 falseAs a best practice, we recommend that you lock any deployed image tag, by setting its write-enabled attribute to false. 这样做可防止无意中从注册表中删除映像并防止可能的部署中断。This practice prevents you from inadvertently removing an image from the registry and possibly disrupting your deployments. 可在发布管道中包含锁定步骤。You can include the locking step in your release pipeline.

锁定已部署的映像后,你仍可使用 Azure 容器注册表功能从注册表中删除其他未部署的映像,从而维护注册表。Locking a deployed image still allows you to remove other, undeployed images from your registry using Azure Container Registry features to maintain your registry. 例如,自动清除早于指定持续时间的未标记清单或未锁定映像,或者为未标记的清单设置保留策略For example, auto-purge untagged manifests or unlocked images older than a specified duration, or set a retention policy for untagged manifests.

后续步骤Next steps

有关本文中概念的更详细讨论,请查看博客文章 - Docker 标记:对 docker 映像进行标记和版本控制的最佳做法For a more detailed discussion of the concepts in this article, see the blog post Docker Tagging: Best practices for tagging and versioning docker images.

若要最大程度地提高 Azure 容器注册表的性能并以经济高效的方式使用它,请参阅有关 Azure 容器注册表的最佳做法To help maximize the performance and cost-effective use of your Azure container registry, see Best practices for Azure Container Registry.