使用 `docker pull` 和 `docker push` 管理 Docker 镜像的最佳实践

了解使用 `docker pull` 和 `docker push` 管理 Docker 镜像的最佳实践。本指南涵盖了用于获取、标记和将镜像上传到注册表的有效工作流程,优化镜像大小,确保使用特定标签的可复现性,以及与 CI/CD 流水线集成。改进您的 Docker 镜像管理策略,以实现更顺畅的开发和部署。

使用 Docker Pull 和 Push 管理镜像的最佳实践

Docker 镜像将您的应用程序从笔记本电脑迁移到 CI 再到生产环境,但草率的拉取和推送习惯可能导致部署不可预测。如果您依赖浮动标签、跳过仓库身份验证检查,或在不制定命名计划的情况下推送镜像,即使每个命令都成功执行,也可能部署错误的构建版本。

这些关于使用 docker pulldocker push 管理 Docker 镜像的最佳实践,专注于可重复的标签、安全的仓库工作流程,以及可在脚本和 CI/CD 流水线中使用的简单命令。

理解 docker pull

docker pull 命令是您访问仓库中大量预构建 Docker 镜像生态系统的入口。它会从仓库下载一个镜像或特定标签到您的本地 Docker 守护进程。当您需要使用现有镜像作为自己应用程序的基础,或运行依赖特定容器镜像的服务时,这是第一步。

基本用法

使用 docker pull 最直接的方式是指定镜像名称,可选地后跟一个标签:

docker pull <image_name>[:<tag>]

示例:

  • 拉取 Ubuntu 的 latest 标签:

    docker pull ubuntu
    

    这会下载标记为 latest 的镜像,如果未指定标签,这是默认行为。请将其视为便利标签,而非生产环境的固定引用。

  • 拉取特定版本的 Alpine Linux:

    docker pull alpine:3.18
    

    这确保您获得可重复的构建环境。

  • 从特定仓库拉取镜像:

    docker pull registry.example.com/my-app:v1.2
    

    如果您使用私有仓库或 Docker Hub 以外的仓库,则需要包含仓库主机名。

docker pull 的最佳实践

  • 始终指定标签: 依赖 latest 可能导致意外行为,因为仓库所有者可以随时移动该标签。显式标签如 alpine:3.18nginx:1.25-alpine 使构建更容易重复。
  • 为生产环境使用不可变引用: 标签对人类友好,但可能被覆盖。对于严格的生产部署,使用经过测试的标签加上镜像摘要,例如 nginx:1.25-alpine@sha256:<digest>
  • 清理未使用的镜像: 定期使用 docker image prune 清理本地镜像缓存以释放磁盘空间。您拉取的镜像可能占用大量存储。
  • 理解镜像层: Docker 镜像是分层构建的。当您拉取镜像时,会下载这些层。Docker 智能地在本地缓存这些层,因此如果您拉取一个与已有镜像共享层的镜像,只会下载新层,使后续拉取更快。

理解 docker push

docker push 命令用于将本地构建或修改的 Docker 镜像上传到容器仓库。这对于与协作者共享镜像、部署到云平台或作为备份存储至关重要。

基本用法

要推送镜像,必须使用仓库的主机名、您的用户名(或组织名)、镜像名称和标签正确标记它。

docker push <image_name>[:<tag>]

前提条件:

  1. 您必须登录 到要推送的仓库,使用 docker login
  2. 镜像必须正确标记 为目标仓库。

为推送标记镜像

在推送镜像之前,您需要使用仓库中目标存储库的完整路径来标记它。标准格式是:

<registry_hostname>/<username_or_organization>/<image_name>:<tag>

如果您要推送到 Docker Hub,通常省略 registry_hostname,格式变为 <username>/<image_name>:<tag>

示例工作流程:

假设您已构建了一个名为 my-app 的镜像,并希望将其推送到您的 Docker Hub 账户(myusername),标签为 v1.0

  1. 构建您的镜像(如果尚未完成):

    docker build -t my-app .
    
  2. 为 Docker Hub 标记镜像:

    docker tag my-app:latest myusername/my-app:v1.0
    

    注意:我们将 my-applatest 构建标记到特定的仓库路径 myusername/my-app:v1.0

  3. 登录 Docker Hub:

    docker login
    

使用 Docker Hub 访问令牌或您的仓库推荐的令牌流程,而不是在自动化中输入账户密码。

  1. 推送标记的镜像:
    docker push myusername/my-app:v1.0
    

docker push 的最佳实践

  • 有意义的标记: 使用描述性标签(例如版本号、发布名称、stagingproduction),而不是仅使用 latest。这使识别和管理特定版本的镜像更容易。
  • 在有用时使用多个标签: 一个发布镜像可以同时拥有 1.4.2git-3f2a9c1 标签。版本号帮助人类理解;提交 SHA 指向源代码。
  • 扫描镜像漏洞: 在推送之前,特别是推送到公共仓库或敏感环境时,考虑使用 Docker Scout 或第三方扫描器扫描镜像中的已知漏洞。
  • 最小化镜像大小: 较小的镜像推送和拉取更快。优化您的 Dockerfile 以减少镜像大小(例如,使用多阶段构建、清理中间文件、使用最小基础镜像如 Alpine)。
  • 对敏感数据使用私有仓库: 对于专有代码或敏感配置,始终使用私有仓库并适当管理访问控制。
  • 自动化标记和推送: 将镜像标记和推送集成到您的 CI/CD 流水线中,以实现自动构建和部署。

高级场景与技巧

拉取和推送多个标签

默认情况下,docker pulldocker push 操作一个镜像引用。您可以多次标记同一个镜像 ID 并推送每个标签。某些 Docker 版本还支持 docker image push --all-tags <repository>,当您有意推送仓库的所有本地标签时。

示例:推送具有多个标签的镜像

# 添加一个指向相同镜像 ID 的 'latest' 标签
docker tag myusername/my-app:v1.0 myusername/my-app:latest

# 推送新的 'latest' 标签
docker push myusername/my-app:latest

私有仓库的身份验证

对于私有仓库(如 AWS ECR、Google GCR、Azure ACR 或自托管仓库),您需要先进行身份验证才能拉取或推送。

# Docker Hub 示例
docker login

# AWS ECR 示例(通常使用辅助命令)
aws ecr get-login-password --region <region> | docker login --username AWS --password-stdin <aws_account_id>.dkr.ecr.<region>.amazonaws.com

始终参考您特定仓库的文档以获取正确的身份验证方法。

镜像层与缓存

Docker 的分层文件系统使拉取保持高效。当您拉取镜像时,Docker 会检查其本地内容存储中已有的层,并仅下载尚未拥有的层。在 docker build 期间,当 Dockerfile 指令和输入未更改时,BuildKit 还可以重用先前构建的缓存层。

保持镜像更新

定期拉取基础镜像并重新构建您的应用程序镜像,以纳入安全补丁和更新。

# 拉取最新的基础镜像
docker pull python:3.11-slim

# 使用更新的基础镜像重新构建应用程序镜像
docker build -t myusername/my-app:v1.1 .

# 推送新版本
docker push myusername/my-app:v1.1

实用要点

对于日常工作,保持工作流程简单:拉取明确的基础镜像标签,使用版本和提交标签构建,扫描结果,使用令牌登录,然后仅推送您打算部署的引用。对于生产环境,记录通过测试的摘要,以便即使可变标签更改,也能在以后拉取相同的镜像。