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

將容器映像檔從第三方註冊資料庫遷移至 Artifact Registry,即可整合映像檔管理作業,並避免因外部頻率限制和服務中斷而導致建構或部署作業中斷。您可以找出經常提取的映像檔,並複製到 Artifact Registry,以便部署至 Google Kubernetes Engine 或 Cloud Run 等 Google Cloud 環境。

遷移作業總覽

遷移容器映像檔的步驟如下:

  1. 設定必要條件。
  2. 找出要遷移的映像檔。
    • 搜尋 Dockerfile 檔案和部署資訊清單,找出第三方登錄檔的參照
    • 使用 Cloud Logging 和 BigQuery,判斷從第三方登錄檔提取映像檔的頻率。
  3. 將識別出的映像檔複製到 Artifact Registry。
  4. 確認已正確設定登錄檔權限,特別是 Artifact Registry 和 Google Cloud部署環境位於不同專案時。
  5. 更新部署作業的資訊清單。
  6. 重新部署工作負載。

Artifact Registry 不會監控上游 Registry,確認複製的映像檔是否有更新。如要將新版映像檔納入管道,必須將映像檔推送至 Artifact Registry。

事前準備

  1. 登入 Google Cloud 帳戶。如果您未曾使用過 Google Cloud,歡迎 建立帳戶,親自體驗實際使用我們產品的成效。新客戶還能獲得價值 $300 美元的免費抵免額,用於執行、測試及部署工作負載。
  2. 安裝 Google Cloud CLI。

  3. 若您採用的是外部識別資訊提供者 (IdP),請先 使用聯合身分登入 gcloud CLI。

  4. 執行下列指令,初始化 gcloud CLI:

    gcloud init
  5. 建立或選取 Google Cloud 專案。

    選取或建立專案所需的角色

    • 選取專案:選取專案時,不需具備特定 IAM 角色,只要您已獲派某個專案的角色,即可選取該專案。
    • 建立專案:如要建立專案,您必須具備專案建立者角色 (roles/resourcemanager.projectCreator),其中包含 resourcemanager.projects.create 權限。瞭解如何授予角色。
    • 建立 Google Cloud 專案:

      gcloud projects create PROJECT_ID

      將 PROJECT_ID 替換為您要建立的 Google Cloud 專案名稱。

    • 選取您建立的 Google Cloud 專案:

      gcloud config set project PROJECT_ID

      將 PROJECT_ID 替換為 Google Cloud 專案名稱。

  6. 確認 Google Cloud 專案已啟用計費功能。

  7. 啟用 Artifact Registry API (如果尚未啟用):

    啟用 API 所需的角色

    您必須具備 serviceusage.services.enable 權限,才能啟用 API。如果您建立了專案,可能已透過「擁有者」角色 (roles/owner) 取得這項權限。否則,您可以透過「Service Usage 管理員」角色 (roles/serviceusage.serviceUsageAdmin) 取得這項權限。瞭解如何授予角色。

    gcloud services enable artifactregistry.googleapis.com
  8. 安裝 Google Cloud CLI。

  9. 若您採用的是外部識別資訊提供者 (IdP),請先 使用聯合身分登入 gcloud CLI。

  10. 執行下列指令,初始化 gcloud CLI:

    gcloud init
  11. 建立或選取 Google Cloud 專案。

    選取或建立專案所需的角色

    • 選取專案:選取專案時,不需具備特定 IAM 角色,只要您已獲派某個專案的角色,即可選取該專案。
    • 建立專案:如要建立專案,您必須具備專案建立者角色 (roles/resourcemanager.projectCreator),其中包含 resourcemanager.projects.create 權限。瞭解如何授予角色。
    • 建立 Google Cloud 專案:

      gcloud projects create PROJECT_ID

      將 PROJECT_ID 替換為您要建立的 Google Cloud 專案名稱。

    • 選取您建立的 Google Cloud 專案:

      gcloud config set project PROJECT_ID

      將 PROJECT_ID 替換為 Google Cloud 專案名稱。

  12. 確認 Google Cloud 專案已啟用計費功能。

  13. 啟用 Artifact Registry API (如果尚未啟用):

    啟用 API 所需的角色

    您必須具備 serviceusage.services.enable 權限,才能啟用 API。如果您建立了專案,可能已透過「擁有者」角色 (roles/owner) 取得這項權限。否則,您可以透過「Service Usage 管理員」角色 (roles/serviceusage.serviceUsageAdmin) 取得這項權限。瞭解如何授予角色。

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

費用

本指南使用下列 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 資訊清單的位置執行這些步驟。如果檔案位於 VM 中,這可能是本機簽出的程式碼或 Cloud Shell。
  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. 在「查詢建立工具」分頁中,輸入下列查詢:

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

  5. 點選「執行查詢」。

  6. 確認結果正確顯示後,依序點選「Actions」(動作) >「Create Sink」(建立接收器)。

  7. 在「Sink details」(接收器詳細資料) 對話方塊中,完成下列步驟:

    1. 在「Sink Name」(接收器名稱) 欄位中輸入 image_pull_logs。
    2. 在「Sink description」(接收器說明) 中,輸入接收器說明。
  8. 點選「下一步」。

  9. 在「Sink destination」(接收器目的地) 對話方塊中,選取下列值:

    1. 在「選取接收器服務」欄位中,選取「BigQuery 資料集」。
    2. 在「Select BigQuery dataset」(選取 BigQuery 資料集) 欄位中,選取「Create a new BigQuery dataset」(建立新的 BigQuery 資料集),然後在開啟的對話方塊中填寫必要資訊。如要進一步瞭解如何建立 BigQuery 資料集,請參閱「建立資料集」。
    3. 點選「建立資料集」。
  10. 點選「下一步」。

    在「Choose logs to include in sink」(選擇要納入接收器的記錄檔) 部分,查詢會與您在「Query builder」(查詢建立工具) 分頁中執行的查詢相符。

  11. 點選「下一步」。

  12. 選用:選擇要從接收器排除的記錄。如要進一步瞭解如何查詢及篩選 Cloud Logging 資料,請參閱「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 的映像檔提取頻率。

圖片

將映像檔複製到 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。