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

如果直接从第三方注册表中拉取某些容器映像以 部署到 Cloud de Confiance 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 和您的 Cloud de Confiance by S3NS 部署环境位于不同的项目中时。
  5. 更新部署的清单
  6. 重新部署您的工作负载。

准备工作

  1. 安装 Google Cloud CLI。

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

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

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

    gcloud init
  4. 创建或选择 Cloud de Confiance 项目

    选择或创建项目所需角色

    • 选择项目:选择项目不需要特定的 IAM 角色,您可以选择已获授角色的任何项目。
    • 创建项目:如需创建项目,您需要 Project Creator 角色 (roles/resourcemanager.projectCreator),该角色包含 resourcemanager.projects.create 权限。了解如何授予 角色
    • 创建 Cloud de Confiance 项目:

      gcloud projects create PROJECT_ID

      PROJECT_ID 替换为您要创建的 Cloud de Confiance 项目名称。

    • 选择您创建的 Cloud de Confiance 项目:

      gcloud config set project PROJECT_ID

      PROJECT_ID 替换为您的 Cloud de Confiance 项目名称。

  5. 验证是否已为您的 Cloud de Confiance 项目启用结算功能。

  6. 启用 Artifact Registry API:

    启用 API 所需的角色

    如需启用 API,您需要拥有 serviceusage.services.enable 权限。如果您已创建项目,则可能已通过 Owner 角色 (roles/owner) 拥有此权限。否则,您可以通过 Service Usage Admin 角色 (roles/serviceusage.serviceUsageAdmin) 获得此权限。 了解如何授予角色

    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 安装文档

费用

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

识别要迁移的映像

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

识别 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
        

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

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

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

收集日志数据

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

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

  1. 在 Cloud de Confiance 控制台中,前往 Logs Explorer 页面:

    前往 Logs Explorer

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

  2. 选择 Cloud de Confiance 项目。

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

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

  5. 点击运行查询

  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 是用空格分隔的项目 ID 列表。 Cloud de Confiance 例如 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