このページでは、crane と oras で、イメージを作成して Artifact Registry のリポジトリに公開する方法について説明します。
Artifact Registry を使用して OCI イメージから同期するように Config Sync を構成できます。この機能を使用するには、RootSync API と RepoSync API を有効にする必要があります。
Artifact Registry について
Artifact Registry は、コンテナ イメージとコンテナ以外のアーティファクトの両方をサポートするフルマネージド サービスです。 Google Cloudでのコンテナ イメージの保存と管理には、Artifact Registry を使用することをおすすめします。Artifact Registry にアーティファクトを push するには、いくつかのツールを使用できます。たとえば、Docker イメージを push することや、go-containerregistry ライブラリをコンテナ レジストリと一緒に使用することが可能です。最適なツールを選択してください。
始める前に
- アカウントにログインします。 Google Cloud を初めて使用する場合は、 Google Cloud アカウントを作成して、 実際のシナリオで Google プロダクトのパフォーマンスを評価してください。新規のお客様には、ワークロードの実行、テスト、デプロイができる無料クレジット $300 分を差し上げます。
-
Google Cloud CLI をインストールします。
-
外部 ID プロバイダ(IdP)を使用している場合は、まず連携 ID を使用して gcloud CLI にログインする必要があります。
-
gcloud CLI を初期化するには、次のコマンドを実行します:
gcloud init -
プロジェクトを 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 プロジェクトの名前に置き換えます。
GKE、Config Sync、Artifact Registry の API を有効にします。
API を有効にするために必要なロール
API を有効にするには、 権限を含む Service Usage 管理者 IAM ロール(
roles/serviceusage.serviceUsageAdmin)が必要です。serviceusage.services.enable詳しくは、ロールを付与する方法をご覧ください。gcloud services enable container.googleapis.com
anthosconfigmanagement.googleapis.com artifactregistry.googleapis.com -
Google Cloud CLI をインストールします。
-
外部 ID プロバイダ(IdP)を使用している場合は、まず連携 ID を使用して gcloud CLI にログインする必要があります。
-
gcloud CLI を初期化するには、次のコマンドを実行します:
gcloud init -
プロジェクトを 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 プロジェクトの名前に置き換えます。
GKE、Config Sync、Artifact Registry の API を有効にします。
API を有効にするために必要なロール
API を有効にするには、 権限を含む Service Usage 管理者 IAM ロール(
roles/serviceusage.serviceUsageAdmin)が必要です。serviceusage.services.enable詳しくは、ロールを付与する方法をご覧ください。gcloud services enable container.googleapis.com
anthosconfigmanagement.googleapis.com artifactregistry.googleapis.com - Config Sync の要件を満たし、最新バージョンの Config Sync を使用しているクラスタを作成するか、このクラスタにアクセスできることを確認します。
nomosCLI をインストールするか、最新バージョンにアップグレードします。- (省略可)Cosign を使用して OCI イメージ署名を検証する場合は、以下をインストールします。
費用
このドキュメントでは、課金対象である次のコンポーネントを使用します。 Google Cloud:
料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。
Artifact Registry リポジトリを作成する
このセクションでは、Artifact Registry リポジトリを作成します。Artifact Registry リポジトリの作成の詳細については、リポジトリを作成するをご覧ください。
Artifact Registry リポジトリを作成します。
gcloud artifacts repositories create AR_REPO_NAME \ --repository-format=docker \ --location=AR_REGION \ --description="Config Sync repo" \ --project=PROJECT_ID
次のように置き換えます。
PROJECT_ID: 組織のプロジェクト ID。AR_REPO_NAME: リポジトリの ID。AR_REGION: リポジトリのリージョンまたはマルチリージョン ロケーション。
次のセクションで使用される変数:
FLEET_HOST_PROJECT_ID: GKE の Workload Identity Federation for GKE を使用している場合は、PROJECT_IDと同じです。フリートの Workload Identity Federation for GKE を使用している場合は、クラスタが登録されているフリートのプロジェクト ID です。GSA_NAME: Artifact Registry への接続に使用するカスタム Google サービス アカウントの名前。KSA_NAME: Reconciler の Kubernetes サービス アカウント。- ルート リポジトリで、
RootSync名がroot-syncの場合は、root-reconcilerを追加します。それ以外の場合は、root-reconciler-ROOT_SYNC_NAMEを追加します。 - 名前空間リポジトリで、
RepoSync名がrepo-syncの場合はns-reconciler-NAMESPACEを追加します。それ以外の場合は、ns-reconciler-NAMESPACE-REPO_SYNC_NAME-REPO_SYNC_NAME_LENGTHを追加します。ここで、REPO_SYNC_NAME_LENGTHはREPO_SYNC_NAMEの文字数です。
- ルート リポジトリで、
読み取り権限を付与する
次の手順で、Kubernetes サービス アカウントを使用して Artifact Registry を認証します。
Workload Identity Federation for GKE プールを使用して、Artifact Registry 読み取り(roles/artifactregistry.reader)IAM ロールを Kubernetes サービス アカウントに付与します。
gcloud artifacts repositories add-iam-policy-binding AR_REPO_NAME \
--location=AR_REGION \
--member="serviceAccount:FLEET_HOST_PROJECT_ID.svc.id.goog[config-management-system/KSA_NAME]" \
--role=roles/artifactregistry.reader \
--project=PROJECT_ID
イメージを Artifact Registry リポジトリに push する
このセクションでは、OCI イメージを作成して Artifact Registry に push します。
Namespaceマニフェスト ファイルを作成します。cat <<EOF> test-namespace.yaml apiVersion: v1 kind: Namespace metadata: name: test EOFArtifact Registry にログインします。
gcloud auth configure-docker AR_REGION-docker.pkg.devイメージをパッケージ化して Artifact Registry に push します。
craneこのセクションのコマンドは、
craneを使用してリモート イメージとレジストリを操作します。ファイルをパッケージ化します。
tar -cf test-namespace.tar test-namespace.yamlcraneツールをインストールします。イメージを Artifact Registry に push します。
crane append -f test-namespace.tar -t AR_REGION-docker.pkg.dev/PROJECT_ID/AR_REPO_NAME/test-namespace:v1
orasこのセクションのコマンドは、
orasを使用してリモート イメージとレジストリを操作します。ファイルをパッケージ化します。
tar -czf test-namespace.tar.gz test-namespace.yamlorasツールをインストールします。イメージを Artifact Registry に push します。
oras push AR_REGION-docker.pkg.dev/PROJECT_ID/AR_REPO_NAME/test-namespace:v1 test-namespace.tar.gz
イメージから同期するように Config Sync を構成する
このセクションでは、RootSync オブジェクトを作成し、OCI イメージから同期するように Config Sync を構成します。
RootSyncオブジェクトを一意の名前で作成します。cat <<EOF>> ROOT_SYNC_NAME.yaml apiVersion: configsync.gke.io/v1beta1 kind: RootSync metadata: name: ROOT_SYNC_NAME namespace: config-management-system spec: sourceFormat: unstructured sourceType: oci oci: image: AR_REGION-docker.pkg.dev/PROJECT_ID/AR_REPO_NAME/test-namespace:v1 dir: . auth: k8sserviceaccount EOFROOT_SYNC_NAMEは、実際のRootSyncオブジェクトの名前に置き換えます。この名前はクラスタ内で一意で、26 文字以下にする必要があります。RootSyncオブジェクトを構成する際のオプションの完全なリストについては、RootSyncフィールドとRepoSyncフィールドをご覧ください。RootSyncオブジェクトを適用します。kubectl apply -f ROOT_SYNC_NAME.yamlConfig Sync がイメージから同期していることを確認します。
nomos status --contexts=$(kubectl config current-context)出力は次の例のようになります。
Connecting to clusters... *publish-config-registry -------------------- <root>:root-sync-test AR_REGION-docker.pkg.dev/PROJECT_ID/AR_REPO_NAME/test-namespace:v1 SYNCED 05e6a6b77de7a62286387cfea833d45290105fe84383224938d7b3ab151a55a1 Managed resources: NAMESPACE NAME STATUS SOURCEHASH namespace/test Current 05e6a6bこれで、イメージがクラスタに正常に同期されました。
(省略可)OCI ソース署名を確認する
構成がクラスタに適用される前に、OCI ソースイメージの真正性を検証できます。この方法では、ValidatingWebhookConfiguration オブジェクトと検証 Webhook サーバーを使用して、RootSync オブジェクトと RepoSync オブジェクトの更新リクエストをインターセプトします。Config Sync は、新しいイメージ ダイジェストを正常に取得した後、RootSync オブジェクトと RepoSync オブジェクトの configsync.gke.io/image-to-sync アノテーションを更新します。検証 Webhook サーバーは、古いアノテーションと新しいアノテーションの値を比較し、変更が検出されると、Cosign などの検証ツールで検証を実行します。
署名検証サーバーをセットアップする
OCI ソースの真正性を確保するには、署名を検証する HTTP サーバーが必要です。Config Sync サンプル リポジトリのサンプルを使用するか、独自の Docker イメージを使用できます。
提供されたサンプルを使用する場合は、次の手順を完了します。
サンプル リポジトリのクローンを作成します。
git clone https://github.com/GoogleCloudPlatform/anthos-config-management-samples/署名検証サーバーのサンプルが含まれているディレクトリに移動します。
cd anthos-config-management-samples/tree/main/pre-sync/oci-image-verification
署名検証サーバーの Docker イメージを作成してイメージ レジストリに push するには、次のコマンドを実行します。
docker build -t SIGNATURE_VERIFICATION_SERVER_IMAGE_URL:latest . && docker push SIGNATURE_VERIFICATION_SERVER_IMAGE_URL:latestSIGNATURE_VERIFICATION_SERVER_IMAGE_URLは、署名検証サーバー イメージの URL に置き換えます。
サービスに対して認証する
署名検証サーバーを設定するには、Artifact Registry、Cosign クライアント、Webhook サーバーの認証を行う必要があります。
名前空間を作成します。
kubectl create ns signature-verificationKubernetes ServiceAccount を使用して Artifact Registry を認証するには、次の操作を行います。
作成した名前空間に Kubernetes ServiceAccount を作成します。
kubectl create sa signature-verification-sa -n signature-verificationArtifact Registry 読み取りロール(
roles/artifactregistry.reader)の IAM ポリシー バインディングを追加します。gcloud artifacts repositories add-iam-policy-binding REPOSITORY_NAME \ --location=REPOSITORY_LOCATION \ --member="serviceAccount:PROJECT_ID.svc.id.goog[signature-verification/signature-verification-sa]" \ --role=roles/artifactregistry.reader \ --project=PROJECT_ID次のように置き換えます。
REPOSITORY_NAME: OCI イメージを保存する Artifact Registry リポジトリの名前。REPOSITORY_LOCATION: Artifact Registry リポジトリのロケーション。
Cosign クライアントに対して認証を行う手順は次のとおりです。
Cosign 鍵のペアを生成します。このコマンドは、公開鍵と秘密鍵を生成します。
cosign generate-key-pair作成した名前空間の Kubernetes Secret に公開鍵を保存します。
kubectl create secret generic cosign-key --from-file=cosign.pub -n signature-verification
署名検証サーバーを認証するには、次の操作を行います。
署名検証サーバー内の通信を暗号化するには、OpenSSL を使用して TLS 証明書と秘密鍵を生成します。
openssl req -nodes -x509 -sha256 -newkey rsa:4096 \ -keyout tls.key \ -out tls.crt \ -days 356 \ -subj "/CN=signature-verification-service.signature-verification.svc" \ -addext "subjectAltName = DNS:signature-verification-service,DNS:signature-verification-service.signature-verification.svc,DNS:signature-verification-service.signature-verification"生成した認証情報を Kubernetes Secret に保存します。
kubectl create secret tls webhook-tls --cert=tls.crt --key=tls.key -n signature-verificationtls.certの Base64 エンコードされたコンテンツを取得します。これは、次のセクションで作成する検証 Webhook 構成に必要です。cat tls.crt | base64 -w 0.
アドミッション Webhook をデプロイする
次のサンプルを使用して、署名検証サーバーのデプロイと検証用 Webhook 構成を作成できます。
次のファイルを保存して、署名検証サーバーのデプロイメントを作成します。
SIGNATURE_VERIFICATION_SERVER_IMAGE_URLは、署名検証サーバー イメージの完全な URL に置き換えます。Deployment をクラスタに適用します。
kubectl apply -f signature-verification-deployment.yaml -n signature-verification次のファイルを保存して、検証用 Webhook 構成を作成します。
CA_BUNDLEは、tls.certの base64 でエンコードされたコンテンツに置き換えます。検証 Webhook 構成をクラスタに適用します。
kubectl apply -f signature-verification-validatingwebhookconfiguration.yaml
ログでイメージ検証エラーを確認する
イメージ検証サーバーを設定すると、未署名の OCI イメージからの同期は失敗します。
署名検証エラーを確認するには、次のコマンドを実行して署名検証サーバーからログを表示します。
kubectlログを確認するkubectl logs deployment signature-verification-server -n signature-verification署名検証に関連する
kubectlのエラーは次のようになります。main.go:69: error during command execution: no signatures foundConfig Sync ログを確認します。
nomos status署名検証に関連する Config Sync のエラーは次のようになります。
Error: KNV2002: admission webhook "imageverification.webhook.com" denied the request: Image validation failed: cosign verification failed: exit status 10, output: Error: no signatures found
エラーが表示されない場合は、RootSync または RepoSync 構成を調べて、署名付きイメージが同期対象のオブジェクトであることを確認できます。
RootSync
kubectl get rootsync ROOTSYNC_NAME -n config-management-system -oyaml
ROOTSYNC_NAME は、RootSync の名前で置き換えます。
RepoSync
kubectl get reposync REPOSYNC_NAME -n REPOSYNC_NAMESPACE -oyaml
次のように置き換えます。
REPOSYNC_NAME:RepoSyncの名前。REPOSYNC_NAMESPACE:RepoSyncに関連付けられている名前空間の名前。
RootSync オブジェクトまたは RepoSync オブジェクトにアノテーション configsync.gke.io/image-to-sync が追加されているはずです。アノテーションには、ソース OCI イメージの URL と、Config Sync によって取得された最新のダイジェストが含まれています。