推送和拉取映像

本页介绍了如何使用 Docker 推送和拉取容器映像。如果您要排查 Google Kubernetes Engine 中的问题,该文档还提供了有关使用 crictl 工具拉取映像的信息。

如需了解如何部署到 Google Cloud 运行时环境,请参阅部署到 Google Cloud

如需了解如何列出、标记和删除映像,请参阅管理映像

准备工作

  1. 如果目标代码库不存在,请创建新代码库
  2. 您必须至少具有代码库的 Artifact Registry Writer 访问权限。
  3. 安装 Docker(如果尚未安装)。

所需的角色

如需获得推送和拉取映像所需的权限,请让您的管理员为您授予代码库的以下 IAM 角色:

如需详细了解如何授予角色,请参阅管理对项目、文件夹和组织的访问权限

您也可以通过自定义角色或其他预定义角色来获取所需的权限。

向代码库进行身份验证

每当您使用 Docker 或其他第三方客户端与 Docker 代码库搭配使用时,都必须对代码库进行身份验证。本部分简要介绍了成功进行身份验证所需满足的条件。如需了解详细说明,请参阅为 Docker 设置身份验证

使用凭据帮助程序

对于 gcloud CLI 凭据帮助程序独立凭据帮助程序,您使用的 Artifact Registry 主机必须在 Docker 配置文件中。

Artifact Registry 不会自动将所有注册表主机添加到 Docker 配置文件中。配置了大量注册库时,Docker 响应时间会明显变慢。为了尽可能减少配置文件中的注册表数量,您需要将所需的主机添加到该文件中。

如需确认已配置哪些主机,请运行以下命令以显示配置文件的内容:

  • Linux:cat ~/.docker/config.json
  • Windows:type %USERPROFILE%\.docker\config.json

credHelpers 部分列出了已配置的 Artifact Registry Docker 主机。主机名以 -docker.pkg.dev 结尾。以下示例展示了为 gcloud CLI 凭据帮助程序配置的一些主机。

"credHelpers": {
  "asia.gcr.io": "gcloud",
  "eu.gcr.io": "gcloud",
  "gcr.io": "gcloud",
  "marketplace.gcr.io": "gcloud",
  "northamerica-northeast1-docker.pkg.dev": "gcloud",
  "us-central1-docker.pkg.dev": "gcloud",
  "us-east1-docker.pkg.dev": "gcloud",
  "us.gcr.io": "gcloud"
}

如果您要使用的主机不在列表中,请再次运行凭据帮助程序以添加主机。例如,以下命令会添加 us-west1-docker.pkg.dev

  • gcloud CLI 凭据帮助程序:

    gcloud auth configure-docker us-west1-docker.pkg.dev
    
  • 独立凭据帮助程序

    docker-credential-gcr configure-docker us-west1-docker.pkg.dev
    

使用访问令牌

对于访问令牌身份验证,您可以使用 docker login 命令生成令牌,并将其用作密码。令牌有效期为 60 分钟,因此您应在标记、推送或提取映像之前进行身份验证。

以下示例使用服务账号模拟生成访问令牌,然后对工件注册库进行身份验证。您必须拥有 Service Account Token Creator 角色 (roles/iam.serviceAccountTokenCreator) 的权限,才能以这种方式生成令牌。

Linux

gcloud auth print-access-token \
  --impersonate-service-account  ACCOUNT | docker login \
  -u oauth2accesstoken \
  --password-stdin https://LOCATION-docker.pkg.dev

Windows

gcloud auth print-access-token \
--impersonate-service-account  ACCOUNT

ya29.8QEQIfY_...

docker login -u oauth2accesstoken -p "ya29.8QEQIfY_..." \
https://LOCATION-docker.pkg.dev

如果您没有权限模拟服务账号,可以在 gcloud CLI 会话中激活服务账号,然后获取令牌。如需了解详情,请参阅设置访问令牌身份验证的说明。

使用服务账号密钥

对于服务账号密钥,您可以将该密钥作为密码与 docker login 命令搭配使用。

例如,以下命令使用文件 key.json 中的 base64 编码的服务账号密钥对 us-west1-docker.pkg.dev 进行身份验证。

Linux

cat key.json | docker login -u _json_key_base64 --password-stdin \
https://us-west1-docker.pkg.dev

Windows

docker login -u _json_key_base64 --password-stdin https://us-west1-docker.pkg.dev < key.json

如需了解详情,请参阅设置服务账号密钥身份验证的说明。

推送映像

代码库模式:标准

如需将本地映像推送到标准 Docker 代码库,请使用代码库名称标记该映像,然后再推送映像。

如果您的 Artifact Registry Docker 代码库启用了标记不可更改性,则标记必须始终引用代码库中的同一映像摘要。您无法对推送到代码库的同一图片的其他版本使用该标记。如需详细了解映像摘要、标记和标记不可变性,请参阅容器映像版本

对于大图片,存在以下限制:

上传时间
如果您使用访问令牌向 Artifact Registry 进行身份验证,令牌仅有效 60 分钟。如果您预计上传时间超过 60 分钟,请使用其他身份验证方法
图片大小
工件大小上限为 5 TB。
Artifact Registry 不支持 Docker 分块上传。某些工具支持通过分块上传或单一上传来上传大型映像。您必须使用单一上传将映像推送到 Artifact Registry。

为本地图片添加标记

  1. 确保您已对代码库进行身份验证

  2. 确定图片的名称。完整映像名称的格式为:

    LOCATION-docker.pkg.dev/PROJECT-ID/REPOSITORY/IMAGE
    

    替换以下值:

    • LOCATION 是存储映像的代码库所在的单区域或多区域位置
    • PROJECT-ID 是您的 Google Cloud 控制台项目 ID。 如果您的项目 ID 包含英文冒号 (:),请参阅网域级项目
    • REPOSITORY 是存储了映像的代码库的名称。
    • IMAGE 是映像的名称。该名称可能与映像的本地名称不同。

    例如,假设一个映像具有以下特征:

    • 代码库位置:us-west1
    • 代码库名称:my-repo
    • 项目 ID:my-project
    • 本地图片名称:my-image
    • 目标映像名称:test-image

    本示例的此映像名称为:

    us-west1-docker.pkg.dev/my-project/my-repo/test-image
    

    如需详细了解映像名称格式(包括如何处理网域级项目),请参阅代码库和映像名称

  3. 使用代码库名称标记本地映像。

    docker tag SOURCE-IMAGE LOCATION-docker.pkg.dev/PROJECT-ID/REPOSITORY/IMAGE:TAG
    

    SOURCE-IMAGE 替换为本地映像名称或映像 ID,并将 TAG 替换为代码。如果您未指定标记,Docker 将应用默认的 latest 标记。

    如果启用了不可更改的映像标记设置,则每个映像版本的标记(包括 latest 标记)都必须是唯一的。如果代码库中的同一映像的另一个版本已使用该标记,您将无法将映像推送到该代码库。如需验证是否为代码库启用了此设置,请运行以下命令:

    gcloud artifacts repositories describe REPOSITORY \
        --project=PROJECT-ID \
        --location=LOCATION
    

    对于上一步中的示例映像,如果本地映像 my-image 位于当前目录中,请使用以下命令:

    docker tag my-image us-west1-docker.pkg.dev/my-project/my-repo/test-image
    

    如果要应用特定标记,请使用以下命令:

    docker tag SOURCE-IMAGE LOCATION-docker.pkg.dev/PROJECT-ID/REPOSITORY/IMAGE:TAG
    

    如需使用示例映像标记 staging,请在命令中添加 :staging

    docker tag my-image us-west1-docker.pkg.dev/my-project/my-repo/test-image:staging
    

将带有标记的映像推送到 Artifact Registry

  1. 确保您已对代码库进行身份验证

    如果您使用 gcloud auth configure-dockerdocker-credential-gcr configure-docker 配置了 Docker 客户端,请验证目标主机名是否在 Docker 配置文件中。

  2. 使用以下命令推送带有标记的映像:

    docker push LOCATION-docker.pkg.dev/PROJECT-ID/REPOSITORY/IMAGE
    

    此命令将推送带有 latest 标记的映像。如果要推送带有不同标记的映像,请使用以下命令:

    docker push LOCATION-docker.pkg.dev/PROJECT-ID/REPOSITORY/IMAGE:TAG
    

当您推送映像时,它会存储在指定的代码库中。

推送您的映像后,您可以执行以下操作:

  • 前往 Google Cloud 控制台查看图片。

  • 运行 gcloud 命令来查看映像的标记和自动生成的摘要:

    gcloud artifacts docker images list \
    LOCATION-docker.pkg.dev/PROJECT-ID/REPOSITORY/IMAGE [--include-tags]
    

    以下示例输出显示了被截断的映像摘要,但该命令始终返回完整的映像摘要。

     IMAGE                                                 DIGEST         CREATE_TIME          UPDATE_TIME
      us-west1-docker.pkg.dev/my-project/my-repo/my-image  sha256:85f...  2019-04-10T15:08:45  2019-04-10T15:08:45
      us-west1-docker.pkg.dev/my-project/my-repo/my-image  sha256:238...  2019-04-10T17:23:53  2019-04-10T17:23:53
      us-west1-docker.pkg.dev/my-project/my-repo/my-image  sha256:85f...  2019-04-10T15:08:46  2019-04-10T15:08:46
    

使用 Docker 拉取映像

代码库模式:标准、远程、虚拟
  1. 确保您已对代码库进行身份验证

    如果您使用 gcloud auth configure-dockerdocker-credential-gcr configure-docker 配置了 Docker 客户端,请验证目标主机名是否在 Docker 配置文件中。

  2. 如需从代码库中拉取映像,请使用以下命令:

    docker pull LOCATION-docker.pkg.dev/PROJECT-ID/REPOSITORY/IMAGE:TAG
    

    docker pull LOCATION-docker.pkg.dev/PROJECT-ID/REPOSITORY/IMAGE@IMAGE-DIGEST
    

    替换以下值:

    • LOCATION 是存储映像的代码库所在的单区域或多区域位置
    • PROJECT 是您的 Google Cloud 控制台项目 ID。 如果您的项目 ID 包含英文冒号 (:),请参阅网域级项目
    • PROJECT 是您的 Google Cloud 控制台项目 ID
    • REPOSITORY 是存储了映像的代码库的名称。
    • IMAGE 是代码库中的映像名称。
    • TAG 是您要拉取的映像版本的标记。
    • IMAGE-DIGEST 是映像内容的 sha256 哈希值。图片的每个版本都有一个唯一的图片摘要。在 Google Cloud 控制台中,点击特定映像可查看其元数据。此摘要将被列为映像摘要

    例如,假设一个映像具有以下特征:

    • 代码库位置:us-west1
    • 代码库名称:my-repo
    • 项目 ID:my-project
    • 映像名称:test-image
    • 标记:staging

    用于拉取映像的命令如下:

    docker pull us-west1-docker.pkg.dev/my-project/my-repo/test-image:staging
    

Docker 会下载指定的映像。

如果您从远程代码库请求映像,并且不存在缓存的副本,则远程代码库会从上游源下载并缓存映像。

如果您从虚拟代码库请求映像,Artifact Registry 会在上游代码库中搜索请求的映像。如果您请求的版本在多个上游代码库中都有,Artifact Registry 会根据为虚拟代码库配置的优先级设置选择要使用的上游代码库。

例如,假设某个虚拟代码库的上游代码库具有以下优先级设置:

  • main-repo:优先级设置为 100
  • secondary-repo1:优先级设置为 80
  • secondary-repo2:优先级设置为 80
  • test-repo:优先级设置为 20

main-repo 具有最高优先级值,因此虚拟仓库始终会先搜索它。

secondary-repo1secondary-repo2 的优先级均设为 80。如果请求的映像未在 main-repo 中,Artifact Registry 会接下来搜索这些代码库。由于它们具有相同的优先级值,因此如果两个代码库中都提供该版本,Artifact Registry 可以选择从任一代码库中提供该映像。

test-repo 具有最低优先级值,如果其他上游代码库都没有存储工件,则会提供存储的工件。

使用 crictl 拉取图片

crictl 是一款实用的命令行工具,可供 CRI 运行时开发者调试其运行时,而无需设置 Kubernetes 组件。如果您的 Google Kubernetes Engine 节点使用 containerd 运行时,您可以使用 crictl 从 Artifact Registry 拉取映像。

由于 crictl 主要是一种问题排查工具,因此某些 docker 命令(例如推送或标记映像)无法使用。

如需从 Artifact Registry 拉取映像,请执行以下操作:

  1. 在 Google Cloud 控制台中,转到虚拟机实例页面。

    转到“虚拟机实例”

  2. 通过 SSH 连接到您要排查问题的节点。

  3. 获取用于对代码库进行身份验证的访问令牌。

    curl -s "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token" -H "Metadata-Flavor: Google"
  4. 使用 crictl pull --credsaccess_token 值拉取映像

    crictl pull --creds "oauth2accesstoken:ACCESS_TOKEN" LOCATION-docker.pkg.dev/PROJECT-ID/REPOSITORY/IMAGE:TAG

    crictl pull --creds "oauth2accesstoken:ACCESS_TOKEN" LOCATION-docker.pkg.dev/PROJECT-ID/REPOSITORY/IMAGE@IMAGE-DIGEST

    输出如下所示:

    Image is up to date for sha256:0f25067aa9c180176967b4b50ed49eed096d43fa8c17be9a5fa9bff05933bee5

后续步骤