Envoy でサービス セキュリティを設定する
このガイドでは、Cloud Service Mesh と Envoy プロキシでデプロイされたサービスの認証と認可を構成する手順について説明します。Cloud Service Mesh サービスのセキュリティの詳細については、Cloud Service Mesh サービスのセキュリティをご覧ください。
要件
Envoy で Cloud Service Mesh のサービス セキュリティを構成する前に、次の前提条件を満たしていることを確認してください。
Cloud Service Mesh をデプロイするためのすべての要件を満たす必要があります。これらの要件の詳細については、Envoy とプロキシレス ワークロードを使用したサービス ルーティング API の設定の準備をご覧ください。
Envoy とプロキシレス ワークロードを使用したサービス ルーティング API の設定の準備で説明されているように、サービス セキュリティを使用するための Cloud Service Mesh とGoogle Cloud サービス メッシュ リソースを作成または更新するのに十分な権限を持っている必要があります。
設定を準備する
以降のセクションでは、Cloud Service Mesh セキュリティ サービスを設定する前に完了しておく必要のあるタスクについて説明します。タスクは次のとおりです。
- Google Cloud CLI の更新
- 変数の設定
- Cloud Service Mesh が Certificate Authority Service と連携するために必要な API の有効化
gcloud コマンドライン ツールを更新する
Google Cloud CLI を更新するには、ローカルマシンで次のコマンドを実行します。
gcloud components update
環境変数を設定する
このドキュメントの例では、一貫した値を含むコードをコピーして貼り付けできるように、次の変数を設定します。次の値を使用します。
- PROJECT_ID: プロジェクトの ID に置き換えます。
- CLUSTER_NAME: 使用するクラスタ名(
secure-td-clusterなど)に置き換えます。 - ZONE: クラスタが配置されているゾーンに置き換えます。
- GKE_CLUSTER_URL:
https://container.googleapis.com/v1/projects/PROJECT_ID/locations/ZONE/clusters/CLUSTER_NAMEに置き換えます。 - WORKLOAD_POOL:
PROJECT_ID.svc.id.googに置き換えます。 - K8S_NAMESPACE:
defaultに置き換えます。 - DEMO_CLIENT_KSA: 実際のクライアントの Kubernetes サービス アカウントの名前に置き換えます。
- DEMO_SERVER_KSA: 実際のサーバーの Kubernetes サービス アカウントの名前に置き換えます。
PROJNUM: プロジェクトのプロジェクト番号に置き換えます。プロジェクト番号は、 Google Cloud コンソールまたは次のコマンドで確認できます。
gcloud projects describe PROJECT_ID --format="value(projectNumber)"
SA_GKE:
service-PROJNUM@container-engine-robot.iam.gserviceaccount.comに置き換えます。CLUSTER_VERSION: 利用可能な最新のバージョンに置き換えます。詳細については、Rapid チャンネルのリリースノートをご覧ください。必要な最小バージョンは 1.21.4-gke.1801 です。これは、この例で使用する GKE クラスタ バージョンです。
ここで値を設定します。
# Substitute your project ID PROJECT_ID=PROJECT_ID # GKE cluster name and zone for this example. CLUSTER_NAME=CLUSTER_NAME ZONE=ZONE # GKE cluster URL derived from the above GKE_CLUSTER_URL="https://container.googleapis.com/v1/projects/PROJECT_ID/locations/ZONE/clusters/CLUSTER_NAME" # Workload pool to be used with the GKE cluster WORKLOAD_POOL="PROJECT_ID.svc.id.goog" # Kubernetes namespace to run client and server demo. K8S_NAMESPACE=K8S_NAMESPACE DEMO_CLIENT_KSA=DEMO_CLIENT_KSA DEMO_SERVER_KSA=DEMO_SERVER_KSA # Compute other values # Project number for your project PROJNUM=PROJNUM CLUSTER_VERSION=CLUSTER_VERSION SA_GKE=service-PROJNUM@container-engine-robot.iam.gserviceaccount.com
API を有効にする
gcloud services enable コマンドを使用して、Certificate Authority Service で Cloud Service Mesh のセキュリティを設定するために必要なすべての API を有効にします。
gcloud services enable \ container.googleapis.com \ cloudresourcemanager.googleapis.com \ compute.googleapis.com \ trafficdirector.googleapis.com \ networkservices.googleapis.com \ networksecurity.googleapis.com \ privateca.googleapis.com \ gkehub.googleapis.com
GKE クラスタを作成または更新する
Cloud Service Mesh サービスのセキュリティは、GKE との CA Service 統合に依存します。GKE クラスタは、設定要件に加えて、次の要件を満たしている必要があります。
- 1.21.4-gke.1801 の最小クラスタ バージョンを使用します。新しいバージョンの機能が必要な場合は、Rapid リリース チャンネルからそのバージョンを取得できます。
- 証明書を発行する認証局を作成するで説明されているように、GKE クラスタを有効にして、メッシュ証明書で構成する必要があります。
Workload Identity Federation for GKE を使用する新しいクラスタを作成します。既存のクラスタを更新する場合は、次のステップに進みます。
--tagsに指定する値は、Cloud Load Balancing コンポーネントを使用した Cloud Service Mesh を構成するセクションで説明しているfirewall-rules createコマンドの--target-tagsフラグに渡される名前と一致している必要があります。# Create a GKE cluster with GKE managed mesh certificates. gcloud container clusters create CLUSTER_NAME \ --release-channel=rapid \ --scopes=cloud-platform \ --image-type=cos_containerd \ --machine-type=e2-standard-2 \ --zone=ZONE \ --workload-pool=PROJECT_ID.svc.id.goog \ --enable-mesh-certificates \ --cluster-version=CLUSTER_VERSION \ --enable-ip-alias \ --tags=allow-health-checks \ --workload-metadata=GKE_METADATA
クラスタの作成が完了するまでに数分かかることがあります。
既存のクラスタを使用している場合は、Workload Identity Federation for GKE と GKE メッシュ証明書を有効にします。クラスタが
--enable-ip-aliasフラグで作成されていることを確認してください。このフラグは、updateコマンドでは使用できません。gcloud container clusters update CLUSTER_NAME \ --enable-mesh-certificates
次のコマンドを実行して、
kubectlコマンドのデフォルト クラスタとして新しいクラスタに切り替えます。gcloud container clusters get-credentials CLUSTER_NAME \ --zone ZONE
マルチクラスタ環境でのデプロイ
マルチクラスタ環境にデプロイする場合は、このセクションで説明する一般的な手順を行います。以下の手順は、一方のクラスタでクライアント Pod が実行され、もう一方のクラスタでサーバー Pod が実行されていることを前提としています。
前のセクションの手順に沿って、クラスタを作成または更新します。
次のコマンドを使用して、各クラスタの Pod IP アドレス範囲を取得します。
gcloud compute firewall-rules list \ --filter="name~gke-{CLUSTER_NAME}-[0-9a-z]*-all" \ --format="value(sourceRanges)"たとえば、
cluster-aとcluster-bという名前のクラスタの場合、次のような結果が返されます。cluster-a, pod CIDR: 10.4.0.0/14, node network tag: gke-cluster-a-9cd18751-node cluster-b, pod CIDR: 10.8.0.0/14, node network tag: gke-cluster-b-acd14479-node
クラスタが互いに通信できるようにする VPC ファイアウォール ルールを作成します。たとえば、次のコマンドは、
cluster-aPod IP アドレスがcluster-bノードと通信できるようにするファイアウォール ルールを作成します。gcloud compute firewall-rules create per-cluster-a-pods \ --allow="tcp,udp,icmp,esp,ah,sctp" \ --target-tags="gke-cluster-b-acd14479-node"
次のコマンドは、
cluster-bPod IP アドレスがcluster-aノードと通信することを許可するファイアウォール ルールを作成します。gcloud compute firewall-rules create per-cluster-b-pods \ --allow="tcp,udp,icmp,esp,ah,sctp" \ --target-tags="gke-cluster-a-9cd18751-node"
フリートにクラスタを登録する
GKE クラスタの作成で作成または更新したクラスタをフリートに登録します。クラスタを登録すると、複数のプロジェクトにまたがるクラスタを簡単に構成できるようになります。
各ステップが完了するまでに最大で 10 分かかることがあります。
クラスタをフリートに登録します。
gcloud container fleet memberships register CLUSTER_NAME \ --gke-cluster=ZONE/CLUSTER_NAME \ --enable-workload-identity --install-connect-agent \ --manifest-output-file=MANIFEST-FILE_NAME
変数を、次のように置き換えます。
- CLUSTER_NAME: クラスタの名前。
- ZONE: クラスタのゾーン。
- MANIFEST-FILE_NAME: これらのコマンドが登録用のマニフェストを生成するパス。
登録プロセスが成功すると、次のようなメッセージが表示されます。
Finished registering the cluster CLUSTER_NAME with the fleet.
生成されたマニフェスト ファイルをクラスタに適用します。
kubectl apply -f MANIFEST-FILE_NAME
適用プロセスが成功すると、次のようなメッセージが表示されます。
namespace/gke-connect created serviceaccount/connect-agent-sa created podsecuritypolicy.policy/gkeconnect-psp created role.rbac.authorization.k8s.io/gkeconnect-psp:role created rolebinding.rbac.authorization.k8s.io/gkeconnect-psp:rolebinding created role.rbac.authorization.k8s.io/agent-updater created rolebinding.rbac.authorization.k8s.io/agent-updater created role.rbac.authorization.k8s.io/gke-connect-agent-20210416-01-00 created clusterrole.rbac.authorization.k8s.io/gke-connect-impersonation-20210416-01-00 created clusterrolebinding.rbac.authorization.k8s.io/gke-connect-impersonation-20210416-01-00 created clusterrolebinding.rbac.authorization.k8s.io/gke-connect-feature-authorizer-20210416-01-00 created rolebinding.rbac.authorization.k8s.io/gke-connect-agent-20210416-01-00 created role.rbac.authorization.k8s.io/gke-connect-namespace-getter created rolebinding.rbac.authorization.k8s.io/gke-connect-namespace-getter created secret/http-proxy created deployment.apps/gke-connect-agent-20210416-01-00 created service/gke-connect-monitoring created secret/creds-gcp create
クラスタからメンバー リソースを取得します。
kubectl get memberships membership -o yaml
出力には、フリートによって割り当てられた Workoad Identity プールが含まれています。ここで、PROJECT_ID はプロジェクト ID です。
workload_identity_pool: PROJECT_ID.svc.id.goog
これは、クラスタが正常に登録されたことを意味します。
証明書を発行する認証局を作成する
Pod に対して証明書を発行するには、CA Service プールと次の認証局(CA)を作成します。
- ルート CA。これは、発行されるすべてのメッシュ証明書のルート オブ トラストです。既存のルート CA が存在する場合はそれを使用できます。ルート CA を
enterprise階層に作成します。ルート CA は有効期間が長く、少量の証明書の発行に適しています。 - 下位 CA。この CA はワークロード用の証明書を発行します。クラスタがデプロイされるリージョンで下位 CA を作成します。下位 CA を
devops階層に作成します。下位 CA は有効期間が短く、大量の証明書の発行に適しています。
下位 CA の作成は任意ですが、GKE メッシュの証明書を発行するためにルート CA を使用するよりも、下位 CA を作成することを強くおすすめします。ルート CA を使用してメッシュ証明書を発行する場合は、デフォルトの構成ベースの発行モードが引き続き許可されることを確認してください。
下位 CA はクラスタと異なるリージョンに設定できますが、パフォーマンスを最適化するために、クラスタと同じリージョンに作成することをおすすめします。ただし、ルート CA または下位 CA は別々のリージョンに作成でき、それによるパフォーマンスや可用性への影響はありません。
CA Service では、以下のリージョンがサポートされます。
| リージョン名 | リージョンの説明 |
|---|---|
asia-east1 |
台湾 |
asia-east2 |
香港 |
asia-northeast1 |
東京 |
asia-northeast2 |
大阪 |
asia-northeast3 |
ソウル |
asia-south1 |
ムンバイ |
asia-south2 |
デリー |
asia-southeast1 |
シンガポール |
asia-southeast2 |
ジャカルタ |
australia-southeast1 |
シドニー |
australia-southeast2 |
メルボルン |
europe-central2 |
ワルシャワ |
europe-north1 |
フィンランド |
europe-southwest1 |
マドリッド |
europe-west1 |
ベルギー |
europe-west2 |
ロンドン |
europe-west3 |
フランクフルト |
europe-west4 |
オランダ |
europe-west6 |
チューリッヒ |
europe-west8 |
ミラノ |
europe-west9 |
パリ |
europe-west10 |
ベルリン |
europe-west12 |
トリノ |
me-central1 |
ドーハ |
me-central2 |
ダンマーム |
me-west1 |
テルアビブ |
northamerica-northeast1 |
モントリオール |
northamerica-northeast2 |
トロント |
southamerica-east1 |
サンパウロ |
southamerica-west1 |
サンティアゴ |
us-central1 |
アイオワ |
us-east1 |
サウスカロライナ |
us-east4 |
北バージニア |
us-east5 |
コロンバス |
us-south1 |
ダラス |
us-west1 |
オレゴン |
us-west2 |
ロサンゼルス |
us-west3 |
ソルトレイクシティ |
us-west4 |
ラスベガス |
サポートされているロケーションのリストを確認するには、次のコマンドを実行します。
gcloud privateca locations list
CA プールと CA を作成する個人に IAM
roles/privateca.caManagerを付与します。MEMBER の正しい形式はuser:userid@example.comです。その個人が現在のユーザーであれば、シェルコマンド$(gcloud auth list --filter=status:ACTIVE --format="value(account)")を使用してユーザー ID を取得できます。gcloud projects add-iam-policy-binding PROJECT_ID \ --member=MEMBER \ --role=roles/privateca.caManager
IAM ポリシーを変更する必要があるユーザーに CA Service のロール
role/privateca.adminを付与します。MEMBERは、このアクセスを必要とするユーザー(特に、この後の手順でprivateca.auditorロールとprivateca.certificateManagerロールの付与を実行するユーザー)です。gcloud projects add-iam-policy-binding PROJECT_ID \ --member=MEMBER \ --role=roles/privateca.admin
ルート CA Service プールを作成します。
gcloud privateca pools create ROOT_CA_POOL_NAME \ --location ROOT_CA_POOL_LOCATION \ --tier enterprise
ルート CA を作成します。
gcloud privateca roots create ROOT_CA_NAME --pool ROOT_CA_POOL_NAME \ --subject "CN=ROOT_CA_NAME, O=ROOT_CA_ORGANIZATION" \ --key-algorithm="ec-p256-sha256" \ --max-chain-length=1 \ --location ROOT_CA_POOL_LOCATION
このデモ設定では、変数に次の値を使用します。
- ROOT_CA_POOL_NAME=td_sec_pool
- ROOT_CA_NAME=pkcs2-ca
- ROOT_CA_POOL_LOCATION=us-east1
- ROOT_CA_ORGANIZATION="TestCorpLLC"
下位プールと下位 CA を作成します。デフォルトの構成ベースの発行モードが許可されることを確認します。
gcloud privateca pools create SUBORDINATE_CA_POOL_NAME \ --location SUBORDINATE_CA_POOL_LOCATION \ --tier devops
gcloud privateca subordinates create SUBORDINATE_CA_NAME \ --pool SUBORDINATE_CA_POOL_NAME \ --location SUBORDINATE_CA_POOL_LOCATION \ --issuer-pool ROOT_CA_POOL_NAME \ --issuer-location ROOT_CA_POOL_LOCATION \ --subject "CN=SUBORDINATE_CA_NAME, O=SUBORDINATE_CA_ORGANIZATION" \ --key-algorithm "ec-p256-sha256" \ --use-preset-profile subordinate_mtls_pathlen_0
このデモ設定では、変数に次の値を使用します。
- SUBORDINATE_CA_POOL_NAME="td-ca-pool"
- SUBORDINATE_CA_POOL_LOCATION=us-east1
- SUBORDINATE_CA_NAME="td-ca"
- SUBORDINATE_CA_ORGANIZATION="TestCorpLLC"
- ROOT_CA_POOL_NAME=td_sec_pool
- ROOT_CA_POOL_LOCATION=us-east1
GKE サービス アカウントからのアクセスを許可するために、ルート CA プールの IAM
privateca.auditorロールを付与します。gcloud privateca pools add-iam-policy-binding ROOT_CA_POOL_NAME \ --location ROOT_CA_POOL_LOCATION \ --role roles/privateca.auditor \ --member="serviceAccount:service-PROJNUM@container-engine-robot.iam.gserviceaccount.com"
GKE サービス アカウントからのアクセスを許可するために、下位 CA プールの IAM
privateca.certificateManagerロールを付与します。gcloud privateca pools add-iam-policy-binding SUBORDINATE_CA_POOL_NAME \ --location SUBORDINATE_CA_POOL_LOCATION \ --role roles/privateca.certificateManager \ --member="serviceAccount:service-PROJNUM@container-engine-robot.iam.gserviceaccount.com"
次の
WorkloadCertificateConfigYAML 構成を保存して、メッシュ証明書を発行する方法をクラスタに指示します。apiVersion: security.cloud.google.com/v1 kind: WorkloadCertificateConfig metadata: name: default spec: # Required. The CA service that issues your certificates. certificateAuthorityConfig: certificateAuthorityServiceConfig: endpointURI: ISSUING_CA_POOL_URI # Required. The key algorithm to use. Choice of RSA or ECDSA. # # To maximize compatibility with various TLS stacks, your workloads # should use keys of the same family as your root and subordinate CAs. # # To use RSA, specify configuration such as: # keyAlgorithm: # rsa: # modulusSize: 4096 # # Currently, the only supported ECDSA curves are "P256" and "P384", and the only # supported RSA modulus sizes are 2048, 3072 and 4096. keyAlgorithm: rsa: modulusSize: 4096 # Optional. Validity duration of issued certificates, in seconds. # # Defaults to 86400 (1 day) if not specified. validityDurationSeconds: 86400 # Optional. Try to start rotating the certificate once this # percentage of validityDurationSeconds is remaining. # # Defaults to 50 if not specified. rotationWindowPercentage: 50次のように置き換えます。
- クラスタが実行されるプロジェクトのプロジェクト ID:
PROJECT_ID
- メッシュ証明書を発行する CA の完全修飾 URI(ISSUING_CA_POOL_URI)。下位 CA(推奨)またはルート CA のいずれかを指定できます。形式は次のとおりです。
//privateca.googleapis.com/projects/PROJECT_ID/locations/SUBORDINATE_CA_POOL_LOCATION/caPools/SUBORDINATE_CA_POOL_NAME
- クラスタが実行されるプロジェクトのプロジェクト ID:
次の
TrustConfigYAML 構成を保存して、発行済み証明書を信頼する方法をクラスタに指示します。apiVersion: security.cloud.google.com/v1 kind: TrustConfig metadata: name: default spec: # You must include a trustStores entry for the trust domain that # your cluster is enrolled in. trustStores: - trustDomain: PROJECT_ID.svc.id.goog # Trust identities in this trustDomain if they appear in a certificate # that chains up to this root CA. trustAnchors: - certificateAuthorityServiceURI: ROOT_CA_POOL_URI次のように置き換えます。
- クラスタが実行されるプロジェクトのプロジェクト ID:
PROJECT_ID
- ルート CA プールの完全修飾 URI(ROOT_CA_POOL_URI)。形式は次のとおりです。
//privateca.googleapis.com/projects/PROJECT_ID/locations/ROOT_CA_POOL_LOCATION/caPools/ROOT_CA_POOL_NAME
- クラスタが実行されるプロジェクトのプロジェクト ID:
この構成をクラスタに適用します。
kubectl apply -f WorkloadCertificateConfig.yaml kubectl apply -f TrustConfig.yaml
Identity and Access Management を構成する
設定に必要なリソースを作成するには、compute.NetworkAdmin ロールが必要です。このロールには、必要なリソースの作成、更新、削除、一覧表示、使用(他のリソースでの参照)に必要なすべての権限が含まれています。プロジェクトのオーナー編集者には、このロールが自動的に付与されます。
なお、これらのリソースをバックエンド サービスで参照する場合、networksecurity.googleapis.com.clientTlsPolicies.use と networksecurity.googleapis.com.serverTlsPolicies.use は適用されません。
今後これらの権限が適用され、compute.NetworkAdmin ロールを使用している場合、このチェックの適用時に問題は検出されません。
カスタムロールを使用していて、今後このチェックが適用される場合は、各 .use 権限を含める必要があります。そうしないと、バックエンド サービスまたはエンドポイント ポリシーから clientTlsPolicy または serverTlsPolicy を参照するために必要な権限がカスタムロールに付与されない場合があります。
次の手順では、デフォルトのサービス アカウントで Cloud Service Mesh Security API にアクセスし、Kubernetes サービス アカウントを作成します。
デフォルトのサービス アカウントが Cloud Service Mesh Security API にアクセスできるように IAM を構成します。
GSA_EMAIL=$(gcloud iam service-accounts list --format='value(email)' \ --filter='displayName:Compute Engine default service account') gcloud projects add-iam-policy-binding PROJECT_ID \ --member serviceAccount:${GSA_EMAIL} \ --role roles/trafficdirector.clientKubernetes サービス アカウントを設定します。次のセクションで説明するクライアントとサーバーのデプロイでは、Kubernetes サーバーとクライアントのサービス アカウント名を使用します。
kubectl create serviceaccount --namespace K8S_NAMESPACE DEMO_SERVER_KSA kubectl create serviceaccount --namespace K8S_NAMESPACE DEMO_CLIENT_KSA
Kubernetes サービス アカウントがデフォルトの Compute Engine サービス アカウントの権限を借用できるようにするには、両者の間に IAM ポリシー バインディングを作成します。このバインディングにより、Kubernetes サービス アカウントがデフォルトの Compute Engine サービス アカウントとして機能します。
gcloud iam service-accounts add-iam-policy-binding \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:PROJECT_ID.svc.id.goog[K8S_NAMESPACE/DEMO_SERVER_KSA]" ${GSA_EMAIL} gcloud iam service-accounts add-iam-policy-binding \ --role roles/iam.workloadIdentityUser \ --member "serviceAccount:PROJECT_ID.svc.id.goog[K8S_NAMESPACE/DEMO_CLIENT_KSA]" ${GSA_EMAIL}Kubernetes サービス アカウントにアノテーションを付け、デフォルトの Compute Engine サービス アカウントに関連付けます。
kubectl annotate --namespace K8S_NAMESPACE \ serviceaccount DEMO_SERVER_KSA \ iam.gke.io/gcp-service-account=${GSA_EMAIL} kubectl annotate --namespace K8S_NAMESPACE \ serviceaccount DEMO_CLIENT_KSA \ iam.gke.io/gcp-service-account=${GSA_EMAIL}
Cloud Service Mesh を設定する
次の手順に沿って、サイドカー インジェクタをインストールし、テストサービスを設定して、他のデプロイタスクを完了します。
クラスタに Envoy サイドカー インジェクタをインストールする
自動 Envoy インジェクションによる GKE Pod での Cloud Service Mesh の設定の以下の両セクションの手順に沿って、クラスタで Envoy サイドカー インジェクションをデプロイして有効にします。
- プロジェクト情報を構成する
- MutatingWebhookConfigurations のインストール。メッシュ名を
sidecar_mesh、ネットワークを空の文字列として構成します。 - サイドカー インジェクションを有効にする
テストサービスを設定する前に、両方の手順が完了していることを確認してください。
テストサービスを設定する
Envoy サイドカー インジェクタをインストールしたら、次の手順で Deployment のテストサービスを設定します。
wget -q -O - https://storage.googleapis.com/traffic-director/security/ga/service_sample.yaml | sed -e s/DEMO_SERVER_KSA_PLACEHOLDER/DEMO_SERVER_KSA/g > service_sample.yaml kubectl apply -f service_sample.yaml
ファイル service_sample.yaml には、デモサーバー アプリケーションの PodSpec が含まれています。Cloud Service Mesh セキュリティに固有のアノテーションも含まれます。
Cloud Service Mesh プロキシ メタデータ
PodSpec は proxyMetadata アノテーションを指定します。
spec:
...
annotations:
cloud.google.com/proxyMetadata: '{"app": "payments"}'
...
Pod が初期化されると、サイドカー プロキシはこのアノテーションを取得し、Cloud Service Mesh に送信します。Cloud Service Mesh はこの情報を使用して、フィルタされた構成を返します。
- このガイドの後半では、エンドポイント ポリシーでエンドポイント マッチャーが指定されます。
- エンドポイント マッチャーは、名前が
app、値がpaymentsのラベルを持つクライアントだけがフィルタされた構成を受信するよう指定します。
CA Service によって署名されたメッシュ証明書と鍵を使用する
PodSpec は enableManagedCerts アノテーションを指定します。
spec:
...
annotations:
...
cloud.google.com/enableManagedCerts: "true"
...
Pod が初期化されると、CA Service の署名付き証明書と鍵が自動的にローカル サイドカー プロキシ ファイル システムにマウントされます。
受信トラフィック インターセプト ポートを構成する
PodSpec は includeInboundPorts アノテーションを指定します。
spec:
...
annotations:
...
cloud.google.com/includeInboundPorts: "8000"
...
これは、サーバー アプリケーションが接続をリッスンするポートです。Pod が初期化されると、サイドカー プロキシはこのアノテーションを取得し、Cloud Service Mesh に送信します。Cloud Service Mesh はこの情報を使用してフィルタされた構成を返します。これにより、このポートへのすべての着信トラフィックが傍受され、セキュリティ ポリシーを適用できます。
ヘルスチェック ポートはアプリケーション ポートとは異なるものにする必要があります。そうしないと、ヘルスチェック ポートへの受信接続に同じセキュリティ ポリシーが適用され、接続が拒否されてサーバーが誤って異常としてマークされる可能性があります。
NEG を使用して GKE サービスを構成する
GKE サービスは、Cloud Service Mesh バックエンド サービスのバックエンドとして構成できるように、ネットワーク エンドポイント グループ(NEG)で公開されている必要があります。この設定ガイドで提供されている service_sample.yaml パッケージは、次のアノテーションで NEG 名 service-test-neg を使用します。
...
metadata:
annotations:
cloud.google.com/neg: '{"exposed_ports": {"80":{"name": "service-test-neg"}}}'
spec:
ports:
- port: 80
name: service-test
protocol: TCP
targetPort: 8000
service_sample.yaml ファイルを変更する必要はありません。
NEG の名前を保存する
NEG の名前を NEG_NAME 変数に保存します。
NEG_NAME="service-test-neg"
クライアント アプリケーションを GKE にデプロイする
次のコマンドを実行して、Envoy プロキシをサイドカーとして使用するデモ クライアントを起動します。これは、セキュリティ機能のデモに必要です。
wget -q -O - https://storage.googleapis.com/traffic-director/security/ga/client_sample.yaml | sed -e s/DEMO_CLIENT_KSA_PLACEHOLDER/DEMO_CLIENT_KSA/g > client_sample.yaml kubectl apply -f client_sample.yaml
クライアント PodSpec には、enableManagedCerts アノテーションのみが含まれます。これは、CA Service インスタンスによって署名された GKE マネージド メッシュ証明書と鍵に必要なボリュームをマウントするために必要です。
ヘルスチェック、ファイアウォール ルール、バックエンド サービスのリソースを構成する
このセクションでは、Cloud Service Mesh のヘルスチェック、ファイアウォール ルール、バックエンド サービス リソースを作成します。
ヘルスチェックを作成します。
gcloud compute health-checks create http td-gke-health-check \ --use-serving-port
ヘルス チェッカーの IP アドレス範囲を許可するファイアウォール ルールを作成します。
gcloud compute firewall-rules create fw-allow-health-checks \ --action ALLOW \ --direction INGRESS \ --source-ranges 35.191.0.0/16,130.211.0.0/22 \ --rules tcp
バックエンド サービスを作成し、バックエンド サービスにヘルスチェックを関連付けます。
gcloud compute backend-services create td-gke-service \ --global \ --health-checks td-gke-health-check \ --load-balancing-scheme INTERNAL_SELF_MANAGED
前に作成した NEG をバックエンドとしてバックエンド サービスに追加します。
gcloud compute backend-services add-backend td-gke-service \ --global \ --network-endpoint-group ${NEG_NAME} \ --network-endpoint-group-zone ZONE \ --balancing-mode RATE \ --max-rate-per-endpoint 5
Mesh リソースと HTTPRoute リソースを構成する
このセクションでは、Mesh リソースと HTTPRoute リソースを作成します。
Meshリソース仕様を作成し、mesh.yamlというファイルに保存します。name: sidecar-mesh interceptionPort: 15001
mesh.yamlファイルで指定しない場合、インターセプト ポートはデフォルトで15001になります。mesh.yaml 仕様を使用して
Meshリソースを作成します。gcloud network-services meshes import sidecar-mesh \ --source=mesh.yaml \ --location=global
HTTPRoute仕様を作成し、http_route.yamlというファイルに保存します。PROJECT_IDまたはPROJECT_NUMBERを使用できます。name: helloworld-http-route hostnames: - service-test meshes: - projects/PROJNUM/locations/global/meshes/sidecar-mesh rules: - action: destinations: - serviceName: "projects/PROJNUM/locations/global/backendServices/td-gke-service"
http_route.yamlファイルの仕様を使用して、HTTPRouteリソースを作成します。gcloud network-services http-routes import helloworld-http-route \ --source=http_route.yaml \ --location=global
Cloud Service Mesh の構成が完了し、認証ポリシーと認可ポリシーを構成できるようになりました。
サービス間のセキュリティを設定する
サービス間のセキュリティを設定するには、次のセクションの手順を使用します。
メッシュで mTLS を有効にする
メッシュに mTLS を設定するには、バックエンド サービスへの送信トラフィックを保護し、エンドポイントへの着信トラフィックを保護する必要があります。
ポリシー参照の形式
サーバー TLS ポリシー、クライアント TLS ポリシー、認証ポリシーを参照する場合は、次の形式にする必要があります。
projects/PROJECT_ID/locations/global/[serverTlsPolicies|clientTlsPolicies|authorizationPolicies]/[server-tls-policy|client-mtls-policy|authz-policy]
次に例を示します。
projects/PROJECT_ID/locations/global/serverTlsPolicies/server-tls-policy
projects/PROJECT_ID/locations/global/clientTlsPolicies/client-mtls-policy
projects/PROJECT_ID/locations/global/authorizationPolicies/authz-policy
バックエンド サービスへの送信トラフィックを保護する
送信トラフィックを保護するには、まず次のことを行うクライアント TLS ポリシーを作成します。
clientCertificateのプラグインとしてgoogle_cloud_private_spiffeを使用します。このプラグインは、Envoy が GKE マネージド メッシュ証明書をクライアント ID として使用するようにプログラミングします。serverValidationCaのプラグインとしてgoogle_cloud_private_spiffeを使用します。このプラグインは、Envoy が GKE マネージド メッシュ証明書をサーバー検証に使用するようにプログラミングします。
次に、バックエンド サービスにクライアント TLS ポリシーを接続します。これにより、以下が実行されます。
- クライアント TLS ポリシーの認証ポリシーを、バックエンド サービスのエンドポイトへの送信接続に適用します。
- SAN(サブジェクト代替名)は、接続先サーバーの正確な ID を表明するようにクライアントに指示します。
client-mtls-policy.yamlファイルにクライアント TLS ポリシーを作成します。name: "client-mtls-policy" clientCertificate: certificateProviderInstance: pluginInstance: google_cloud_private_spiffe serverValidationCa: - certificateProviderInstance: pluginInstance: google_cloud_private_spiffeクライアント TLS ポリシーをインポートします。
gcloud network-security client-tls-policies import client-mtls-policy \ --source=client-mtls-policy.yaml --location=globalクライアント TLS ポリシーをバックエンド サービスに接続します。これにより、クライアントからこのバックエンド サービスへのすべての送信リクエストに mTLS 認証が適用されます。
gcloud compute backend-services export td-gke-service \ --global --destination=demo-backend-service.yaml次の行を
demo-backend-service.yamlに追加します。securitySettings: clientTlsPolicy: projects/PROJECT_ID/locations/global/clientTlsPolicies/client-mtls-policy subjectAltNames: - "spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_SERVER_KSA"次の値をインポートします。
gcloud compute backend-services import td-gke-service \ --global --source=demo-backend-service.yaml必要に応じて、次のコマンドを実行して、リクエストが失敗するかどうかを確認します。クライアントがエンドポイントからの証明書を要求しているものの、エンドポイントがセキュリティ ポリシーでプログラミングされていないため、これは想定内の失敗となります。
# Get the name of the Podrunning Busybox. BUSYBOX_POD=$(kubectl get po -l run=client -o=jsonpath='{.items[0].metadata.name}') # Command to execute that tests connectivity to the service service-test. TEST_CMD="wget -q -O - service-test; echo" # Execute the test command on the pod. kubectl exec -it $BUSYBOX_POD -c busybox -- /bin/sh -c "$TEST_CMD"次のような出力が表示されます。
wget: server returned error: HTTP/1.1 503 Service Unavailable
エンドポイントへの受信トラフィックを保護する
受信トラフィックを保護するには、まず、次のことを行うサーバー TLS ポリシーを作成します。
serverCertificateのプラグインとしてgoogle_cloud_private_spiffeを使用します。このプラグインは、Envoy が GKE マネージド メッシュ証明書をサーバー ID として使用するようにプログラミングします。clientValidationCaのプラグインとしてgoogle_cloud_private_spiffeを使用します。これは、Envoy が GKE マネージド メッシュ証明書をクライアント検証に使用するようにプログラミングします。
サーバーの TLS ポリシー値を
server-mtls-policy.yamlというファイルに保存します。name: "server-mtls-policy" serverCertificate: certificateProviderInstance: pluginInstance: google_cloud_private_spiffe mtlsPolicy: clientValidationCa: - certificateProviderInstance: pluginInstance: google_cloud_private_spiffeサーバーの TLS ポリシーを作成します。
gcloud network-security server-tls-policies import server-mtls-policy \ --source=server-mtls-policy.yaml --location=globalエンドポイント マッチャーを含む
ep_mtls.yamlというファイルを作成し、サーバーの TLS ポリシーを接続します。endpointMatcher: metadataLabelMatcher: metadataLabelMatchCriteria: MATCH_ALL metadataLabels: - labelName: app labelValue: payments name: "ep" serverTlsPolicy: projects/PROJECT_ID/locations/global/serverTlsPolicies/server-mtls-policy type: SIDECAR_PROXYエンドポイント マッチャーをインポートします。
gcloud network-services endpoint-policies import ep \ --source=ep_mtls.yaml --location=global
設定を検証する
次の curl コマンドを実行します。リクエストが正常に完了すると、出力に x-forwarded-client-cert が表示されます。ヘッダーは、接続が mTLS 接続の場合にのみ出力されます。
# Get the name of the Podrunning Busybox.
BUSYBOX_POD=$(kubectl get po -l run=client -o=jsonpath='{.items[0].metadata.name}')
# Command to execute that tests connectivity to the service service-test.
TEST_CMD="wget -q -O - service-test; echo"
# Execute the test command on the pod.
kubectl exec -it $BUSYBOX_POD -c busybox -- /bin/sh -c "$TEST_CMD"
次のような出力が表示されます。
GET /get HTTP/1.1 Host: service-test content-length: 0 x-envoy-internal: true accept: */* x-forwarded-for: 10.48.0.6 x-envoy-expected-rq-timeout-ms: 15000 user-agent: curl/7.35.0 x-forwarded-proto: http x-request-id: redacted x-forwarded-client-cert: By=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_SERVER_KSA;Hash=Redacted;Subject="Redacted;URI=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA
x-forwarded-client-cert ヘッダーはサーバー側の Envoy によって挿入され、独自の ID(サーバー)とソース クライアントの ID が含まれます。クライアント ID とサーバー ID の両方が表示されているため、これは mTLS 接続のシグナルです。
認可ポリシーでサービスレベルのアクセスを構成する
この手順では、ホスト名が service-test、ポートが 8000、HTTP メソッドが GET の DEMO_CLIENT_KSA アカウントによってリクエストが送信されることを許可する認可ポリシーを作成します。認可ポリシーを作成する前に、認可を使用してアクセスを制限するの注意事項をお読みください。
authz-policy.yamlという名前のファイルを作成して認可ポリシーを作成します。action: ALLOW name: authz-policy rules: - sources: - principals: - spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA destinations: - hosts: - service-test ports: - 8000 methods: - GETポリシーをインポートします。
gcloud network-security authorization-policies import authz-policy \ --source=authz-policy.yaml \ --location=global
ep_mtls.yamlファイルに次の行を追加して、新しい承認ポリシーを参照するようにエンドポイント ポリシーを更新します。authorizationPolicy: projects/PROJECT_ID/locations/global/authorizationPolicies/authz-policy
エンドポイント ポリシーでは、Envoy サイドカー プロキシが
app:paymentsというラベルを持つ Pod への受信リクエストに対して、mTLS と承認ポリシーの両方を適用する必要があることを指定しています。ポリシーをインポートします。
gcloud network-services endpoint-policies import ep \ --source=ep_mtls.yaml --location=global
設定を検証する
次のコマンドを実行して設定を検証します。
# Get the name of the Podrunning Busybox.
BUSYBOX_POD=$(kubectl get po -l run=client -o=jsonpath='{.items[0].metadata.name}')
# Command to execute that tests connectivity to the service service-test.
# This is a valid request and will be allowed.
TEST_CMD="wget -q -O - service-test; echo"
# Execute the test command on the pod.
kubectl exec -it $BUSYBOX_POD -c busybox -- /bin/sh -c "$TEST_CMD"
予想される出力は次のようになります。
GET /get HTTP/1.1 Host: service-test content-length: 0 x-envoy-internal: true accept: */* x-forwarded-for: redacted x-envoy-expected-rq-timeout-ms: 15000 user-agent: curl/7.35.0 x-forwarded-proto: http x-request-id: redacted x-forwarded-client-cert: By=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_SERVER_KSA;Hash=Redacted;Subject="Redacted;URI=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA
次のコマンドを実行して、承認ポリシーが無効なリクエストを正しく却下するどうかをテストします。
# Failure case # Command to execute that tests connectivity to the service service-test. # This is an invalid request and server will reject because the server # authorization policy only allows GET requests. TEST_CMD="wget -q -O - service-test --post-data='' ; echo" # Execute the test command on the pod. kubectl exec -it $BUSYBOX_POD -c busybox -- /bin/sh -c "$TEST_CMD"
予想される出力は次のようになります。
<RBAC: access denied HTTP/1.1 403 Forbidden>
Ingress ゲートウェイ セキュリティを設定する
このセクションは、サイドカー自動インジェクタを使用した GKE クラスタの設定、認証局の作成、エンドポイント ポリシーの作成など、サービス間のセキュリティ セクションを完了していることを前提としています。
このセクションでは、TLS 接続を終端し、クラスタの内部クライアントからのリクエストを承認する Ingress ゲートウェイとして Envoy プロキシをデプロイします。
TLS を終端するように Ingress ゲートウェイを設定する手順は次のとおりです。
- クラスタの内部 IP アドレスを使用して到達可能な Kubernetes Service をデプロイします。
- このデプロイは、Kubernetes Service として公開され、Cloud Service Mesh に接続するスタンドアロンの Envoy プロキシで構成されています。
- TLS を終端するサーバー TLS ポリシーを作成します。
- 受信リクエストを承認する認可ポリシーを作成します。
Ingress ゲートウェイ サービスを GKE にデプロイする
次のコマンドを実行して、GKE に Ingress ゲートウェイ サービスをデプロイします。
wget -q -O - https://storage.googleapis.com/traffic-director/security/ga/gateway_sample_xdsv3.yaml | sed -e s/PROJECT_NUMBER_PLACEHOLDER/PROJNUM/g | sed -e s/NETWORK_PLACEHOLDER/default/g | sed -e s/DEMO_CLIENT_KSA_PLACEHOLDER/DEMO_CLIENT_KSA/g > gateway_sample.yaml kubectl apply -f gateway_sample.yaml
ファイル gateway_sample.yaml は Ingress ゲートウェイの仕様です。以下のセクションでは、この仕様への追加について説明します。
Cloud Service Mesh サイドカー インジェクションを無効化する
gateway_sample.yaml 仕様では、Envoy プロキシを唯一のコンテナとしてデプロイします。前のステップでは、Envoy をサイドカーとしてアプリケーション コンテナに挿入しました。複数の Envoy でリクエストを処理しないように、次のステートメントを使用して、この Kubernetes Service のサイドカー インジェクションを無効にできます。
sidecar.istio.io/inject: "false"
正しいボリュームをマウントする
gateway_sample.yaml 仕様ではボリューム gke-workload-certificates をマウントします。このボリュームはサイドカーのデプロイでも使用されますが、アノテーション cloud.google.com/enableManagedCerts: "true" が検出されると、サイドカー インジェクタによって自動的に追加されます。gke-workload-certificates ボリュームには、設定した CA Service インスタンスによって署名される GKE マネージド SPIFFE 証明書と鍵が含まれます。
クラスタの内部 IP アドレスを設定する
ClusterInternal タイプのサービスを使用して Ingress ゲートウェイを構成します。これにより、mesh-gateway の内部解決可能な DNS ホスト名が作成されます。クライアントが mesh-gateway:443 にリクエストを送信すると、Kubernetes はすぐにリクエストを Ingress ゲートウェイの Envoy Deployment のポート 8080 に転送します。
Ingress ゲートウェイで TLS を有効にする
Ingress ゲートウェイで TLS を有効にする手順は次のとおりです。
server-tls-policy.yamlという名前のファイル内の値を使用して、TLS 接続を終了するサーバー TLS ポリシー リソースを作成します。description: tls server policy name: server-tls-policy serverCertificate: certificateProviderInstance: pluginInstance: google_cloud_private_spiffeサーバーの TLS ポリシーをインポートします。
gcloud network-security server-tls-policies import server-tls-policy \ --source=server-tls-policy.yaml --location=global新しいターゲット
Gatewayを作成し、td-gke-gateway.yamlファイルに保存します。これにより、サーバー TLS ポリシーが接続され、受信 TLS トラフィックを終了するように Envoy プロキシ Ingress ゲートウェイが構成されます。name: td-gke-gateway scope: gateway-proxy ports: - 8080 type: OPEN_MESH serverTlsPolicy: projects/PROJECT_ID/locations/global/serverTlsPolicies/server-tls-policy
ゲートウェイをインポートします。
gcloud network-services gateways import td-gke-gateway \ --source=td-gke-gateway.yaml \ --location=global
ゲートウェイを参照してすべてのリクエストを
td-gke-serviceに転送する、td-gke-routeという新しいHTTPRouteを作成して保存します。name: td-gke-route hostnames: - mesh-gateway gateways: - projects/PROJECT_NUMBER/locations/global/gateways/td-gke-gateway rules: - action: destinations: - serviceName: "projects/PROJECT_NUMBER/locations/global/backendServices/td-gke-service"HTTPRouteをインポートします。gcloud network-services http-routes import td-gke-route \ --source=td-gke-route.yaml \ --location=global
必要に応じて、以下のすべての条件が満たされる場合に、バックエンドの認可ポリシーを更新し、リクエストを許可します。
DEMO_CLIENT_KSAによって送信されたリクエスト。(Ingress ゲートウェイのデプロイでは、DEMO_CLIENT_KSAサービス アカウントが使用されます。)- ホストが
mesh-gatewayまたはservice-testのリクエスト - ポート:
8000
バックエンドの認可ポリシーを構成していない限り、これらのコマンドを実行する必要はありません。エンドポイントに承認ポリシーがない場合、または承認ポリシーにホストまたはソースのプリンシパルの一致が含まれない場合、このステップなしでリクエストが許可されます。これらの値を
authz-policy.yamlに追加します。action: ALLOW name: authz-policy rules: - sources: - principals: - spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA destinations: - hosts: - service-test - mesh-gateway ports: - 8000 methods: - GETポリシーをインポートします。
gcloud network-security authorization-policies import authz-policy \ --source=authz-policy.yaml \ --location=global
Ingress ゲートウェイの Deployment を検証する
debug という新しいコンテナを使用して Ingress ゲートウェイにリクエストを送信し、デプロイを検証します。
次の仕様では、アノテーション "sidecar.istio.io/inject":"false" によって Cloud Service Mesh サイドカー インジェクタがサイドカー プロキシを自動的に挿入しないようにしています。リクエスト ルーティングで debug コンテナをサポートするサイドカーはありません。コンテナは、ルーティングのために Ingress ゲートウェイに接続する必要があります。
この仕様には、サーバー証明書の検証を無視する --no-check-certificate フラグが含まれています。debug コンテナには、TLS を終了するために Ingress ゲートウェイが使用する、CA Service によって署名された有効な証明書に必要な認証局検証証明書がありません。
本番環境では、CA Service の検証証明書をダウンロードし、それをクライアントにマウントまたはインストールすることをおすすめします。検証証明書をインストールしたら、wget コマンドの --no-check-certificate オプションを削除します。
次のコマンドを実行します。
kubectl run -i --tty --rm debug --image=busybox --restart=Never --overrides='{ "metadata": {"annotations": { "sidecar.istio.io/inject":"false" } } }' -- /bin/sh -c "wget --no-check-certificate -qS -O - https://mesh-gateway; echo"
次のような出力が表示されます。
GET / HTTP/1.1 Host: 10.68.7.132 x-forwarded-client-cert: By=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_SERVER_KSA;Hash=Redacted;Subject="Redacted;URI=spiffe://PROJECT_ID.svc.id.goog/ns/K8S_NAMESPACE/sa/DEMO_CLIENT_KSA x-envoy-expected-rq-timeout-ms: 15000 x-envoy-internal: true x-request-id: 5ae429e7-0e18-4bd9-bb79-4e4149cf8fef x-forwarded-for: 10.64.0.53 x-forwarded-proto: https content-length: 0 user-agent: Wget
次のネガティブ テスト コマンドを実行します。
# Negative test
# Expect this to fail because gateway expects TLS.
kubectl run -i --tty --rm debug --image=busybox --restart=Never --overrides='{ "metadata": {"annotations": { "sidecar.istio.io/inject":"false" } } }' -- /bin/sh -c "wget --no-check-certificate -qS -O - http://mesh-gateway:443/headers; echo"
次のような出力が表示されます。
wget: error getting response: Connection reset by peer
次のネガティブ テスト コマンドを実行します。
# Negative test.
# AuthorizationPolicy applied on the endpoints expect a GET request. Otherwise
# the request is denied authorization.
kubectl run -i --tty --rm debug --image=busybox --restart=Never --overrides='{ "metadata": {"annotations": { "sidecar.istio.io/inject":"false" } } }' -- /bin/sh -c "wget --no-check-certificate -qS -O - https://mesh-gateway --post-data=''; echo"
次のような出力が表示されます。
HTTP/1.1 403 Forbidden wget: server returned error: HTTP/1.1 403 Forbidden
Deployment を削除する
必要に応じて、これらのコマンドを実行して、このガイドに従って作成した Deployment を削除できます。
クラスタを削除するには、次のコマンドを実行します。
gcloud container clusters delete CLUSTER_NAME --zone ZONE --quiet
作成したリソースを削除するには、次のコマンドを実行します。
gcloud compute backend-services delete td-gke-service --global --quiet
cloud compute network-endpoint-groups delete service-test-neg --zone ZONE --quiet
gcloud compute firewall-rules delete fw-allow-health-checks --quiet
gcloud compute health-checks delete td-gke-health-check --quiet
gcloud network-services endpoint-policies delete ep \
--location=global --quiet
gcloud network-security authorization-policies delete authz-gateway-policy \
--location=global --quiet
gcloud network-security authorization-policies delete authz-policy \
--location=global --quiet
gcloud network-security client-tls-policies delete client-mtls-policy \
--location=global --quiet
gcloud network-security server-tls-policies delete server-tls-policy \
--location=global --quiet
gcloud network-security server-tls-policies delete server-mtls-policy \
--location=global --quiet
制限事項
Cloud Service Mesh サービスのセキュリティは GKE でのみサポートされています。Compute Engine ではサービスのセキュリティをデプロイできません。
トラブルシューティング
このセクションでは、セキュリティ サービスの設定中に発生した問題を修正する方法について説明します。
接続エラー
upstream connect エラーまたは disconnect/reset
before headers エラーで接続が失敗した場合は、Envoy のログを調べます。次のいずれかのログメッセージが表示される場合があります。
gRPC config stream closed: 5, Requested entity was not found
gRPC config stream closed: 2, no credential token is found
Envoy のログにこれらのエラーが記録されている場合は、サービス アカウント トークンが正しくマウントされていないか、別の audience が使用されている、またはその両方の可能性があります。
詳細については、Envoy のログのエラー メッセージが構成の問題を示しているをご覧ください。
Pod が作成されない
この問題のトラブルシューティングを行うには、GKE Pod の自動デプロイのトラブルシューティングをご覧ください。
Envoy が Cloud Service Mesh で認証されない
Envoy(envoy-proxy)が Cloud Service Mesh に接続して xDS 構成を取得する場合、(ブートストラップが変更されている場合を除き)Workload Identity Federation for GKE と Compute Engine VM のデフォルト サービス アカウントを使用します。認証に失敗した場合、Envoy は準備完了状態になりません。
--workload-identity-certificate-authority flag を指定してクラスタを作成できない
このエラーが表示された場合は、Google Cloud CLI の最新バージョンを実行していることを確認してください。
gcloud components update
Pod が保留状態のままになる
設定プロセス中に Pod が保留状態のままである場合は、デプロイ仕様の Pod の CPU とメモリリソースを増やします。
--enable-mesh-certificates フラグを指定してクラスタを作成できない
gcloud CLI の最新バージョンを実行していることを確認します。
gcloud components update
--enable-mesh-certificates フラグは gcloud beta でのみ機能します。
Pod が起動しない
証明書のプロビジョニングが失敗した場合、GKE メッシュ証明書を使用する Pod が起動しない可能性があります。これは、次のような状況で発生します。
WorkloadCertificateConfigまたはTrustConfigが正しく構成されていないか、存在しない。- CSR が承認されていない。
証明書のプロビジョニングが失敗するかどうかを確認するには、Pod イベントを確認します。
Pod のステータスを確認します。
kubectl get pod -n POD_NAMESPACE POD_NAME次のように置き換えます。
POD_NAMESPACE: Pod の名前空間。POD_NAME: Pod の名前。
Pod の最近のイベントを確認します。
kubectl describe pod -n POD_NAMESPACE POD_NAME証明書のプロビジョニングに失敗した場合、
Type=Warning、Reason=FailedMount、From=kubeletが含まれるイベントと、先頭がMountVolume.SetUp failed for volume "gke-workload-certificates"のMessageフィールドが表示されます。Messageフィールドにはトラブルシューティング情報が含まれています。Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedMount 13s (x7 over 46s) kubelet MountVolume.SetUp failed for volume "gke-workload-certificates" : rpc error: code = Internal desc = unable to mount volume: store.CreateVolume, err: unable to create volume "csi-4d540ed59ef937fbb41a9bf5380a5a534edb3eedf037fe64be36bab0abf45c9c": caPEM is nil (check active WorkloadCertificateConfig)Pod が起動しない原因がオブジェクトの構成が適切でないか、CSR が拒否されたことである場合は、以下のトラブルシューティングの手順をご覧ください。
WorkloadCertificateConfig または TrustConfig の構成に誤りがある
WorkloadCertificateConfig オブジェクトと TrustConfig オブジェクトが正しく作成されていることを確認してください。kubectl を使用して、これらのオブジェクトの構成ミスを診断できます。
現在のステータスを取得します。
WorkloadCertificateConfig:kubectl get WorkloadCertificateConfig default -o yamlTrustConfig:kubectl get TrustConfig default -o yamlステータスの出力を検査します。有効なオブジェクトには、
type: Readyとstatus: "True"の条件が設定されます。status: conditions: - lastTransitionTime: "2021-03-04T22:24:11Z" message: WorkloadCertificateConfig is ready observedGeneration: 1 reason: ConfigReady status: "True" type: Ready無効なオブジェクトの場合は、
status: "False"が代わりに表示されます。reasonフィールドとmessageフィールドには、追加のトラブルシューティングの詳細が含まれます。
CSR が承認されていない
CSR 承認プロセス中に問題が発生した場合は、CSR の type: Approved 条件と type: Issued 条件でエラーの詳細を確認できます。
kubectlを使用して、関連する CSR を一覧表示します。kubectl get csr \ --field-selector='spec.signerName=spiffe.gke.io/spiffe-leaf-signer'ApprovedでIssuedではない CSR、またはApprovedでない CSR を選択します。kubectl を使用して、選択した CSR の詳細を取得します。
kubectl get csr CSR_NAME -o yamlCSR_NAMEを、選択した CSR の名前に置き換えます。
有効な CSR には、type: Approved と status: "True" の条件と、status.certificate フィールドに有効な証明書があります。
status:
certificate: <base64-encoded data>
conditions:
- lastTransitionTime: "2021-03-04T21:58:46Z"
lastUpdateTime: "2021-03-04T21:58:46Z"
message: Approved CSR because it is a valid SPIFFE SVID for the correct identity.
reason: AutoApproved
status: "True"
type: Approved
無効な CSR のトラブルシューティング情報が message フィールドと reason フィールドに表示されます。
アプリケーションで発行済みの mTLS 認証情報を使用できない
証明書の有効期限が切れていないことを確認します。
cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Not After"使用しているキータイプがアプリケーションでサポートされていることを確認します。
cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Public Key Algorithm" -A 3発行 CA が証明書鍵と同じ鍵ファミリーを使用していることを確認します。
CA Service(プレビュー)インスタンスのステータスを取得します。
gcloud privateca ISSUING_CA_TYPE describe ISSUING_CA_NAME \ --location ISSUING_CA_LOCATION次のように置き換えます。
ISSUING_CA_TYPE: 発行 CA のタイプ(subordinatesまたはrootsのいずれか)。ISSUING_CA_NAME: 発行 CA の名前。ISSUING_CA_LOCATION: 発行 CA のリージョン。
出力の
keySpec.algorithmがWorkloadCertificateConfigYAML マニフェストで定義したのと同じ鍵アルゴリズムであることを確認します。出力は次のようになります。config: ... subjectConfig: commonName: td-sub-ca subject: organization: TestOrgLLC subjectAltName: {} createTime: '2021-05-04T05:37:58.329293525Z' issuingOptions: includeCaCertUrl: true keySpec: algorithm: RSA_PKCS1_2048_SHA256 ...
証明書が拒否される
- ピア アプリケーションが同じ信頼バンドルを使用して証明書を検証することを確認します。
証明書の有効期限が切れていないことを確認します。
cat /var/run/secrets/workload-spiffe-credentials/certificates.pem | openssl x509 -text -noout | grep "Not After"gRPC Go Credentials Reloading API を使用していない場合、クライアント コードがファイル システムから認証情報を定期的に更新することを確認します。
ワークロードが CA と同じ信頼ドメインに存在することを確認します。GKE メッシュ証明書は、単一の信頼ドメインにあるワークロード間の通信をサポートします。