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 Service Mesh リソースを作成または更新するのに十分な権限があります。
設定を準備する
以降のセクションでは、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 Console または次のコマンドで確認できます。
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 クラスタを有効にして、メッシュ証明書で構成する必要があります。
GKE 用 Workload Identity 連携を使用する新しいクラスタを作成します。既存のクラスタを更新する場合は、次のステップに進みます。
--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-a
Pod 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-b
Pod 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 |
Dammam |
me-west1 |
テルアビブ |
northamerica-northeast1 |
モントリオール |
northamerica-northeast2 |
トロント |
southamerica-east1 |
サンパウロ |
southamerica-west1 |
サンチアゴ |
us-central1 |
アイオワ |
us-east1 |
サウスカロライナ |
us-east4 |
北バージニア |
us-east5 |
コロンバス |
us-south1 |
Dallas |
us-west1 |
Oregon |
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"
次の
WorkloadCertificateConfig
YAML 構成を保存して、メッシュ証明書を発行する方法をクラスタに指示します。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:
次の
TrustConfig
YAML 構成を保存して、発行済み証明書を信頼する方法をクラスタに指示します。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
ID およびアクセス管理を構成する
設定に必要なリソースを作成するには、compute.NetworkAdmin
ロールが必要です。このロールには、必要なリソースの作成、更新、削除、一覧表示、使用(他のリソースでの参照)に必要なすべての権限が含まれています。プロジェクトのオーナー編集者には、このロールが自動的に付与されます。
なお、これらのリソースをバックエンド サービスで参照する場合、networksecurity.googleapis.com.clientTlsPolicies.use
と networksecurity.googleapis.com.serverTlsPolicies.use
は適用されません。
今後これらの権限が適用され、compute.NetworkAdmin
ロールを使用している場合、このチェックの適用時に問題は検出されません。
カスタムロールを使用していて、今後このチェックが適用される場合は、各 .use
権限を含める必要があります。そうしないと、バックエンド サービスまたはエンドポイント ポリシーから clientTlsPolicy
または serverTlsPolicy
を参照するために必要な権限がカスタムロールに付与されない場合があります。
次の手順では、デフォルトのサービス アカウントで Cloud Service Mesh のセキュリティ 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.client
Kubernetes サービス アカウントを設定します。次のセクションで説明するクライアントとサーバーのデプロイでは、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 での Traffic Director の設定の以下の両セクションの手順に沿って、クラスタで Envoy サイドカー インジェクションをデプロイして有効にします。
- Envoy サイドカー インジェクタをインストールする。メッシュ名を
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>
GKE のサイドカーで認可ポリシーを設定する
このセクションでは、GKE の Cloud Service Mesh サイドカーにさまざまな種類の認可ポリシーを設定する方法について説明します。
認可ポリシーを作成する前に、GCPAuthzPolicy CustomResourceDefinition(CRD)をインストールする必要があります。
curl https://github.com/GoogleCloudPlatform/gke-networking-recipes/blob/main/gateway-api/config/mesh/crd/experimental/gcpauthzpolicy.yaml \
| kubectl apply -f -
リクエストを拒否する認可ポリシー
cron ジョブなど、発信のみを行うワークロードがある場合は、ワークロードへの受信 HTTP リクエストを拒否するように認可ポリシーを構成できます。次の例では、ワークロード example-app
への受信 HTTP リクエストを拒否します。
次のステップを実行して、拒否認可ポリシーを作成して適用します。
deny-all-authz-policy.yaml
という名前のファイルを作成してカスタム ポリシーを作成します。cat >deny-all-authz-policy.yaml <<EOF apiVersion: networking.gke.io/v1 kind: GCPAuthzPolicy metadata: name: my-workload-authz namespace: ns1 spec: targetRefs: - kind: Deployment name: example-app httpRules: - to: operations: - paths: - type: Prefix value: "/" action: DENY EOF
ポリシーを適用します。
kubectl apply -f deny-all-authz-policy.yaml
リクエストを許可する認可ポリシー
特定の条件に一致するリクエストのみを許可し、残りを拒否する許可ポリシーを構成することもできます。次の例では、ID が spiffee://cluster.local/ns1/pod1
の Pod からの mTLS リクエストのみを許可するように、example-app
Deployment で認可ポリシーを構成します。
次のステップを実行して、許可認可ポリシーを作成して適用します。
allow-authz-policy.yaml
という名前のファイルを作成してカスタム ポリシーを作成します。cat >allow-authz-policy.yaml <<EOF apiVersion: networking.gke.io/v1 kind: GCPAuthzPolicy metadata: name: my-workload-authz namespace: ns1 spec: targetRefs: - kind: Deployment name: example-app httpRules: - from: sources: - principals: - type: Exact value: "spiffee://cluster.local/ns1/pod1" action: ALLOW EOF
ポリシーを適用します。
kubectl apply -f allow-authz-policy.yaml
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 デプロイのポート 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 httproutes 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 ゲートウェイにリクエストを送信し、Deployment を検証します。
次の仕様では、アノテーション "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 を削除する
必要に応じて、これらのコマンドを実行して、このガイドに従って作成したデプロイを削除できます。
クラスタを削除するには、次のコマンドを実行します。
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 構成を取得する場合、(ブートストラップが変更されている場合を除き)GKE 用 Workload Identity 連携と 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 yaml
TrustConfig
: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 yaml
CSR_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
がWorkloadCertificateConfig
YAML マニフェストで定義したのと同じ鍵アルゴリズムであることを確認します。出力は次のようになります。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 メッシュ証明書は、単一の信頼ドメインにあるワークロード間の通信をサポートします。