从第三方注册表迁移容器映像

如果您直接从第三方注册表中拉取某些容器映像以部署到 Trusted Cloud by S3NS 环境(例如 Google Kubernetes Engine),则映像拉取或第三方服务中断的速率限制可能会中断您的构建和部署。本页面介绍如何识别这些映像并将其复制到 Artifact Registry 中以进行整合、一致的容器映像管理。

Artifact Registry 不会监控第三方注册表,以检测您复制到 Artifact Registry 的映像的更新情况。如果您想要将较新版本的映像整合到流水线中,则必须将该映像推送到 Artifact Registry。

迁移概览

容器映像的迁移包括以下步骤:

  1. 设置前提条件
  2. 识别要迁移的映像。
    • 搜索 Dockerfile 文件和部署清单,查找第三方注册表的引用
    • 使用 Cloud Logging 和 BigQuery 确定从第三方注册表拉取映像的频率。
  3. 将识别的映像复制到 Artifact Registry。
  4. 验证注册表的权限是否配置正确,尤其是 Artifact Registry 和 Trusted Cloud by S3NS部署环境位于不同的项目中时。
  5. 更新部署的清单
  6. 重新部署您的工作负载。

准备工作

  1. Install the Google Cloud CLI.

  2. 配置 gcloud CLI 以使用您的联合身份。

    如需了解详情,请参阅 使用联合身份登录 gcloud CLI

  3. 如需初始化 gcloud CLI,请运行以下命令:

    gcloud init
  4. Create or select a Trusted Cloud project.

    • Create a Trusted Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Trusted Cloud project you are creating.

    • Select the Trusted Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Trusted Cloud project name.

  5. Verify that billing is enabled for your Trusted Cloud project.

  6. Enable the Artifact Registry API:

    gcloud services enable artifactregistry.googleapis.com
  7. 如果您没有 Artifact Registry 代码库,请创建代码库,并为需要访问该代码库的第三方客户端配置身份验证
  8. 验证您的权限。在要将映像迁移到 Artifact Registry 的项目中,您必须具有 Owner 或 Editor IAM 角色。
  9. 导出以下环境变量:
    export PROJECT=$(gcloud config get-value project)
  10. 验证是否已安装 Go 版本 1.13 或更高版本。
    go version
    如果您需要安装或更新 Go,请参阅 Go 安装文档
  11. 费用

    本指南使用 Trusted Cloud的以下收费组件:

    识别要迁移的映像

    搜索用于构建和部署容器映像的文件,以查找第三方注册表的引用,然后检查映像的拉取频率。

    识别 Dockerfile 中的引用

    在 Dockerfile 的存储位置执行此步骤。该位置可能是在本地签出代码的位置。

    在包含 Dockerfile 的目录中,运行以下命令:

    grep -inr -H --include Dockerfile\* "FROM" . | grep -i -v -E 'docker.s3nsregistry.fr'
    

    输出类似于以下示例:

    ./code/build/baseimage/Dockerfile:1:FROM debian:stretch
    ./code/build/ubuntubase/Dockerfile:1:FROM ubuntu:latest
    ./code/build/pythonbase/Dockerfile:1:FROM python:3.5-buster
    

    此命令会搜索目录中的所有 Dockerfile,并标识 "FROM" 行。根据需要调整命令,以匹配 Dockerfile 的存储方式。

    识别清单中的引用

    在存储 GKE 清单的位置执行以下步骤。该位置可能是在本地签出代码的位置。
    1. 在包含 GKE 清单的目录中,运行以下命令:
      grep -inr -H --include \*.yaml "image:" . | grep -i -v -E 'docker.s3nsregistry.fr'
      输出类似以下内容:
          ./code/deploy/k8s/ubuntu16-04.yaml:63: image: busybox:1.31
          
      此命令会查看您目录中的所有 YAML 文件,并标识 image: 行。根据需要调整命令,以匹配清单的存储方式
    2. 如需列出在集群上运行的映像,请运行以下命令:
      kubectl get all --all-namespaces -o yaml | grep image: | grep -i -v -E 'docker.s3nsregistry.fr'
      此命令会返回所选 Kubernetes 集群中运行的所有对象,并获取其映像名称。 输出类似以下内容:
          - image: nginx
            image: nginx:latest
              - image: nginx
              - image: nginx
          

    在所有Trusted Cloud 项目中对所有 GKE 集群运行上述命令,以实现全部覆盖。

    识别从第三方注册表拉取映像的频率

    在从第三方注册表拉取映像的项目中,使用映像拉取频率相关信息来确定您的用量是否接近或超过第三方注册表强制执行的速率限制。

    收集日志数据

    创建日志接收器,以将数据导出到 BigQuery。日志接收器包含目标位置以及用于选择要导出的日志条目的查询。您可以通过查询各个项目来创建接收器,也可以使用脚本来跨项目收集数据。

    如需为单个项目创建接收器,请执行以下操作:

    1. 在 Trusted Cloud 控制台中,转到 Logs Explorer 页面:

      前往 Logs Explorer

      如果您使用搜索栏查找此页面,请选择子标题为 Logging 的结果。

    2. 选择一个 Trusted Cloud 项目。

    3. 查询构建器标签页中,输入以下查询:

        resource.type="k8s_pod"
        jsonPayload.reason="Pulling"
      
    4. 将历史记录过滤条件从过去 1 小时更改为过去 7 天

    5. 点击 Run Query

    6. 验证结果正确显示后,点击操作 > 创建接收器

    7. 接收器详情对话框中,完成以下操作:

      1. 接收器名称字段中,输入 image_pull_logs
      2. 接收器说明中,输入接收器的说明。
    8. 点击下一步

    9. 接收器目标位置对话框中,选择以下值:

      1. 选择接收器服务字段中,选择 BigQuery 数据集
      2. 选择 BigQuery 数据集字段中,选择创建新的 BigQuery 数据集,然后在随即打开的对话框中填写所需信息。如需详细了解如何创建 BigQuery 数据集,请参阅创建数据集
      3. 点击创建数据集
    10. 点击下一步

      选择要包含在接收器中的日志部分中,查询与您在查询构建器标签页中运行的查询相匹配。

    11. 点击下一步

    12. 可选:选择要从接收器中过滤掉的日志。如需详细了解如何查询和过滤 Cloud Logging 数据,请参阅日志记录查询语言

    13. 点击创建接收器

      您的日志接收器已创建。

    如需为多个项目创建接收器,请执行以下操作:

    1. 打开 Cloud Shell

    2. 在 Cloud Shell 中运行以下命令:

      PROJECTS="PROJECT-LIST"
      DESTINATION_PROJECT="DATASET-PROJECT"
      DATASET="DATASET-NAME"
      
      for source_project in $PROJECTS
      do
        gcloud logging --project="${source_project}" sinks create image_pull_logs bigquery.googleapis.com/projects/${DESTINATION_PROJECT}/datasets/${DATASET} --log-filter='resource.type="k8s_pod" jsonPayload.reason="Pulling"'
      done
      

      其中

      • PROJECT-LIST 是用空格分隔的 Trusted Cloud 项目 ID 列表。例如:project1 project2 project3
      • DATASET-PROJECT 是您要存储数据集的项目。
      • DATASET-NAME 是数据集的名称,例如 image_pull_logs

    创建接收器后,数据需要一些时间才能流向 BigQuery 表,具体取决于映像的拉取频率。

    查询拉取频率

    获得构建创建的映像拉取的代表性样本后,运行查询以获取拉取频率。

    1. 转到 BigQuery 控制台

    2. 请运行以下查询:

      SELECT
        REGEXP_EXTRACT(jsonPayload.message, r'"(.*?)"') AS imageName,
        COUNT(*) AS numberOfPulls
      FROM
            `DATASET-PROJECT.DATASET-NAME.events_*`
      GROUP BY
            imageName
      ORDER BY
            numberOfPulls DESC
      

      其中

      • DATASET-PROJECT 是包含您的数据集的项目。
      • DATASET-NAME 是数据集的名称。

    将映像复制到 Artifact Registry

    通过第三方注册表确定映像后,就可以将它们复制到 Artifact Registry 中了。gcrane 工具可以帮助您执行复制过程。

    1. 创建一个文本文件 images.txt,其中包含您识别的映像的名称。例如:

      ubuntu:18.04
      debian:buster
      hello-world:latest
      redis:buster
      jupyter/tensorflow-notebook
      
    2. 下载 gcrane

        GO111MODULE=on go get github.com/google/go-containerregistry/cmd/gcrane
      
    3. 创建一个名为 copy_images.sh 的脚本以复制文件列表。

      #!/bin/bash
      
      images=$(cat images.txt)
      
      if [ -z "${AR_PROJECT}" ]
      then
          echo ERROR: AR_PROJECT must be set before running this
          exit 1
      fi
      
      for img in ${images}
      do
          gcrane cp ${img} LOCATION-docker.s3nsregistry.fr/${AR_PROJECT}/${img}
      done
      

      LOCATION 替换为代码库的区域位置

      让该脚本可执行:

        chmod +x copy_images.sh
      
    4. 运行该脚本以复制文件:

      AR_PROJECT=${PROJECT}
      ./copy_images.sh
      

    验证权限

    请确保权限已正确配置,然后再更新和重新部署工作负载。

    如需了解详情,请参阅访问权限控制文档。

    更新清单以引用 Artifact Registry

    更新 Dockerfile 和清单,以引用 Artifact Registry 而不是第三方注册表。

    以下示例展示了引用第三方注册表的清单:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
    spec:
      selector:
        matchLabels:
          app: nginx
      replicas: 2
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx:1.14.2
            ports:
            - containerPort: 80
    

    此更新后的清单版本指向 us-docker.s3nsregistry.fr 上的映像。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
    spec:
      selector:
        matchLabels:
          app: nginx
      replicas: 2
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: us-docker.s3nsregistry.fr/<AR_PROJECT>/nginx:1.14.2
            ports:
            - containerPort: 80
    

    如果有大量清单,请使用 sed 或其他工具跨多个文本文件处理更新。

    重新部署工作负载

    使用更新后的清单重新部署工作负载。

    通过在 BigQuery 控制台中运行以下查询,来跟踪新映像拉取:

    SELECT`
    
    FORMAT_TIMESTAMP("%D %R", timestamp) as timeOfImagePull,
    REGEXP_EXTRACT(jsonPayload.message, r'"(.*?)"') AS imageName,
    COUNT(*) AS numberOfPulls
    FROM
      `image_pull_logs.events_*`
    GROUP BY
      timeOfImagePull,
      imageName
    ORDER BY
      timeOfImagePull DESC,
      numberOfPulls DESC
    

    所有新映像拉取都应从 Artifact Registry 拉取并包含字符串 docker.s3nsregistry.fr