從第三方登錄檔遷移容器映像檔

如果您直接從第三方註冊資料庫提取某些容器映像檔,然後部署至 Google Kubernetes Engine 或 Cloud Run 等 Google Cloud 環境,則映像檔提取的速率限制或第三方服務中斷可能會中斷您的建構和部署作業。本頁說明如何找出這些映像檔,並將其複製到 Artifact Registry,以便統一管理容器映像檔。

Artifact Registry 不會監控第三方登錄,以便更新您複製至 Artifact Registry 的映像檔。如果您想將較新版本的映像檔納入管道,則必須將其推送至 Artifact Registry。

遷移作業總覽

容器映像檔遷移作業包括下列步驟:

  1. 設定前置條件
  2. 找出要遷移的圖片。
    • 搜尋 Dockerfile 檔案和部署資訊清單,找出第三方登錄資料庫的參照
    • 使用 Cloud Logging 和 BigQuery,判斷從第三方註冊中心擷取映像檔的頻率。
  3. 將已辨識的圖片複製至 Artifact Registry。
  4. 確認已正確設定登錄項的權限,尤其是當 Artifact Registry 和您的 Google Cloud部署環境位於不同專案時。
  5. 更新部署作業的資訊清單
  6. 重新部署工作負載。

事前準備

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. Install the Google Cloud CLI.

  3. If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.

  4. To initialize the gcloud CLI, run the following command:

    gcloud init
  5. Create or select a Google Cloud project.

    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

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

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  6. Make sure that billing is enabled for your Google Cloud project.

  7. Install the Google Cloud CLI.

  8. If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.

  9. To initialize the gcloud CLI, run the following command:

    gcloud init
  10. Create or select a Google Cloud project.

    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

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

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  11. Make sure that billing is enabled for your Google Cloud project.

  12. 如果您沒有 Artifact Registry 存放區,請建立存放區,並為需要存取存放區的第三方用戶端設定驗證機制
  13. 確認權限。您必須在將圖片遷移至 Artifact Registry 的專案中,具備擁有者或編輯者 IAM 角色。
  14. 匯出下列環境變數:
    export PROJECT=$(gcloud config get-value project)
  15. 確認已安裝 Go 1.13 以上版本。
    go version
    如需安裝或更新 Go,請參閱 Go 安裝說明文件
  16. 費用

    本指南使用 Google Cloud的下列計費元件:

    找出要遷移的圖片

    搜尋用於建構及部署容器映像檔的檔案,找出第三方登錄檔的參照,然後檢查您擷取映像檔的頻率。

    在 Dockerfile 中找出參照

    請在 Dockerfile 儲存的位置執行此步驟。這可能是本機檢出的程式碼所在位置,如果檔案可在 VM 中使用,則會在 Cloud Shell 中。

    在 Dockerfile 所在的目錄中執行下列指令:

    grep -inr -H --include Dockerfile\* "FROM" . | grep -i -v -E 'docker.pkg.dev|gcr.io'
    

    輸出內容如下所示:

    ./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 或 Cloud Run 資訊清單的位置執行這些步驟。這可能是在本機檢出程式碼的位置,或是在 Cloud Shell 中 (如果檔案可在 VM 中使用)。
    1. 在包含 GKE 或 Cloud Run 資訊清單的目錄中,執行下列指令:
      grep -inr -H --include \*.yaml "image:" . | grep -i -v -E 'docker.pkg.dev|gcr.io'
      輸出內容如下:
          ./code/deploy/k8s/ubuntu16-04.yaml:63: image: busybox:1.31.1-uclibc
          ./code/deploy/k8s/master.yaml:26:      image: kubernetes/redis:v1
          
      這個指令會查看目錄中的所有 YAML 檔案,並找出 image: 行。視需要調整指令,以便配合資訊清單的儲存方式
    2. 如要列出叢集中執行的映像檔,請執行下列指令:
      kubectl get all --all-namespaces -o yaml | grep image: | grep -i -v -E 'docker.pkg.dev|gcr.io'
      這個指令會傳回在所選 Kubernetes 叢集中執行的所有物件,並取得其映像檔名稱。輸出內容會類似以下內容:
          - image: nginx
            image: nginx:latest
              - image: nginx
              - image: nginx
          

    針對所有Google Cloud 專案中的所有 GKE 叢集執行上述指令,以便全面涵蓋。

    從第三方登錄檔中找出擷取頻率

    在從第三方註冊中心擷取的專案中,請使用圖片擷取頻率資訊,判斷您的使用量是否接近或超過第三方註冊中心強制執行的任何速率限制。

    收集記錄資料

    建立記錄檔接收器,將資料匯出至 BigQuery。記錄接收器包含目的地和查詢,用於選取要匯出的記錄項目。您可以查詢個別專案來建立接收端,也可以使用指令碼收集各專案的資料。

    如要為單一專案建立接收器,請按照下列步驟操作:

    1. 前往 Google Cloud 控制台的「Logs Explorer」頁面:

      前往「Logs Explorer」(記錄檔探索工具)

      如果您是使用搜尋列尋找這個頁面,請選取子標題為「Logging」的結果

    2. 選擇 Google Cloud 專案。

    3. 在「Query builder」(查詢建立工具) 分頁中,輸入下列查詢:

        resource.type="k8s_pod"
        jsonPayload.reason="Pulling"
      
    4. 將變更記錄篩選器從「過去 1 小時」變更為「過去 7 天」圖片

    5. 按一下 [Run Query] (執行查詢)。

    6. 確認結果顯示正確後,請依序點選「動作」 >「建立接收器」

    7. 在「Sink details」對話方塊中,完成下列步驟:

      1. 在「Sink Name」欄位中輸入 image_pull_logs
      2. 在「Sink 說明」中輸入 Sink 的說明。
    8. 點選「下一步」

    9. 在「Sink destination」對話方塊中,選取下列值:

      1. 在「Select Sink service」(選取接收器服務) 欄位中,選取「BigQuery 資料集」
      2. 在「選取 BigQuery 資料集」欄位中,選取「建立新的 BigQuery 資料集」,然後在隨即顯示的對話方塊中填入必要資訊。如要進一步瞭解如何建立 BigQuery 資料集,請參閱「建立資料集」。
      3. 點選「建立資料集」
    10. 點選「下一步」

      在「Choose logs to include in sink」部分,查詢會與您在「Query builder」分頁中執行的查詢相符。

    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 是 Google 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 是資料集名稱。
    以下範例顯示查詢的輸出內容。在「imageName」imageName欄中,您可以查看未儲存在 Artifact Registry 或 Container Registry 中的映像檔提取頻率。

    圖片

    將映像檔複製到 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.pkg.dev/${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.pkg.dev 上的圖片。

    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.pkg.dev/<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.pkg.dev 字串。