Artifact Registry は、Artifact Registry にコピーされたイメージの更新に関し、サードパーティのレジストリをモニタリングしません。新しいバージョンのイメージをパイプラインに組み込むには、Artifact Registry に push する必要があります。
移行の概要
コンテナ イメージの移行には次の手順が含まれます。
- 前提条件を設定する。
- 移行するイメージを特定する。
- Dockerfile ファイルとデプロイメント マニフェストを検索して、サードパーティのレジストリへの参照を確認する
- Cloud Logging と BigQuery を使用して、サードパーティのレジストリからイメージを pull する頻度を決定する
- 特定されたイメージを Artifact Registry にコピーする。
- レジストリへの権限が正しく構成されていることを確認する(特に、Artifact Registry と Google Cloudのデプロイ環境が異なるプロジェクトに存在する場合)。
- デプロイのmanifestsを更新する。
- ワークロードを再デプロイする。
始める前に
- 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.
- Install the Google Cloud CLI.
-
To use a federated identity with the gcloud CLI, you must first configure the tool to use a federated identity.
For more information, see Browser-based sign-in with the gcloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
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.
-
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Artifact Registry API:
gcloud services enable artifactregistry.googleapis.com
- Install the Google Cloud CLI.
-
To use a federated identity with the gcloud CLI, you must first configure the tool to use a federated identity.
For more information, see Browser-based sign-in with the gcloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
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.
-
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Artifact Registry API:
gcloud services enable artifactregistry.googleapis.com
- Artifact Registry リポジトリがない場合は、リポジトリを作成し、リポジトリへのアクセス権を必要とするサードパーティ クライアントの認証を構成します。
- 権限を確認します。イメージを Artifact Registry に移行するプロジェクトで、オーナーまたは編集者の IAM ロールが割り当てられている必要があります。
- 次の環境変数をエクスポートします。
export PROJECT=$(gcloud config get-value project)
- Go バージョン 1.13 以降がインストールされていることを確認します。
Go をインストールまたは更新する必要がある場合は、Go のインストールのドキュメントをご覧ください。go version
費用
このガイドでは、 Google Cloudの次の課金対象コンポーネントを使用します。
移行するイメージを特定する
サードパーティのレジストリの参照用としてコンテナ イメージのビルドとデプロイに使用するファイルを検索し、そのイメージを pull する頻度を確認します。
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 で使用されている場合もあります。- GKE または Cloud Run マニフェストがあるディレクトリで次のコマンドを実行します。
出力は次のようになります。grep -inr -H --include \*.yaml "image:" . | grep -i -v -E 'docker.pkg.dev|gcr.io'
このコマンドは、ディレクトリ内のすべての YAML ファイルを調べて image: 行を特定します。必要に応じてコマンドを調整し、マニフェストの保存方法に合わせます。./code/deploy/k8s/ubuntu16-04.yaml:63: image: busybox:1.31.1-uclibc ./code/deploy/k8s/master.yaml:26: image: kubernetes/redis:v1
- クラスタで実行中のイメージを一覧表示するには、次のコマンドを実行します。
このコマンドは、選択した Kubernetes クラスタで実行中のすべてのオブジェクトを返し、イメージ名を取得します。出力は次のようになります。kubectl get all --all-namespaces -o yaml | grep image: | grep -i -v -E 'docker.pkg.dev|gcr.io'
- image: nginx image: nginx:latest - image: nginx - image: nginx
適用範囲を全体的に確認するため、すべてのGoogle Cloud プロジェクトですべての GKE クラスタに対して上記のコマンドを実行します。
サードパーティ レジストリから pull 頻度を特定する
サードパーティのレジストリから pull するプロジェクトでは、イメージの pull 頻度に関する情報を使用して、使用量がサードパーティのレジストリに適用されるレート制限と同等、または超過しているかを判断します。
ログデータを収集する
BigQuery にデータをエクスポートするログシンクを作成します。ログシンクに記述された宛先やクエリで、エクスポートするログエントリを選択します。個々のプロジェクトに対してクエリを実行してシンクを作成するか、スクリプトを使用してプロジェクト間でデータを収集できます。
単一のプロジェクトのシンクを作成するには:
-
Google Cloud コンソールで、[ログ エクスプローラ] ページに移動します。
検索バーを使用してこのページを検索する場合は、小見出しが「Logging」の結果を選択します。
Google Cloud プロジェクトを選択します。
[クエリビルダー] タブに、次のクエリを入力します。
resource.type="k8s_pod" jsonPayload.reason="Pulling"
履歴のフィルタを [過去 1 時間] から [過去 7 日間] に変更します。
[クエリを実行] をクリックします。
結果が正しく表示されたことを確認したら、[アクション] > [シンクを作成] をクリックします。
[シンクの詳細] ダイアログで、次の操作を行います。
- [シンク名] フィールドに「
image_pull_logs
」と入力します。 - [シンクの説明] に、シンクの説明を入力します。
- [シンク名] フィールドに「
[次へ] をクリックします。
[シンクのエクスポート先] ダイアログで、次の値を選択します。
- [シンクサービスの選択] フィールドで、[BigQuery データセット] を選択します。
- [BigQuery データセットを選択] フィールドで [新しい BigQuery データセットを作成する] を選択し、開いたダイアログで必要な情報を入力します。BigQuery データセットの作成方法については、データセットを作成するをご覧ください。
- [データセットを作成] をクリックします。
[次へ] をクリックします。
[シンクに含めるログを選択] セクションのクエリは、[クエリビルダー] タブで実行したクエリと一致します。
[次へ] をクリックします。
省略可: シンクから除外するログを選択します。Cloud Logging データのクエリとフィルタリングの方法については、Logging のクエリ言語をご覧ください。
[シンクを作成] をクリックします。
ログシンクが作成されます。
複数のプロジェクトのシンクを作成するには:
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
)。
- PROJECT-LIST は、スペースで区切られた Google Cloud プロジェクト ID のリストです。たとえば、
シンクを作成した後、BigQuery テーブルにデータが流れるまでに時間がかかりますが、これはイメージを pull する頻度に応じて変わります。
pull 頻度のクエリ
ビルドが行うイメージ pull の代表サンプルを取得したら、pull 頻度のクエリを実行します。
次のクエリを実行します。
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 ツールは、コピープロセスに利用できます。
特定したイメージの名前を使用してテキスト ファイル
images.txt
を作成します。次に例を示します。ubuntu:18.04 debian:buster hello-world:latest redis:buster jupyter/tensorflow-notebook
gcrane をダウンロードします。
GO111MODULE=on go get github.com/google/go-containerregistry/cmd/gcrane
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
スクリプトを実行してファイルをコピーします。
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 コンソールで次のクエリを実行して、新しいイメージの pull を追跡します。
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
新しいイメージの pull はすべて Artifact Registry から行われ、文字列 docker.pkg.dev
が含まれている必要があります。