このチュートリアルでは、Cloud Build プライベート プールを使用して限定公開の Google Kubernetes Engine(GKE)クラスタのコントロール プレーンにアクセスする方法について説明します。このアクセス権により、Cloud Build を使用して限定公開 GKE クラスタにアプリケーションをデプロイし、リソースを管理できるようになります。このチュートリアルは、プラットフォーム管理者、クラスタ管理者、デベロッパーを対象としています。対象読者は、GKE、Cloud Build、OpenID Connect、gcloud
コマンドライン ツールに精通していることを前提としています。
Cloud Build のプライベート プールと GKE クラスタ コントロール プレーンは、どちらも Google が所有する Virtual Private Cloud(VPC)ネットワークで実行されます。これらの VPC ネットワークは、Google Cloud 上の独自の VPC ネットワークにピアリングされます。ただし、VPC ネットワーク ピアリングでは推移的なピアリングがサポートされていないため、Cloud Build のプライベート プールを使用する場合は制限となる可能性があります。このチュートリアルでは、Identity Service for GKE を使用して、Cloud Build プライベート プールのワーカーが限定公開 GKE クラスタのコントロール プレーンにアクセスできるようにするソリューションを紹介します。
アーキテクチャの概要
Identity Service for GKE は、GKE クラスタ コントロール プレーンの認証プロキシです。API サーバーにリクエストをプロキシし、OpenID Connect(OIDC) ID プロバイダによって発行された ID トークンを検証します。プロキシで ID トークンが正常に検証されると、プロキシはユーザーなりすましの HTTP ヘッダーを元のリクエストに追加し、API サーバーに転送します。プロキシは、ユーザーとグループの権限を借用する権限を持つ Kubernetes サービス アカウントとして実行されます。
Identity Service for GKE プロキシはクラスタノードで Pod として動作します。LoadBalancer
タイプの Kubernetes Service は、クラスタ外部にプロキシを公開します。限定公開クラスタで Identity Service for GKE が有効になっている場合、インストーラが Kubernetes Service にアノテーションを追加して、内部パススルー ネットワーク ロードバランサをプロビジョニングします。プロキシは、VPC ネットワーク ピアリング接続(Cloud Build プライベート プールなど)上でロードバランサを通じてアクセスできます。これは、プロキシが、VPC ネットワークのクラスタノードで実行されているためです。
Google の OAuth 2.0 認証システムは OpenID Connect 仕様に準拠しているため、Identity Service for GKE で OpenID Connect ID プロバイダとして Google を構成できます。Google サービス アカウントの ID トークンを取得するには、Service Account Credentials API API の generateIdToken
メソッドを使用できます。ID トークンは、Google によって発行され、署名されます。
すべてをまとめると、このソリューションでは、Identity Service for GKE プロキシを使用して、限定公開 GKE クラスタ コントロール プレーンへのアクセスが可能です。Cloud Build プライベート プールで実行されるビルドは、VPC ネットワーク ピアリング接続上でプロキシに接続します。Cloud Build プライベート プールで実行されているビルドは、Google サービス アカウントとして実行されます。この Google サービス アカウントは、Service Account Credentials API からプロキシを認証するための ID トークンを取得できます。
次の図は、前述のテキストで説明したアーキテクチャを示しています。
このソリューションのすべての通信は、内部 IP アドレス空間上で行われます。プライベート プール内のワーカーは、公共のインターネット接続を必要としません。
ユーザー アカウントと Google サービス アカウントに付与されている Identity and Access Management(IAM)権限は、Identity Service for GKE を使用して認証する場合には適用されません。代わりに、Kubernetes ロールベースのアクセス制御(RBAC)を使用して、これらのアカウントのクラスタ権限を管理します。
準備
- 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 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 Cloud Build, GKE, Identity-Aware Proxy (IAP), and Service Networking APIs APIs:
gcloud services enable cloudbuild.googleapis.com
container.googleapis.com iap.googleapis.com servicenetworking.googleapis.com - Install the Google Cloud 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 Cloud Build, GKE, Identity-Aware Proxy (IAP), and Service Networking APIs APIs:
gcloud services enable cloudbuild.googleapis.com
container.googleapis.com iap.googleapis.com servicenetworking.googleapis.com
限定公開 GKE クラスタの作成
Cloud Shell で、コントロール プレーンのパブリック エンドポイントへのクライアント アクセス権がなく、Identity Service for GKE がインストールされている GKE クラスタを作成します。
gcloud container clusters create CLUSTER \ --enable-identity-service \ --enable-ip-alias \ --enable-master-authorized-networks \ --enable-private-endpoint \ --enable-private-nodes \ --master-ipv4-cidr CONTROL_PANE_CIDR \ --network NETWORK\ --release-channel regular \ --scopes cloud-platform \ --subnetwork SUBNET \ --tags NODE_TAGS \ --workload-pool PROJECT_ID.svc.id.goog \ --zone ZONE
次のように置き換えます。
- CLUSTER: クラスタの名前。 このチュートリアルでは、
private-cluster
を使用します。 - CONTROL_PANE_CIDR: コントロール プレーンの IP アドレス範囲。
/28
接頭辞が必要です。このチュートリアルでは、172.16.0.32/28
を使用できます。 - NETWORK: コントロール プレーンが接続する VPC ネットワーク。このチュートリアルでは、
default
を使用します。 - SUBNET: GKE クラスタ コントロール プレーンが接続するサブネット。サブネットは、NETWORK で指定された VPC ネットワークに属している必要があります。このチュートリアルでは、
default
を使用します。 - NODE_TAGS: ノードに適用するネットワーク タグのカンマ区切りのリスト。このチュートリアルでは、
private-cluster-node
を使用します。 - PROJECT_ID: Google Cloud プロジェクト ID。
- ZONE: GKE クラスタのゾーン。このチュートリアルでは、
us-central1-f
を使用します。
コマンドについて、次の点に注意してください。
--enable-identity-service
フラグによって、クラスタで Identity Service for GKE が有効になります。独自の環境では、既存のクラスタで Identity Service for GKE を有効にできます。--enable-private-endpoint
フラグは、内部 IP アドレスを使用することによってのみアクセスできるようにコントロール プレーンを構成します。--enable-private-nodes
フラグは、内部 IP アドレスのみを持つようにクラスタノードを構成します。--enable-master-authorized-networks
フラグと--enable-private-nodes
フラグによって、--network
フラグで指定されたプライベート ネットワークからのみ API サーバーにアクセスできます。オプションの
--workload-pool
フラグによって、Workload Identity が有効になります。それはこのチュートリアルでは必須ではありません。
- CLUSTER: クラスタの名前。 このチュートリアルでは、
GKE クラスタ コントロール プレーンが ClientConfig リソースの検証用アドミッション Webhook に接続できるようにファイアウォール ルールを追加します。
gcloud compute firewall-rules create allow-control-plane-clientconfig-webhook \ --allow tcp:15000 \ --network NETWORK\ --source-ranges CONTROL_PANE_CIDR\ --target-tags NODE_TAGS
ClientConfig は、Identity Service for GKE が使用して ID プロバイダとやり取りする方法を構成する Kubernetes カスタム リソースタイプ(CRD)です。
Identity Service for GKE を OAuth 2.0 クライアント アプリケーションとして登録する
このセクションでは、Google の OAuth 2.0 認証システムを使用して、Identity Service for GKE をクライアント アプリケーションとして登録します。
Google Cloud コンソールの認証情報ページを開きます。
[認証情報を作成] をクリックします。
[OAuth クライアント ID] を選択します。
Google Cloud プロジェクトに対して同意画面がまだ構成されていない場合は、[同意画面を構成] をクリックします。同意画面を構成に関するドキュメントに従います。このチュートリアルでは、次の値を設定します。
- [User Type] には、[Internal] または [External] のいずれかを使用できます。このチュートリアルでは、[Internal] を選択できます。
- [アプリ名]、[ユーザー サポートメール]、[デベロッパーの連絡先情報] の値は必須で、任意の値を設定できます。
- このチュートリアルでは、スコープを追加する必要はありません。
同意画面の構成が完了したら、[ダッシュボードに戻る] をクリックし、現在の手順のステップ 1 からやり直します。
[アプリケーションの種類] リストで、[ウェブ アプリケーション] を選択します。
[名前] フィールドに、クライアント ID の名前を入力します。このチュートリアルでは、
Identity Service for GKE
を使用します。[作成] をクリックします。
ダイアログが表示されます。 [クライアント ID] の値をコピーします。この手順で後で必要になります。
[OK] をクリックしてダイアログ ボックスを閉じます。
Cloud Shell で、
cloud-build-private-pools-gke-tutorial
というホーム ディレクトリの下にディレクトリを作成し、そのディレクトリに移動します。mkdir -p ~/cloud-build-private-pools-gke-tutorial cd ~/cloud-build-private-pools-gke-tutorial
新しいディレクトリに、
client-config-patch.yaml
という名前の YAML ファイルを作成します。これには、後で Identity Service for GKE ClientConfig リソースにパッチを適用するのに必要な値があります。cat << EOF > client-config-patch.yaml spec: authentication: - name: google-oidc oidc: clientID: CLIENT_ID cloudConsoleRedirectURI: https://console.cloud.google.com/kubernetes/oidc extraParams: prompt=consent,access_type=offline issuerURI: https://accounts.google.com kubectlRedirectURI: http://localhost:10000/callback scopes: email userClaim: email userPrefix: '-' EOF
CLIENT_ID は、前の手順からの OAuth クライアント ID で置き換えます。
パッチに関する次の点に注意してください。
Google の OAuth 2.0 認証システムが発行する ID トークンには、サブ(サブジェクト)クレームに一意の数値識別子が含まれています。この不透明な ID をロール バインディングで使用すると、ロール バインディングのサブジェクトを特定するのが難しくなります。そのため、このパッチにより、デフォルトのサブクレームを使用する代わりに、ID トークンのメール クレームを使用してユーザーを識別するように Identity Service for GKE を構成します。
メールのスコープが追加され、発行された ID トークンにメール クレームが含まれるようになります。
cloudConsoleRedirectURI
、extraParams
、kubectlRedirectURI
、スコープのフィールドは、デベロッパーが Identity Service for GKE を使用してクラスタに対する認証を行う場合に使用されます。Google サービス アカウントがクラスタを認証するときには使用されません。kubectlRedirectURI フィールドが必須です。userPrefix
フィールドは、構成された ID プロバイダを使用して認証するユーザーの接頭辞です。値'-'
は接頭辞がないことを意味します。spec.authentication
フィールドは配列です。Identity Service for GKE では、複数の OpenID Connect ID プロバイダを使用できます。たとえば、Google サービス アカウントを認証するための ID プロバイダとして、そしてデベロッパーを認証する別の ID プロバイダとして、Google を使用できます。
この構成のフィールドの詳細については、外部 ID プロバイダを使用して GKE に認証するをご覧ください。
Google サービス アカウントを作成して Identity Service for GKE を構成する
Cloud Shell で、Google サービス アカウントを作成します。
gcloud iam service-accounts create ISG_GSA \ --display-name "Configure Identity Service for GKE"
ISG_GSA は、Google サービス アカウントに使用する名前に置き換えます。このチュートリアルでは、
identity-service-for-gke
を使用します。Identity Service for GKE を構成し、クラスタで Kubernetes のロールベース アクセス制御を構成するには、Compute Engine VM インスタンスにこの Google サービス アカウントを割り当てます。
プロジェクトの Kubernetes Engine 管理者ロールを Google サービス アカウントに付与します。
gcloud projects add-iam-policy-binding PROJECT_ID \ --member serviceAccount:ISG_GSA@PROJECT_ID.iam.gserviceaccount.com \ --role roles/container.admin
このロールは、このチュートリアルで次のタスクを行うために必要な権限を提供します。
- プロジェクト内のクラスタで Identity Service for GKE の設定を構成します。
- クラスタにロール バインディングとクラスタ ロール バインディングを作成します。
GKE 用 Identity Service を構成する
Identity Service for GKE を構成するには、クラスタ コントロール プレーンへのアクセス権が必要です。このチュートリアルでは、コントロール プレーンにアクセスするための Compute Engine VM インスタンスを作成します。
VM インスタンスへの SSH アクセスが必要です。VPC ネットワークの外側から VM インスタンスへの SSH アクセスの認証と認可を有効にするには、Identity-Aware Proxy(IAP)で TCP 転送を使用します。この機能により、VM インスタンスにパブリック IP アドレスがなくても SSH アクセスが可能になります。
Cloud Shell で、
ssh-iap
ネットワーク タグを持つ任意の VM インスタンスへの IAP TCP 転送を使用して SSH アクセスを許可するファイアウォール ルールを作成します。gcloud compute firewall-rules create allow-ssh-ingress-from-iap \ --allow tcp:22 \ --description "Allow SSH tunneling using Identity-Aware Proxy" \ --network NETWORK \ --source-ranges 35.235.240.0/20 \ --target-tags ssh-iap
ソース範囲には、IAP が TCP 転送に使用する IP アドレスが含まれています。
GKE クラスタと同じ VPC ネットワーク内に Compute Engine VM インスタンスを作成します。
gcloud compute instances create VM \ --metadata enable-oslogin=TRUE \ --network NETWORK \ --no-address \ --scopes cloud-platform,userinfo-email \ --service-account ISG_GSA@PROJECT_ID.iam.gserviceaccount.com \ --subnet SUBNET \ --tags ssh-iap \ --zone ZONE
VM は、VM インスタンスに使用する名前に置き換えます。このチュートリアルでは、
identity-service-for-gke-configuration
を使用します。上記のコマンドについて、次の点に注意してください。
--service-account
フラグは、Google サービス アカウントを VM インスタンスに接続します。Service Account Credentials API にアクセスするには
cloud-platform
スコープが必要です。userinfo-email
スコープは、Kubernetes ロールベースのアクセス制御を管理する VM インスタンスを作成するときに役立ちます。このチュートリアルでは省略できます。--no-address
フラグは、VM インスタンスが外部 IP アドレスなしで作成されていることを意味します。オプションの
enable-oslogin
インスタンス メタデータ値によって、VM インスタンスで OS Login が有効になります。OS Login は、IAM を使用して VM インスタンスへの SSH アクセスの管理を有効にします。
ClientConfig パッチファイルを VM インスタンスにコピーします。
gcloud compute scp client-config-patch.yaml VM:~ --tunnel-through-iap --zone ZONE
--tunnel-through-iap
フラグを指定すると、gcloud
は IAP を介して接続をトンネリングします。SSH を使用して VM インスタンスに接続します。
gcloud compute ssh VM --tunnel-through-iap --zone ZONE
このセクションの残りのコマンドは、SSH セッションから実行します。
VM インスタンスに
kubectl
コマンドライン ツールと gke-gcloud-auth-plugin バイナリをインストールします。sudo apt-get install -y kubectl google-cloud-sdk-gke-gcloud-auth-plugin
GKE クラスタの認証情報を取得します。
export USE_GKE_GCLOUD_AUTH_PLUGIN=True gcloud container clusters get-credentials CLUSTER --zone ZONE
デフォルトの ClientConfig リソースにパッチを適用します。
kubectl patch clientconfig default \ --namespace kube-public \ --patch-file client-config-patch.yaml \ --type merge
パッチされたデフォルトの ClientConfig リソースから
certificateAuthorityData
フィールドを抽出し、それをcertificateAuthorityData.pem
というファイルに保存します。kubectl get clientconfig default \ --namespace kube-public \ --output jsonpath='{.spec.certificateAuthorityData}' \ | base64 --decode > certificateAuthorityData.pem
パッチされたデフォルトの ClientConfig リソースからサーバー フィールドを抽出し、それを
server.txt
というファイルに保存します。kubectl get clientconfig default \ --namespace kube-public \ --output jsonpath='{.spec.server}' > server.txt
SSH セッションを終了します。
exit
(省略可)クラスタ構成を確認する
続行する前に、Identity Service for GKE がクラスタで正しく設定されていることを確認できます。設定を確認するには、VM インスタンスに接続された Google サービス アカウントを使用して、Identity Service for GKE を使用するクラスタに対して認証を行います。
Cloud Shell で、Google サービス アカウントのサービス アカウントの OpenID Connect ID トークン作成者をサービス アカウント自体に付与します。
gcloud iam service-accounts add-iam-policy-binding \ ISG_GSA@PROJECT_ID.iam.gserviceaccount.com \ --member serviceAccount:ISG_GSA@PROJECT_ID.iam.gserviceaccount.com \ --role roles/iam.serviceAccountOpenIdTokenCreator
このロールは、Service Account Credentials API からサービス アカウントの ID トークンをリクエストするために必要な
iam.serviceAccounts.getOpenIdToken
権限を提供します。SSH を使用して VM インスタンスに接続します。
gcloud compute ssh VM --tunnel-through-iap --zone ZONE
このセクションの残りのコマンドは、SSH セッションから実行します。
VM インスタンスに接続されている Google サービス アカウントのメタデータ サーバーから、リクエストされた
aud
(audience)クレームとして OAuth クライアント ID を使用して、OAuth 2.0 アクセス トークンをリクエストします。ACCESS_TOKEN=$(curl --silent --header "Metadata-Flavor: Google" \ http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token \ | python3 -c 'import json, sys; print(json.load(sys.stdin).get("access_token"))')
メタデータ サーバーからのレスポンス本文は JSON ドキュメントです。このコマンドは、インライン Python スクリプトを使用して、レスポンス本文から
access_token
フィールドを抽出します。VM インスタンスに接続された Google サービス アカウントの Service Account Credentials API から ID トークンをリクエストします。
ID_TOKEN=$(curl --silent --request POST \ --data '{"audience": "CLIENT_ID", "includeEmail": true}' \ --header "Authorization: Bearer $ACCESS_TOKEN" \ --header "Content-Type: application/json; charset=utf-8" \ "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/ISG_GSA@PROJECT_ID.iam.gserviceaccount.com:generateIdToken" \ | python3 -c 'import json, sys; print(json.load(sys.stdin).get("token"))')
上記のコマンドについて、次の点に注意してください。
- リクエスト本文の JSON の
audience
フィールドには、ID トークンのリクエストされたaud
(audience)クレームを指定します。 - 前のステップからのアクセス トークンを使用して API の認証を行います。
- リクエスト本文の JSON の
ID トークンでクレームを表示します。
echo $ID_TOKEN \ | cut -d. -f2 \ | base64 --decode --ignore-garbage 2> /dev/null \ | python3 -m json.tool
email
クレームに Google サービス アカウントのメールアドレスが含まれていることを確認します。Identity Service for GKE で ID トークンを使用して、コントロール プレーンを認証します。
kubectl get namespaces \ --certificate-authority certificateAuthorityData.pem \ --server $(cat server.txt) \ --token $ID_TOKEN
出力は次のようになります。
Error from server (Forbidden): namespaces is forbidden: User "ISG_GSA@PROJECT_ID.iam.gserviceaccount.com" cannot list resource "namespaces" in API group "" at the cluster scope
これは予想されるエラーです。Google サービス アカウントにはプロジェクトの GKE クラスタに対する IAM 権限が付与されていますが、Identity Service for GKE を使用して認証する場合は IAM の権限は適用されません。代わりに、Kubernetes ロールベースのアクセス制御(RBAC)を使用してアクセス権を構成します。
サービス アカウントが Google の OpenID Connect プロバイダを使用してクラスタに対する認証を行うときに、Google サービス アカウントに
view
クラスタロールを付与するクラスタロール バインディングを作成します。kubectl create clusterrolebinding ISG_GSA-cluster-view \ --clusterrole view \ --user ISG_GSA@PROJECT_ID.iam.gserviceaccount.com
独自の環境で ClientConfig で
-
以外のuserPrefix
値を設定している場合は、このコマンドで--user
フラグの値に接頭辞を追加します。Identity Service for GKE を使用して GKE クラスタにアクセスします。
kubectl get namespaces \ --certificate-authority certificateAuthorityData.pem \ --server $(cat server.txt) \ --token $ID_TOKEN
出力は次のようになります。
NAME STATUS AGE anthos-identity-service Active 1h default Active 1h kube-node-lease Active 1h kube-public Active 1h kube-system Active 1h
SSH セッションを終了します。
exit
kubectl
ツールのコンテキストを作成する
kubectl
コマンドでは、kubeconfig ファイルを使用してクラスタへのアクセス権を構成できます。kubeconfig ファイルには、1 つ以上のコンテキストが含まれています。各コンテキストには名前があり、必要に応じてクラスタの接続情報、クラスタの認証に使用される認証情報、デフォルトの名前空間が含まれます。
このセクションでは、コンテキストを持つ kubeconfig ファイルを作成します。コンテキストには、クラスタの Identity Service for GKE プロキシの接続の詳細が含まれます。kubeconfig ファイルには、ユーザー認証情報は追加しません。
Cloud Shell で、認証局データとサーバー URL を含むファイルを VM インスタンスから現在のディレクトリにコピーします。
gcloud compute scp VM:~/certificateAuthorityData.pem VM:~/server.txt . \ --tunnel-through-iap --zone ZONE
後で、Cloud Build から GKE クラスタに接続する際に使用するコンテキストとクラスタ構成を作成します。
kubectl config set-context private-cluster \ --cluster private-cluster \ --kubeconfig kubeconfig
--kubeconfig
フラグをによって、現在のディレクトリに kubeconfig という新しいファイル内にコンテキストとクラスタ構成が作成されます。このコマンドは、GKE クラスタ名をコンテキストのクラスタ構成名として使用します。独自の環境では、コンテキストで別のクラスタ構成名を使用できます。
クラスタ構成に
certificateAuthorityData
フィールドを設定します。kubectl config set-cluster private-cluster \ --certificate-authority certificateAuthorityData.pem \ --embed-certs \ --kubeconfig kubeconfig
クラスタ構成に
server
フィールドを設定します。kubectl config set-cluster private-cluster \ --kubeconfig kubeconfig \ --server $(cat server.txt)
Cloud Build 用の Google サービス アカウントを作成する
Cloud Shell で、Cloud Build プライベート プールでビルドを実行する Google サービス アカウントを作成します。
gcloud iam service-accounts create CB_GSA \ --description "Runs builds on Cloud Build private pools" \ --display-name "Cloud Build private pool"
CB_GSA は、Google サービス アカウントに使用する名前に置き換えます。このチュートリアルでは、
cloud-build-private-pool
を使用します。プロジェクトの Cloud Build サービス アカウント ロールを Google サービス アカウントに付与します。
gcloud projects add-iam-policy-binding PROJECT_ID \ --member serviceAccount:CB_GSA@PROJECT_ID.iam.gserviceaccount.com \ --role roles/cloudbuild.builds.builder
このロールは、Google が管理する Cloud Build サービス アカウントのデフォルトの権限を提供します。
Google サービス アカウントの サービス アカウントの OpenID Connect ID トークン作成者をサービス アカウント自体に付与します。
gcloud iam service-accounts add-iam-policy-binding \ CB_GSA@PROJECT_ID.iam.gserviceaccount.com \ --member serviceAccount:CB_GSA@PROJECT_ID.iam.gserviceaccount.com \ --role roles/iam.serviceAccountOpenIdTokenCreator
このロールは、Service Account Credentials API からサービス アカウントの ID トークンをリクエストするために必要な
iam.serviceAccounts.getOpenIdToken
権限を提供します。SSH を使用して VM インスタンスに接続します。
gcloud compute ssh VM --tunnel-through-iap --zone ZONE
このセクションの残りのコマンドは、SSH セッションから実行します。
SSH セッションで、サービス アカウントが Google の OpenID Connect プロバイダを使用してクラスタを認証するときに、Google サービス アカウントに
cluster-admin
クラスタロールを付与する Kubernetes クラスタのロール バインディングを作成します。kubectl create clusterrolebinding CB_GSA-cluster-admin \ --clusterrole cluster-admin \ --user CB_GSA@PROJECT_ID.iam.gserviceaccount.com
cluster-admin
クラスタロールは、クラスタ全体にわたる広範な権限を付与します。独自の環境では、Cloud Build が実行するタスクに必要な権限のみを提供するクラスタロールを使用できます。ロール バインディングを使用して、特定の名前空間にのみ権限を付与することもできます。独自の環境の ClientConfig で
userPrefix
を設定する場合は、このコマンドで--user
フラグの値にその接頭辞を追加する必要があります。SSH セッションを終了します。
exit
Cloud Build プライベート プールを作成します。
Cloud Shell で、プライベート プールとの接続用に VPC ネットワーク内の IP アドレス範囲を割り当てます。
gcloud compute addresses create RESERVED_RANGE_NAME \ --addresses RESERVED_RANGE_START_IP\ --description "Cloud Build private pool reserved range" \ --global \ --network NETWORK \ --prefix-length RESERVED_RANGE_PREFIX_LENGTH \ --purpose VPC_PEERING
次のように置き換えます。
- RESERVED_RANGE_NAME: Cloud Build プライベート プールをホストする割り当てられた IP アドレス範囲の名前。このチュートリアルでは、
cloud-build-private-pool
を使用します。 - RESERVED_RANGE_START_IP: 割り当てられた IP アドレス範囲の最初の IP アドレス。このチュートリアルでは、
192.168.12.0
を使用します。 - RESERVED_RANGE_PREFIX_LENGTH: 割り当てられた IP アドレス範囲の接頭辞長(サブネット マスク)。接頭辞長は
/23
以下(たとえば、/22
、/21
)である必要があります。より小さい数が、より大きいアドレス範囲を意味します。このチュートリアルでは、23
を使用し、先頭の/
(スラッシュ)は入力しないでください。
- RESERVED_RANGE_NAME: Cloud Build プライベート プールをホストする割り当てられた IP アドレス範囲の名前。このチュートリアルでは、
ファイアウォール ルールを作成して、予約済み IP アドレス範囲から VPC ネットワーク内の他のリソースへの受信トラフィックを許可します。
gcloud compute firewall-rules create allow-private-pools-ingress \ --allow all \ --network NETWORK \ --source-ranges RESERVED_RANGE_START_IP/RESERVED_RANGE_PREFIX_LENGTH
プライベート サービス接続を作成して、VPC ネットワークをサービス ネットワーキング サービスに接続します。
gcloud services vpc-peerings connect \ --network NETWORK \ --ranges RESERVED_RANGE_NAME \ --service servicenetworking.googleapis.com
Cloud Build のプライベート プールは、Service Networking を使用してワーカーを実行します。プライベート サービス接続によって、VPC ネットワーク ピアリング接続を使用して、VPC ネットワークが内部 IP アドレスの割り当てられた範囲のプライベート プールと通信できるようになります。
プライベート サービス接続の作成には数分かかる可能性があります。
独自の環境で共有 VPC を使用している場合、プライベート サービス接続を作成する追加の手順については、環境を設定するをご覧ください。
VPC ネットワークに VPC ピアリングされる Google 所有の VPC ネットワークに Cloud Build プライベート プールを作成します。
gcloud builds worker-pools create PRIVATE_POOL_NAME \ --no-public-egress \ --peered-network projects/PROJECT_ID/global/networks/NETWORK \ --region REGION
次のように置き換えます。
- PRIVATE_POOL_NAME: プライベート プールの名前。このチュートリアルでは、
private-pool
を使用します。 - REGION: プライベート プールに使用するリージョン。このチュートリアルでは、
us-central1
を使用します。
--no-public-egress
フラグは、プライベート プール内のワーカーにパブリック IP アドレスがないことを意味します。独自の環境では、プライベート プール内のワーカーがパブリック IP アドレスを使用してインターネットに接続できるようにする場合は、このフラグを削除します。プライベート プール内のワーカーのマシンタイプやディスクサイズなどの追加の構成オプションについては、プライベート プールの作成と管理をご覧ください。
- PRIVATE_POOL_NAME: プライベート プールの名前。このチュートリアルでは、
問題の解決を確認する
このセクションでは、Cloud Build プライベート プールでビルドを実行してソリューションを確認します。ビルドが限定公開 GKE クラスタにアクセスします。
Cloud Shell で、Cloud Build のビルドログを保存する Cloud Storage バケットを作成します。
gsutil mb -l REGION gs://PROJECT_ID-build-logs
Cloud Build のビルド構成ファイルを作成します。
cat << "EOF" > cloudbuild.yaml steps: - id: list-services name: gcr.io/google.com/cloudsdktool/google-cloud-cli entrypoint: bash args: - -eEuo - pipefail - -c - |- kubectl config use-context $_KUBECTL_CONTEXT ACCESS_TOKEN=$$(curl --silent \ --header "Metadata-Flavor: Google" \ http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token \ | python3 -c 'import json, sys; print(json.load(sys.stdin).get("access_token"))') ID_TOKEN=$$(curl --silent --request POST \ --data '{"audience": "CLIENT_ID", "includeEmail": true}' \ --header "Authorization: Bearer $$ACCESS_TOKEN" \ --header "Content-Type: application/json; charset=utf-8" \ "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/$_SERVICE_ACCOUNT:generateIdToken" \ | python3 -c 'import json, sys; print(json.load(sys.stdin).get("token"))') kubectl get services --namespace $_NAMESPACE --token $$ID_TOKEN logsBucket: gs://PROJECT_ID-build-logs options: env: - KUBECONFIG=/workspace/$_KUBECONFIG substitutions: _KUBECONFIG: kubeconfig _KUBECTL_CONTEXT: private-cluster _NAMESPACE: default serviceAccount: projects/$PROJECT_ID/serviceAccounts/$_SERVICE_ACCOUNT EOF
ビルド構成ファイルの手順では、次のようにします。
_KUBECTL_CONTEXT
置換で指定されたkubectl
コンテキストに切り替わります。デフォルトの置換値はprivate-cluster
です。メタデータ サーバーのアクセス トークンを取得します。アクセス トークンは、ビルドを実行する Google サービス アカウントに発行されます。
Service Account Credentials API を使用して ID トークンを生成します。ID トークンを生成するリクエストは、アクセス トークンを使用して認証されます。ID トークンのリクエストされた
_CLIENT_ID
(audience)クレームが、aud
置換で指定された OAuth 2.0 クライアント ID です。_NAMESPACE
置換で指定された名前空間内の Kubernetes サービスを一覧表示します。デフォルトの置換値はdefault
です。リクエストは、前のコマンドで生成された ID トークンを使用して認証されます。
ビルド構成ファイルについて次の点に注意してください。
$
文字は置換の接頭辞です。$$
は、bash パラメータの拡張とコマンドの置換に使用されます。置換
_KUBECONFIG
と_KUBECTL_CONTEXT
によって、ビルドの実行時に異なる kubeconfig ファイルと異なるコンテキストを指定できます。これらの置換によって、複数のコンテキストを含む単一の kubeconfig ファイルと複数の kubeconfig ファイルのいずれかを使用して、複数のクラスタ構成を管理できます。置換
_SERVICE_ACCOUNT
にはデフォルト値がありません。ビルドを実行するときは、この置換の値を指定する必要があります。options
ブロックはビルドのすべての手順にKUBECONFIG
環境変数を設定します。ビルド手順では、
gcr.io/google.com/cloudsdktool/google-cloud-cli
ビルダー イメージを使用します。これは大きなコンテナ イメージであり、レジストリからプライベート プールワーカーにそれを pull するにはいくらかの時間がかかります。ビルダー イメージを pull する時間を短縮するには、curl
、kubectl
、Python などのビルド手順に必要なツールのみを含むカスタム ビルダー イメージを作成します。
ビルド構成ファイルのインライン シェル スクリプトの詳細については、bash スクリプトの実行をご覧ください。
ビルド構成ファイルと現在のディレクトリ内のファイルを使用してビルドを実行します。
gcloud builds submit \ --config cloudbuild.yaml \ --region REGION \ --substitutions _SERVICE_ACCOUNT=CB_GSA@PROJECT_ID.iam.gserviceaccount.com \ --worker-pool projects/PROJECT_ID/locations/REGION/workerPools/PRIVATE_POOL_NAME
コマンドは、現在のディレクトリ内のすべてのファイルを、Cloud Build による使用のために Cloud Storage にアップロードします。ビルド手順では、kubeconfig ファイルを使用して GKE クラスタに接続します。
出力の終わり付近に、次のような行が表示されます。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 2h
この出力は、プライベート プール ワーカーが Identity Service for GKE 認証プロキシを使用してクラスタ コントロール プレーンに接続していることを示しています。
トラブルシューティング
SSH を使用して VM インスタンスに接続できない場合は、--troubleshoot
フラグを追加して接続の問題の原因の究明に役立てます。
gcloud compute ssh VM --tunnel-through-iap --zone ZONE --troubleshoot
GKE クラスタでデフォルトの ClientConfig にパッチを適用したときにメッセージ Error from server (NotFound): clientconfigs.authentication.gke.io "default" not found
が表示された場合、限定公開 GKE クラスタの作成セクションの説明のとおりに、ファイアウォール ルールが作成されていることを確認してください。そのファイアウォール ルールが存在することを確認します。
gcloud compute firewall-rules describe allow-control-plane-clientconfig-webhook
Identity Service for GKE プロキシで認証できない場合は、gke-oidc-service
deployment の Pod のログでエラーを探します。
gcloud compute ssh VM --tunnel-through-iap --zone ZONE --command \
'kubectl logs deployment/gke-oidc-service \
--namespace anthos-identity-service --all-containers'
このチュートリアルで他の問題が発生した場合は、次のドキュメントを確認することをおすすめします。
クリーンアップ
このチュートリアルで使用したリソースについて、Google Cloud アカウントに課金されないようにするには、リソースを含むプロジェクトを削除するか、プロジェクトを維持して個々のリソースを削除します。
プロジェクトの削除
Delete a Google Cloud project:
gcloud projects delete PROJECT_ID
リソースを削除する
このチュートリアルで使用したプロジェクトを残しておく場合は、個々のリソースを削除します。
Cloud Shell で、Cloud Build プライベート プールを削除します。
gcloud builds worker-pools delete PRIVATE_POOL_NAME --region REGION --quiet
サービス ネットワーキングへのプライベート サービス接続を削除します。
gcloud services vpc-peerings delete --network NETWORK \ --service servicenetworking.googleapis.com --quiet --async
Cloud Build プライベート プールに割り当てられた IP アドレス範囲を削除します。
gcloud compute addresses delete RESERVED_RANGE_NAME --global --quiet
Cloud Storage バケットとそのすべての内容を削除します。
gsutil rm -r gs://PROJECT_ID-build-logs
GKE クラスタを削除します。
gcloud container clusters delete CLUSTER --zone ZONE --quiet --async
Compute Engine VM インスタンスを削除します。
gcloud compute instances delete VM --zone ZONE --quiet
ファイアウォール ルールを削除します。
gcloud compute firewall-rules delete allow-private-pools-ingress --quiet gcloud compute firewall-rules delete allow-ssh-ingress-from-iap --quiet gcloud compute firewall-rules delete allow-control-plane-clientconfig-webhook --quiet
IAM ロール バインディングを削除します。
gcloud projects remove-iam-policy-binding PROJECT_ID \ --member serviceAccount:CB_GSA@PROJECT_ID.iam.gserviceaccount.com \ --role roles/cloudbuild.builds.builder gcloud projects remove-iam-policy-binding PROJECT_ID \ --member serviceAccount:ISG_GSA@PROJECT_ID.iam.gserviceaccount.com \ --role roles/container.admin gcloud iam service-accounts remove-iam-policy-binding \ CB_GSA@PROJECT_ID.iam.gserviceaccount.com \ --member serviceAccount:CB_GSA@PROJECT_ID.iam.gserviceaccount.com \ --role roles/iam.serviceAccountOpenIdTokenCreator gcloud iam service-accounts remove-iam-policy-binding \ ISG_GSA@PROJECT_ID.iam.gserviceaccount.com \ --member serviceAccount:ISG_GSA@PROJECT_ID.iam.gserviceaccount.com \ --role roles/iam.serviceAccountOpenIdTokenCreator
Google サービス アカウントを削除します。
gcloud iam service-accounts delete CB_GSA@PROJECT_ID.iam.gserviceaccount.com \ --quiet gcloud iam service-accounts delete ISG_GSA@PROJECT_ID.iam.gserviceaccount.com \ --quiet
OAuth 2.0 クライアント ID を削除する
Google Cloud コンソールの [認証情報] ページに移動します。
プロジェクト セレクタのリストからプロジェクトを選択します。
[OAuth 2.0 クライアント ID] の表で、Identity Service for GKE の行を見つけて、[OAuth クライアントを削除] アイコンをクリックします。
ダイアログで [削除] をクリックします。
次のステップ
- Connect Gateway で Cloud Build から Anthos clusters にアクセスする方法を学習します。
- Cloud VPN を使用して Cloud Build プライベート プールで限定公開 GKE クラスタにアクセスする方法を学習する。
- コントロール プレーン アクセス用のネットワーク プロキシを持つ GKE 限定公開クラスタを作成する方法を学習します。
- 静的外部 IP を使用してプライベート ネットワーク内の外部リソースにアクセスする方法を学習します。
- GKE Identity Service を確認する。GKE Identity Service によって、一連の Anthos clusters にわたって外部 ID プロバイダ認証を管理できます。