このページでは、crane と oras で、イメージを作成して Artifact Registry のリポジトリに公開する方法について説明します。
Artifact Registry を使用して OCI イメージから同期するように Config Sync を構成できます。この機能を使用するには、RootSync API と RepoSync API を有効にする必要があります。
Artifact Registry について
Artifact Registry は、コンテナ イメージとコンテナ以外のアーティファクトの両方をサポートするフルマネージド サービスです。 Cloud de Confiance by S3NSでのコンテナ イメージの保存と管理には、Artifact Registry を使用することをおすすめします。Artifact Registry にアーティファクトを push するには、いくつかのツールを使用できます。たとえば、Docker イメージを push することや、go-containerregistry ライブラリをコンテナ レジストリと一緒に使用することが可能です。最適なツールを選択してください。
始める前に
-
Google Cloud CLI をインストールします。
-
フェデレーション ID(連携 ID)を使用するように gcloud CLI を構成します。
詳細については、連携 ID を使用して gcloud CLI にログインするをご覧ください。
-
gcloud CLI を初期化するには、次のコマンドを実行します:
gcloud init -
プロジェクトを Cloud de Confiance 作成または選択します。
プロジェクトを選択または作成するために必要なロール
- プロジェクトを選択する: プロジェクトの選択には特定の IAM ロールは必要ありません。ロールが付与されているプロジェクトを選択できます。
-
プロジェクトを作成する: プロジェクトを作成するには、プロジェクト作成者ロール
(
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 プロジェクトの名前に置き換えます。
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 イメージ署名を検証する場合は、以下をインストールします。
費用
このドキュメントでは、課金対象である次のコンポーネントを使用します。 Cloud de Confiance by S3NS:
このセクションでは、Artifact Registry リポジトリを作成します。Artifact Registry リポジトリの作成の詳細については、リポジトリを作成するをご覧ください。 Artifact Registry リポジトリを作成します。 次のように置き換えます。 次のセクションで使用される変数: 次の手順で、Kubernetes サービス アカウントを使用して Artifact Registry を認証します。 Workload Identity Federation for GKE プールを使用して、Artifact Registry 読み取り( このセクションでは、OCI イメージを作成して Artifact Registry に push します。 Artifact Registry にログインします。 イメージをパッケージ化して Artifact Registry に push します。 このセクションのコマンドは、 ファイルをパッケージ化します。 イメージを Artifact Registry に push します。 このセクションのコマンドは、 ファイルをパッケージ化します。 イメージを Artifact Registry に push します。 このセクションでは、 Config Sync がイメージから同期していることを確認します。 出力は次の例のようになります。 これで、イメージがクラスタに正常に同期されました。 構成がクラスタに適用される前に、OCI ソースイメージの真正性を検証できます。この方法では、 OCI ソースの真正性を確保するには、署名を検証する HTTP サーバーが必要です。Config Sync サンプル リポジトリのサンプルを使用するか、独自の Docker イメージを使用できます。 提供されたサンプルを使用する場合は、次の手順を完了します。 サンプル リポジトリのクローンを作成します。 署名検証サーバーのサンプルが含まれているディレクトリに移動します。 署名検証サーバーの Docker イメージを作成してイメージ レジストリに push するには、次のコマンドを実行します。 署名検証サーバーを設定するには、Artifact Registry、Cosign クライアント、Webhook サーバーの認証を行う必要があります。 名前空間を作成します。 Kubernetes ServiceAccount を使用して Artifact Registry を認証するには、次の操作を行います。 作成した名前空間に Kubernetes ServiceAccount を作成します。 Artifact Registry 読み取りロール( 次のように置き換えます。 Cosign クライアントに対して認証を行う手順は次のとおりです。 Cosign 鍵のペアを生成します。このコマンドは、公開鍵と秘密鍵を生成します。 作成した名前空間の Kubernetes Secret に公開鍵を保存します。 署名検証サーバーを認証するには、次の操作を行います。 署名検証サーバー内の通信を暗号化するには、OpenSSL を使用して TLS 証明書と秘密鍵を生成します。 生成した認証情報を Kubernetes Secret に保存します。 次のサンプルを使用して、署名検証サーバーのデプロイと検証用 Webhook 構成を作成できます。 次のファイルを保存して、署名検証サーバーのデプロイメントを作成します。 Deployment をクラスタに適用します。 次のファイルを保存して、検証用 Webhook 構成を作成します。 検証 Webhook 構成をクラスタに適用します。 イメージ検証サーバーを設定すると、未署名の OCI イメージからの同期は失敗します。 署名検証エラーを確認するには、次のコマンドを実行して署名検証サーバーからログを表示します。 署名検証に関連する Config Sync ログを確認します。 署名検証に関連する Config Sync のエラーは次のようになります。 エラーが表示されない場合は、 次のように置き換えます。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 の文字数です。読み取り権限を付与する
roles/artifactregistry.reader)IAM ロールを Kubernetes サービス アカウントに付与します。gcloud artifacts repositories add-iam-policy-binding AR_REPO_NAME \
--location=AR_REGION \
--member="serviceAccount:FLEET_HOST_PROJECT_ID.s3ns.svc.id.goog[config-management-system/KSA_NAME]" \
--role=roles/artifactregistry.reader \
--project=PROJECT_ID
イメージを Artifact Registry リポジトリに push する
Namespace マニフェスト ファイルを作成します。cat <<EOF> test-namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: test
EOF
gcloud auth configure-docker AR_REGION-docker.pkg.dev
cranecrane を使用してリモート イメージとレジストリを操作します。
tar -cf test-namespace.tar test-namespace.yaml
crane ツールをインストールします。crane append -f test-namespace.tar -t AR_REGION-docker.pkg.dev/PROJECT_ID/AR_REPO_NAME/test-namespace:v1
orasoras を使用してリモート イメージとレジストリを操作します。
tar -czf test-namespace.tar.gz test-namespace.yaml
oras ツールをインストールします。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
EOF
ROOT_SYNC_NAME は、実際の RootSync オブジェクトの名前に置き換えます。この名前はクラスタ内で一意で、26 文字以下にする必要があります。RootSync オブジェクトを構成する際のオプションの完全なリストについては、RootSync フィールドと RepoSync フィールドをご覧ください。RootSync オブジェクトを適用します。kubectl apply -f ROOT_SYNC_NAME.yaml
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 ソース署名を確認する
ValidatingWebhookConfiguration オブジェクトと検証 Webhook サーバーを使用して、RootSync オブジェクトと RepoSync オブジェクトの更新リクエストをインターセプトします。Config Sync は、新しいイメージ ダイジェストを正常に取得した後、RootSync オブジェクトと RepoSync オブジェクトの configsync.gke.io/image-to-sync アノテーションを更新します。検証 Webhook サーバーは、古いアノテーションと新しいアノテーションの値を比較し、変更が検出されると、Cosign などの検証ツールで検証を実行します。署名検証サーバーをセットアップする
git clone https://github.com/GoogleCloudPlatform/anthos-config-management-samples/
cd anthos-config-management-samples/tree/main/pre-sync/oci-image-verification
docker build -t SIGNATURE_VERIFICATION_SERVER_IMAGE_URL:latest . && docker push SIGNATURE_VERIFICATION_SERVER_IMAGE_URL:latest
SIGNATURE_VERIFICATION_SERVER_IMAGE_URL は、署名検証サーバー イメージの URL に置き換えます。サービスに対して認証する
kubectl create ns signature-verification
kubectl create sa signature-verification-sa -n signature-verification
roles/artifactregistry.reader)の IAM ポリシー バインディングを追加します。gcloud artifacts repositories add-iam-policy-binding REPOSITORY_NAME \
--location=REPOSITORY_LOCATION \
--member="serviceAccount:PROJECT_ID.s3ns.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 generate-key-pair
kubectl create secret generic cosign-key --from-file=cosign.pub -n signature-verification
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"
kubectl create secret tls webhook-tls --cert=tls.crt --key=tls.key -n signature-verification
tls.cert の Base64 エンコードされたコンテンツを取得します。これは、次のセクションで作成する検証 Webhook 構成に必要です。cat tls.crt | base64 -w 0.
アドミッション Webhook をデプロイする
SIGNATURE_VERIFICATION_SERVER_IMAGE_URL は、署名検証サーバー イメージの完全な URL に置き換えます。kubectl apply -f signature-verification-deployment.yaml -n signature-verification
CA_BUNDLE は、tls.cert の base64 でエンコードされたコンテンツに置き換えます。kubectl apply -f signature-verification-validatingwebhookconfiguration.yaml
ログでイメージ検証エラーを確認する
kubectl ログを確認するkubectl logs deployment signature-verification-server -n signature-verification
kubectl のエラーは次のようになります。main.go:69: error during command execution: no signatures found
nomos status
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 によって取得された最新のダイジェストが含まれています。次のステップ