このチュートリアルでは、証明書を要求する Binary Authorization ポリシーの構成とテストの方法を説明します。このタイプのポリシーは、Google Kubernetes Engine(GKE)にコンテナ イメージをデプロイできる対象と、GKE へのデプロイを許可するコンテナ イメージを定義し、コンテナベースのソフトウェア サプライ チェーンを保護します。
デプロイ時に、Binary Authorization は認証者を使用して証明書のデジタル署名を検証します。証明書は、ビルドプロセスの中で署名者によって作成されています。
このチュートリアルでは、GKE クラスタ、証明書、認証者はすべて 1 つのプロジェクトに存在します。単一プロジェクト構成はサービスのテストや試験運用に非常に役立ちます。より現実的な例については、マルチプロジェクト構成をご覧ください。
以下では、Google Cloud コンソールから実行するタスクと、gcloud
コマンドを使用して実行するタスクについて説明します。これらの手順を gcloud
を使用して行うには、Google Cloud CLI の使用を開始するをご覧ください。
目標
このチュートリアルでは、以下の方法について学習します。
- Binary Authorization を有効にした GKE クラスタを作成する
- Binary Authorization 施行者が証明書の署名を検証するために使用する認証者を作成する
- 証明書を要求するポリシーを構成する
- 証明書に署名して後で検証するための暗号鍵ペアを作成する
- 署名を作成してコンテナ イメージ ダイジェストに署名する
- 署名を使用して証明書を作成する
- コンテナ イメージを GKE にデプロイしてポリシーをテストする
費用
このドキュメントでは、Google Cloud の次の課金対象のコンポーネントを使用します。
- Artifact Registry
- Binary Authorization
- GKE
- Container Registry
- Optional: Cloud Key Management Service
料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。
始める前に
- 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.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Container Registry, Artifact Analysis and Binary Authorization APIs.
- Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
-
Make sure that billing is enabled for your Google Cloud project.
-
Enable the Container Registry, Artifact Analysis and Binary Authorization APIs.
- Install the Google Cloud CLI.
-
To initialize the gcloud CLI, run the following command:
gcloud init
kubectl
をインストールします。
デフォルト プロジェクトを設定する
その後のコマンドを実行しやすくするため、次のように Google Cloud プロジェクト ID を環境変数に保存します。
PROJECT_ID=PROJECT_ID
ここで PROJECT_ID はプロジェクトの名前です。
デフォルト プロジェクトが選択されていない場合は、ここで設定します。
gcloud config set project ${PROJECT_ID}
Binary Authorization を有効にしたクラスタを作成する
クラスタを作成する
これで、Binary Authorization を有効にして GKE クラスタを作成できるようになりました。ここでは、GKE ゾーン us-central1-a
に test-cluster
というクラスタを作成します。
クラスタの作成手順は次のとおりです。
Google Cloud コンソールの GKE メニューに移動します。
[クラスタを作成] をクリックします。
[名前] フィールドに「
test-cluster
」と入力します。[ロケーション タイプ] オプションで [ゾーン] を選択します。
[ゾーン] プルダウン リストから
us-central1-a
を選択します。[可用性、ネットワーキング、セキュリティ、その他の機能] をクリックします。
[セキュリティ] セクションで [Binary Authorization の有効化] を選択します。
[適用のみ] を選択します。
[作成] をクリックします。
kubectl
を構成する
kubectl
のインストール用にローカルの kubeconfig
ファイルも更新する必要があります。これにより、GKE でクラスタにアクセスするために必要な認証情報とエンドポイント情報が提供されます。
ローカル kubeconfig
ファイルの更新手順は次のとおりです。
gcloud container clusters get-credentials \ --zone us-central1-a \ test-cluster
デフォルトのポリシーを表示する
Binary Authorization ポリシーは、コンテナ イメージのデプロイを制御する一連のルールです。プロジェクトごとに 1 つのポリシーを作成できます。デフォルトでは、すべてのコンテナ イメージをデプロイできるポリシーが構成されています。
デフォルト ポリシーを表示するには、次の手順を行います。
Google Cloud コンソールで [Binary Authorization] ページに移動します。
[ポリシーの編集] をクリックします。
[プロジェクトのデフォルト ルール] に、[すべてのイメージを許可] オプションが表示されます。
[ポリシーを保存] をクリックします。
認証者を作成する
認証者は、デプロイ時に Binary Authorization 施行者が GKE で対応する署名付きコンテナ イメージのデプロイを許可するかどうかを決定する際に使用する検証機関です。認証者には公開鍵が含まれ、通常はソフトウェア サプライ チェーンのセキュリティの担当者が管理します。
認証者を作成するには、次のことを行います。
- Binary Authorization で認証者を作成する
- Artifact Analysis で、関連する認証者のメモを自動生成し、承認プロセスで使用される信頼できる証明書メタデータを保存する
このチュートリアルでは、test-attestor
という名前の認証者を使用しています。実際のシナリオでは、任意の数の認証者を指定できます。各認証者は、イメージの認証プロセスに参加する当事者を表します。
鍵ペアを生成する
Binary Authorization は、暗号鍵を使用して署名者の ID を安全に確認します。これにより、承認済みのコンテナ イメージのみをデプロイできます。鍵ペアは秘密鍵と公開鍵で構成されます。署名者は、署名を生成して証明書に保存し、秘密鍵を使用してコンテナ イメージのダイジェストに署名します。公開鍵は認証者に保存されます。コンテナのデプロイを許可する前に、Binary Authorization の施行者が認証者の公開鍵を使用して、証明書の署名を検証します。
このチュートリアルでは、暗号鍵に公開鍵基盤(X.509)(PKIX)形式を使用します。このチュートリアルでは、PKIX 鍵ペアの生成に推奨の楕円曲線デジタル署名アルゴリズム(ECDSA)を使用していますが、RSA 鍵または PGP 鍵で署名することもできます。署名アルゴリズムの詳細については、鍵の目的とアルゴリズムをご覧ください。
Cloud Key Management Service(Cloud KMS)によって生成され、保存された鍵は PKIX に準拠しています。PKIX 鍵と Cloud KMS の使用方法については、CLI を使用した認証者の作成をご覧ください。
PKIX 鍵ペアを生成する手順は次のとおりです。
秘密鍵を作成します。
PRIVATE_KEY_FILE="/tmp/ec_private.pem" openssl ecparam -genkey -name prime256v1 -noout -out ${PRIVATE_KEY_FILE}
秘密鍵から公開鍵を抽出します。
PUBLIC_KEY_FILE="/tmp/ec_public.pem" openssl ec -in ${PRIVATE_KEY_FILE} -pubout -out ${PUBLIC_KEY_FILE}
認証者を作成する
これで、Binary Authorization で認証者を作成し、作成した公開鍵を関連付けることができるようになりました。
認証者を作成する手順は次のとおりです。
Google Cloud コンソールの [Binary Authorization] ページに戻ります。
[認証者] タブで [作成] をクリックします。
次のフィールドに入力します。
[認証者の名前] フィールドに「
test-attestor
」と入力します。[Automatically create a Artifact Analysis note] がオンになっていることを確認します。
[PKIX 公開鍵を追加] をクリックします。
テキスト エディタで
/tmp/ec_public.pem
を開きます。これは、前の手順で作成した公開鍵ファイルです。ファイルの内容を [公開鍵マテリアル] テキスト ボックスにコピーします。[Signature algorithm] プルダウンから
Elliptic Curve P-256 - SHA256 Digest
をクリックします。[完了] をクリックします。
[作成] をクリックして、認証者を作成します。
公開鍵 ID を保存します。
認証者に追加した公開鍵 ID を表示するには、
gcloud container binauthz attestors describe ${ATTESTOR_NAME}
を使用します。公開鍵 ID を格納する環境変数を作成するには、次のコマンドを実行します。ATTESTOR_NAME=test-attestor PUBLIC_KEY_ID=$(gcloud container binauthz attestors describe ${ATTESTOR_NAME}\ --format='value(userOwnedGrafeasNote.publicKeys[0].id)')
ポリシーを構成する
これでポリシーを構成できます。
Google Cloud コンソールの [Binary Authorization] ページに戻ります。
[ポリシー] タブで [ポリシーの編集] をクリックします。
[次のすべてのアテスターによって承認された画像のみを許可] を選択します。
[認証者の追加] をクリックします。
[プロジェクトと認証者の名前により追加] をクリックします。
[プロジェクト名] フィールドに「PROJECT_ID」と入力します。
[認証者の名前] フィールドに「
test-attestor
」と入力します。[Add 1 Attestor] をクリックします。
[ポリシーを保存] をクリックします。
詳細については、Console を使用したポリシーの構成をご覧ください。
ポリシーをテストする
上記で構成したポリシーをテストするには、サンプル コンテナ イメージをクラスタにデプロイします。必要な証明書が作成されていないため、ポリシーによってデプロイがブロックされます。
このチュートリアルでは、Container Registry と Artifact Registry のサンプル イメージを使用できます。Container Registry のイメージは、パス gcr.io/google-samples/hello-app:1.0
にあります。Artifact Registry のイメージはパス us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0
にあります。どちらのパスにも、「Hello, World!」サンプル アプリケーションを含む Google 作成の公開イメージが含まれています。
イメージのデプロイを試みるには、次のコマンドを実行します。
kubectl run hello-server --image gcr.io/google-samples/hello-app:1.0 --port 8080
次に、Binary Authorization でデプロイがブロックされたことを確認します。
kubectl get pods
このコマンドを実行すると、イメージがデプロイされなかったことを示す次のメッセージが出力されます。
No resources found.
次のコマンドによってデプロイの詳細を確認できます。
kubectl get event --template \ '{{range.items}}{{"\033[0;36m"}}{{.reason}}:{{"\033[0m"}}\{{.message}}{{"\n"}}{{end}}'
次のようなレスポンスが表示されます。
FailedCreate: Error creating: pods POD_NAME is forbidden: admission webhook "imagepolicywebhook.image-policy.k8s.io" denied the request: Image IMAGE_NAME denied by Binary Authorization default admission rule. Image IMAGE_NAME denied by ATTESTOR_NAME: No attestations found
この出力で:
- POD_NAME: Pod の名前。
- IMAGE_NAME: イメージの名前。
- ATTESTOR_NAME: 認証者の名前。
デプロイを削除して次の手順に進みます。
kubectl delete deployment hello-server
証明書を作成する
証明書は、GKE が関連するコンテナ イメージのデプロイを許可したことを証明する署名者によって作成されるデジタル ドキュメントです。証明書を作成するプロセスを「イメージに署名する」という場合があります。
このチュートリアルでは、Container Registry や Artifact Registry からのサンプル イメージの証明書を作成します。
証明書を作成するには、次のようにします。
イメージのレジストリパスとダイジェスト、認証者名を格納する変数を設定します。
Container Registry
IMAGE_PATH="gcr.io/google-samples/hello-app" IMAGE_DIGEST="sha256:c62ead5b8c15c231f9e786250b07909daf6c266d0fcddd93fea882eb722c3be4" ATTESTOR="test-attestor" IMAGE_TO_ATTEST=${IMAGE_PATH}@${IMAGE_DIGEST}
Artifact Registry
IMAGE_PATH="us-docker.pkg.dev/google-samples/containers/gke/hello-app" IMAGE_DIGEST="sha256:37e5287945774f27b418ce567cd77f4bbc9ef44a1bcd1a2312369f31f9cce567" ATTESTOR="test-attestor" IMAGE_TO_ATTEST=${IMAGE_PATH}@${IMAGE_DIGEST}
証明書ペイロードを生成します。
Container Registry
gcloud container binauthz create-signature-payload \ --artifact-url=${IMAGE_PATH}@${IMAGE_DIGEST} > /tmp/generated_payload.json
ペイロード JSON ファイルの内容は次のとおりです。
{ "critical": { "identity": { "docker-reference": "gcr.io/google-samples/hello-app" }, "image": { "docker-manifest-digest": "sha256:c62ead5b8c15c231f9e786250b07909daf6c266d0fcddd93fea 882eb722c3be4" }, "type": "Google cloud binauthz container signature" } }
Artifact Registry
gcloud container binauthz create-signature-payload \ --artifact-url=${IMAGE_PATH}@${IMAGE_DIGEST} > /tmp/generated_payload.json
ペイロード JSON ファイルの内容は次のとおりです。
{ "critical": { "identity": { "docker-reference": "us-docker.pkg.dev/google-samples/containers/gke/hello-app" }, "image": { "docker-manifest-digest": "sha256:37e5287945774f27b418ce567cd77f4bbc9ef44a1bcd1a2312369f31f9cce567" }, "type": "Google cloud binauthz container signature" } }
PKIX 秘密鍵でペイロードに署名し、署名ファイルを出力します。
openssl dgst -sha256 -sign ${PRIVATE_KEY_FILE} /tmp/generated_payload.json > /tmp/ec_signature
署名ファイルは、上記で作成したペイロード JSON ファイルのデジタル署名バージョンです。
証明書を作成して検証します。
gcloud container binauthz attestations create \ --project="${PROJECT_ID}" \ --artifact-url="${IMAGE_TO_ATTEST}" \ --attestor="projects/${PROJECT_ID}/attestors/${ATTESTOR_NAME}" \ --signature-file=/tmp/ec_signature \ --public-key-id="${PUBLIC_KEY_ID}" \ --validate
PUBLIC_KEY_ID
は、上記の PKIX 鍵ペアを生成するにある公開鍵 ID です。validate
フラグは、ポリシーで構成した認証者が証明書を検証できることを確認します。証明書が作成されたことを確認します。
gcloud container binauthz attestations list \ --attestor=$ATTESTOR_NAME --attestor-project=$PROJECT_ID
証明書の作成の詳細については、証明書の作成をご覧ください。
ポリシーを再テストする
クラスタにサンプル コンテナ イメージをデプロイして、ポリシーを再度テストします。今回は、Binary Authorization はダイジェストを使用して証明書を検索するため、1.0
や latest
などのタグではなく、ダイジェストを使用してイメージをデプロイする必要があります。ここでは、必要な証明書が作成されたため、Binary Authorization はイメージのデプロイを許可します。
イメージをデプロイするには、次のコマンドを実行します。
kubectl run hello-server --image ${IMAGE_PATH}@${IMAGE_DIGEST} --port 8080
次のコマンドを実行して、イメージがデプロイされたことを確認します。
kubectl get pods
このコマンドを実行すると、デプロイが成功したことを示す次のようなメッセージが出力されます。
NAME READY STATUS RESTARTS AGE hello-server-579859fb5b-h2k8s 1/1 Running 0 1m
Pod を削除するには、次のコマンドを実行します。
kubectl delete pod hello-server
クリーンアップ
このチュートリアルで使用したリソースについて、Google Cloud アカウントに課金されないようにするには、リソースを含むプロジェクトを削除するか、プロジェクトを維持して個々のリソースを削除します。
GKE で作成したクラスタを削除します。
gcloud container clusters delete \ --zone=us-central1-a \ test-cluster