このページでは、ユーザー管理の暗号鍵を使用して、Google Kubernetes Engine(GKE)ノード間の Pod 通信で転送中のデータの暗号化を有効にする方法について説明します。
デフォルトでは、Google はネットワーク インターフェース コントローラ(NIC)レベルで VM 間で転送されているデータを暗号化します。これにより、VM(GKE を含む)上で実行されているサービスまたはアプリケーションに関係なく、転送中のデータの機密性が保持されます。この暗号化レイヤは、すべての GKE ノードと Pod のトラフィックに適用されます。暗号鍵は Google によって提供、管理されます。
GKE では、ノード間で透過的暗号化が行われるため、ユーザーは GKE ノード間の Pod トラフィックの暗号化に使用される暗号鍵をより柔軟に制御できます。GKE では、VM NIC から提供されるデフォルトの暗号化に加えて、GKE Dataplane V2 の WireGuard を使用してこの暗号化を行います。
このように GKE で暗号鍵を直接制御できる機能は、規制の厳しい業種でコンプライアンスやセキュリティ監査が求められる組織にとって便利な機能です。
ノード間の透過的暗号化は、単一クラスタ環境とマルチクラスタ環境で有効にできます。この機能の仕組みの詳細については、GKE でのノード間の透過的暗号化の仕組みをご覧ください。
制限事項
この機能を有効にしただけでは、GKE ノードメモリに保存されている暗号鍵に対する Google のアクセスを防ぐことはできません。規制対象の環境や地域の適用法令、またはコンプライアンス要件によっては、これらの鍵をさらに暗号化してアクセスを制御する必要があります。その場合は、顧客管理の暗号鍵(CMEK)を使用する Confidential GKE Node でノード間の透過的暗号化を使用することをおすすめします。CMEK を使用する Confidential GKE Node は、ユーザーが管理する鍵を使用して、ノードのメモリの内容を暗号化します。
GKE のノード間の透過的暗号化は、GKE Dataplane V2 クラスタでのみサポートされます。
GKE Autopilot はサポートされていません。
GKE のノード間の透過的暗号化には WireGuard を使用します。WireGuard は FIPS に準拠していません。
暗号鍵は動的にローテーションされません。鍵のローテーションは、ノードを再起動して手動で行う必要があります。
Confidential GKE Node を使用したノード間の透過的暗号化は、Container-Optimized OS(COS)と Ubuntu でのみ機能します。Windows では機能しません。
hostNetwork
を使用して GKE ノードまたは Pod から開始したネットワーク トラフィックは、ノード間の透過的暗号化で暗号化されません。ノードポートで公開されている Pod に送信されるネットワーク トラフィックは、ノード間の透過的暗号化で暗号化されません。Service で
ExternalTrafficPolicy: Cluster
が構成されていても、クライアントからトラフィックを受信する最初のノードからバックエンド Pod に転送されるトラフィックは暗号化されません。単一クラスタ構成またはマルチクラスタ構成でノード間の透過的暗号化を有効にできるノードの最大数は 500 です。
ノード間の透過的暗号化により、ノードがオーバーサブスクライブされる可能性があります。スループットが 2 Gbps の Ubuntu OS を使用する n2-standard-8 ノードの場合、CPU 使用率が平均して 15% 増加することが予想されます。
この CPU 使用率の増加は kube-scheduler が認識していないため、どの Pod にも帰属しません。トラフィックが増加した Pod は、ノード上のすべての CPU リソースを使用する可能性があります。その場合、正しく構成されている他の Pod が、必要な CPU リソースを取得できなくなる可能性があります。機密性の高いワークロードを実行しようとする Pod や、リクエストに迅速に応答する必要のある Pod で問題が発生する可能性があります。この問題を回避するには、ノード間の透過的暗号化が有効になっているノードで、大量の CPU をスケジュールしないようにします。また、大量の CPU をリクエストしてもこの CPU リソースを使用しないように、PriorityClass の低い Pod をスケジュールすることもできます。
同じゾーン内で Confidential GKE Node を使用しない 2 つのノード間では、ノード間の透過的暗号化により 150 マイクロ秒のレイテンシが発生します。
ノード間の透過的暗号化を有効にすると、Pod 上のトラフィック トラッキングに使用されるトラフィック オブザーバビリティ機能が期待どおりに動作しない可能性があります。これは、基盤となる Google のインフラストラクチャにアクセスできない鍵で転送中のデータが暗号化されるためです。
ノード間の透過的暗号化を有効にすると、VPC は Pod の IP アドレスを認識できなくなります。Packet Mirroring や Pod CIDR ベースの VPC ファイアウォール ルールなど、パケット検査に依存する機能はノード間の透過的暗号化と互換性がありません。
異なる VPC サブネットに接続しているクラスタでノード間の透過的暗号化を有効にする場合は、クラスタノード間の通信を許可するファイアウォール ルールを手動で作成する必要があります。
ノード間の透過的暗号化により、GKE Dataplane V2 の一部のレイヤ 7 機能が無効になります。そのため、FQDN ネットワーク ポリシーとノード間の透過的暗号化を同時に有効にすることはできません。
この機能をノード内の可視化と同時に有効にすることはできません。
始める前に
作業を始める前に、次のことを確認してください。
- Google Kubernetes Engine API を有効にする。 Google Kubernetes Engine API の有効化
- このタスクに Google Cloud CLI を使用する場合は、gcloud CLI をインストールして初期化する。すでに gcloud CLI をインストールしている場合は、
gcloud components update
を実行して最新のバージョンを取得する。
GKE Enterprise を有効にするための手順に沿って操作します。
GKE ノード間の透過的暗号化は、Google Cloud CLI バージョン 458.0.0 以降と次の GKE バージョンでのみサポートされています。
- 1.26.10-gke.1024000 以降
- 1.27.7-gke.1506000 以降
- 1.28.2-gke.1098000 以降
GKE でノード間の透過的暗号化を有効にする
GKE では、単一クラスタ環境またはマルチクラスタ環境でノード間の透過的暗号化を有効にできます。
新しいクラスタでノード間の透過的暗号化を有効にする
新しいクラスタでノード間の透過的暗号化を有効にするには:
gcloud container clusters create CLUSTER_NAME \ --region=REGION \ --enable-datapane-v2 \ --in-transit-encryption inter-node-transparent
次のように置き換えます。
CLUSTER_NAME
: 使用するクラスタの名前。REGION
: クラスタのコンピューティング リージョン。
構成を確認するには、次のコマンドを実行して暗号化のステータスを確認します。
kubectl -n kube-system exec -ti anetd-XXXX -- cilium status | grep Encryption
出力は次のようになります。
Encryption: Wireguard [cilium_wg0 (Pubkey: <key>, Port: 51871, Peers: 2)]
既存のクラスタでノード間の透過的暗号化を有効にする
既存のクラスタでノード間の透過的暗号化を有効にするには:
gcloud container clusters update CLUSTER_NAME \ --in-transit-encryption inter-node-transparent \ --region=REGION
次のように置き換えます。
CLUSTER_NAME
: 使用するクラスタの名前。REGION
: クラスタのコンピューティング リージョン。
Google Cloud CLI コマンドが正常に完了していることを確認するには:
gcloud container clusters describe CLUSTER_NAME \ --region=REGION \ --format json | jq .status
次のように置き換えます。
CLUSTER_NAME
: 使用するクラスタの名前。REGION
: クラスタのコンピューティング リージョン。
ステータスが「RUNNING」になるまで待ちます。GKE でノード間の暗号化を有効にすると、ノードが自動的に再起動されます。ノードが再起動し、新しいノードにポリシーが適用されるまでに数時間かかることがあります。
ノードが再起動したことを確認するには:
kubectl get nodes
各ノードの
AGE
フィールドを確認します。AGE
フィールドに新しいノードが反映されている場合は次に進みます。構成を確認するには、次のコマンドを実行して暗号化のステータスを確認します。
kubectl -n kube-system exec -ti anetd-XXXX -- cilium status | grep Encryption
出力は次のようになります。
Encryption: Wireguard [cilium_wg0 (Pubkey: <key>, Port: 51871, Peers: 2)]
ピアの数がクラスタ内のノード数よりも 1 つ少ないことを確認します。たとえば、24 個のノードを持つクラスタの場合、ピアの数は 23 個になります。この条件を満たしていない場合は、ノードで
anetd
エージェントを再起動してください。
クラスタ間でノード間の透過的暗号化を有効にする
Autopilot クラスタではノード間の透過的暗号化はサポートされていません。Autopilot クラスタが含まれているフリートは、暗号化が有効になっている Standard クラスタと通信できません。
マルチクラスタ環境でノード間の透過的暗号化を有効にするには:
フリートにクラスタを登録します
フリートに対してノード間の透過的暗号化を有効にします。
gcloud container fleet dataplane-v2-encryption enable --project PROJECT_ID
PROJECT_ID
は、実際のプロジェクト ID に置き換えます。すべてのノードのステータスを確認します。
kubectl -n kube-system get pods -l k8s-app=cilium -o name | xargs -I {} kubectl -n kube-system exec -ti {} -- cilium status
出力は次のようになります。
... Encryption: Wireguard [cilium_wg0 (Pubkey: <key>, Port: 51871, Peers: 5)] ...
ノード間の透過的暗号化を無効にする
パフォーマンスの改善やアプリケーションの接続のトラブルシューティングのために、GKE クラスタでノード間の透過的暗号化の無効化が必要になることがあります。このオペレーションを続行する前に、次の点を考慮してください。
ノード間の透過的暗号化はクラスタ全体で有効になっています。Namespace や Pod など、個々の Kubernetes リソースで部分的に無効にすることはできません。
このオペレーションは、Pod のトラフィックが中断されるため、メンテナンスの時間枠内に実行します。
単一クラスタの場合
単一クラスタでノード間の透過的暗号化を無効にするには:
gcloud container clusters update CLUSTER_NAME \
--region=REGION \
--in-transit-encryption none
次のように置き換えます。
CLUSTER_NAME
: クラスタの名前。REGION
: クラスタのコンピューティング リージョン。
フリート内のクラスタで無効にする
フリート内のクラスタで暗号化を無効にするには、次のいずれかの方法で行います。
フリートからクラスタを完全に削除する場合は、クラスタの登録を解除します。
あるいは、クラスタをフリート内に残し、暗号化を無効にします。
gcloud container fleet dataplane-v2-encryption disable --project PROJECT_ID
PROJECT_ID
は、実際のプロジェクト ID に置き換えます。このコマンドで暗号化を無効にすると、各クラスタの Wireguard ピアリストからリモートノードが削除されます。関係するクラスタとノードの数によっては、このプロセスが完了するまでに数分かかる場合があります。更新されたピア数を確認するには、各クラスタの WireGuard ピアリストを手動で更新する必要があります。クラスタ管理ツールまたは次のコマンドを使用できます。
kubectl -n kube-system exec -ti anetd-XXXX -- cilium status | grep Encryption
クラスタのフリート全体で無効にする
フリートでノード間の透過的暗号化を無効にするには:
gcloud container fleet dataplane-v2-encryption disable --project PROJECT_ID
PROJECT_ID
は、実際のプロジェクト ID に置き換えます。ノード間の透過的暗号化を無効にして、使用されていない API を削除するには、フリートレベルで GKE Dataplane V2 API を無効にします。これにより、フリートで実行されている GKE Dataplane V2 コントローラが無効になります。
gcloud services disable gkedataplanev2.googleapis.com \ --project=PROJECT_ID
PROJECT_ID
は、実際のプロジェクト ID に置き換えます。同じ名前のクラスタを効率的に管理し、マルチクラスタの暗号化を有効にするには、次の操作を行います。
同じ名前の新しいクラスタを作成する前に、フリートから古いクラスタの登録を解除します。
再作成時に新しいクラスタを再登録します。
クラスタの登録解除を忘れた場合は、古いメンバーシップを削除し、新しいメンバーシップで新しいクラスタを再作成します。
この操作を行わないと、フリート メンバーシップが再作成されるまで、新しいクラスタでマルチクラスタの暗号化が有効にならない場合があります。
GKE でのノード間の透過的暗号化の仕組み
以降のセクションでは、クラスタでノード間の透過的暗号化を有効にしたときに、この暗号化がどのように機能するのかについて説明します。
異なるノード上の 2 つの Pod 間でネットワーク トラフィックを暗号化
Pod が異なるノード上に存在している場合、ノード間の透過的暗号化を有効にすると、これらのノードが属するクラスタに関係なく、GKE Dataplane V2 は Pod 間のトラフィックを暗号化します。同じフリートに属しているクラスタは同じ暗号化ドメインに属しています。
同じフリート内に、ノード間の透過的暗号化の構成が異なるクラスタを共存させることができます。一部のクラスタのみがノード間の透過的暗号化を使用するマルチクラスタ環境の場合は、次の点を考慮してください。
同じクラスタ内のノード間の Pod 間通信は公開鍵/秘密鍵のペアで暗号化されます。
ノード間の透過的暗号化が有効になっているクラスタ内のノードと、ノード間の透過的暗号化が有効になっていないクラスタ内のノード間の Pod 間通信は失敗します。
暗号鍵の生成と使用
この機能を有効にすると、クラスタ内のすべての GKE ノードで暗号鍵という公開鍵/秘密鍵のペアが自動的に生成されます。
秘密鍵は、ディスクではなくメモリに保存され、ノードの外部に出ることはありません。GKE Confidential Node を使用すると、ノードメモリも(異なる鍵で)暗号化されるため、鍵が不正に使用されるリスクがさらに低減されます。
公開鍵は、GKE Dataplane V2 コントロール プレーンを使用して他のノードと共有され、同じ暗号化ドメイン内のすべてのノードからアクセスできます。
各ノードは、鍵交換の後に同じ暗号化ドメイン内の他のノードと WireGuard トンネルを確立できます。各トンネルは、特定のノードペアに対して一意です。
公開鍵/秘密鍵のペアとセッションキーを扱う場合は、次の点を考慮してください。
公開鍵/秘密鍵のペア:
公開鍵はクラスタ内で配布され、クラスタ内のすべてのノードが公開鍵にアクセスできます。
鍵ペアは、ノードの再起動時にローテーションされます。GKE は鍵を定期的にローテーションしません。鍵のローテーションを手動でトリガーするには、ノードをドレインして再起動します。これにより、元の鍵ペアが無効になり、新しい鍵ペアが生成されます。
セッションキー:
この鍵は構成できません。
こ鍵は 2 分ごとに定期的にローテーションされます。
セッションキーは、トンネルに関係するノード専用の鍵です。
次のステップ
- 保存時の Google Cloud 暗号化の詳細について理解する。
- 転送中の Google Cloud 暗号化の詳細について理解する。
- アプリケーション レイヤでの Secret の暗号化について理解する。