このページでは、GKE のネットワーク ポリシーを適用して、クラスタの Pod と Service 間の通信を制御する方法について説明します。
完全修飾ドメイン名(FQDN)ネットワーク ポリシーを使用して、クラスタ外のエンドポイントまたはサービスに対する Pod の下り(外向き)トラフィックを制御することもできます。詳細については、FQDN を使用して Pod と Service 間の通信を制御するをご覧ください。
GKE ネットワーク ポリシーの適用について
ネットワーク ポリシーを適用すると、クラスタ内に Kubernetes ネットワーク ポリシーを作成できます。デフォルトでは、クラスタ内のすべての Pod は自由に通信できます。ネットワーク ポリシーは、クラスタ内で相互にアクセスできる Pod と Service を決定する Pod レベルのファイアウォール ルールを作成します。
ネットワーク ポリシーを定義すると、クラスタがマルチレベルのアプリケーションを処理するときに多層防御のような機能を有効にすることができます。たとえば、アプリケーション内の不正使用されたフロントエンド サービスが数レベル下の課金サービスや会計サービスと直接通信できないようにするネットワーク ポリシーを作成することができます。
ネットワーク ポリシーを使用して、複数のユーザーが生成したデータを同時にホストするアプリケーションをより簡単に作成することもできます。たとえば、テナント単位の名前空間モデルを定義して、セキュアなマルチテナンシーを提供できます。このようなモデルでは、ネットワーク ポリシー ルールにより、特定の Namespace 内の Pod や Service が異なる Namespace 内の他の Pod や Service にアクセスできないようにできます。
始める前に
作業を始める前に、次のタスクが完了していることを確認してください。
- Google Kubernetes Engine API を有効にする。 Google Kubernetes Engine API の有効化
- このタスクに Google Cloud CLI を使用する場合は、gcloud CLI をインストールして初期化する。すでに gcloud CLI をインストールしている場合は、
gcloud components update
を実行して最新のバージョンを取得する。
要件と制限事項
次の要件と制限事項は Autopilot クラスタと Standard クラスタの両方に適用されます。
- メタデータ サーバーへの下り(外向き)を許可する必要があります。
- GKE Dataplane V2 が有効になっているクラスタのネットワーク ポリシーで
endPort
フィールドを指定しても、GKE バージョン 1.22 以降では有効になりません。詳細については、ネットワーク ポリシーのポート範囲が有効にならないをご覧ください。Autopilot クラスタの場合、GKE Dataplane V2 は常に有効になります。
次の要件と制限事項は Standard クラスタにのみ適用されます。
- Workload Identity Federation for GKE でネットワーク ポリシーを使用する場合は、メタデータ サーバーへの下り(外向き)を許可する必要があります。
- ネットワーク ポリシーの適用を有効にすると、
kube-system
プロセスのメモリ使用量が約 128 MB 増加し、約 300 ミリコアの CPU が必要になります。つまり、既存のクラスタに対してネットワーク ポリシーを有効にした場合、スケジュールされたワークロードの実行を継続するには、クラスタのサイズを大きくする必要があります。 - ネットワーク ポリシーの適用を有効にする場合、ノードの再作成が必要になります。クラスタのメンテナンスの時間枠が有効になっている場合、次のメンテナンスの時間枠でノードが自動的に再作成されます。必要に応じて、いつでも手動でクラスタをアップグレードできます。
- ネットワーク ポリシーを適用するために必要となるクラスタの最小サイズは 3 つの
e2-medium
インスタンスか、1 つ以上の割り当て可能な vCPU を持つ 1 つのマシンタイプ インスタンスです。詳細については、GKE の既知の問題をご覧ください。 - ノードが
f1-micro
インスタンスまたはg1-small
インスタンスであるクラスタでは、リソース要件が高すぎるため、ネットワーク ポリシーはサポートされません。 - Cilium または Calico では、
hostNetwork: true
に設定した Pod を管理せず、ネットワーク ポリシーでこれらの Pod を管理できません。
ノードのマシンタイプと割り当て可能なリソースについて詳しくは、Standard クラスタ アーキテクチャ - ノードをご覧ください。
ネットワーク ポリシーの適用を有効にする
Autopilot クラスタでは、ネットワーク ポリシーの適用はデフォルトで有効になっているため、ネットワーク ポリシーの作成にスキップできます。
Standard クラスタでネットワーク ポリシーの適用を有効にするには、gcloud CLI、 Trusted Cloud コンソール、または GKE API を使用します。
ネットワーク ポリシーの適用は、GKE Dataplane V2 に組み込まれています。GKE Dataplane V2 を使用するクラスタでネットワーク ポリシーの適用を有効にする必要はありません。
この変更を行うにはノードの再作成が必要になり、実行中のワークロードが中断する可能性があります。この変更について詳しくは、ノード アップグレード戦略に従ってノードを再作成し、メンテナンス ポリシーを遵守する手動変更の表で対応する行をご覧ください。ノードの更新の詳細については、ノードの更新による中断の計画をご覧ください。
gcloud
-
In the Trusted Cloud console, activate Cloud Shell.
At the bottom of the Trusted Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.
クラスタの作成時にネットワーク ポリシーの適用を有効にするには、次のコマンドを実行します。
gcloud container clusters create CLUSTER_NAME --enable-network-policy
CLUSTER_NAME
は、新しいクラスタの名前に置き換えます。既存のクラスタに対してネットワーク ポリシーの適用を有効にするには、次のタスクを実行します。
次のコマンドを実行して、アドオンを有効にします。
gcloud container clusters update CLUSTER_NAME --update-addons=NetworkPolicy=ENABLED
CLUSTER_NAME
は、クラスタの名前に置き換えます。次のコマンドを実行してクラスタでネットワーク ポリシーの適用を有効にします。これにより、ネットワーク ポリシーの適用が有効に設定されて、クラスタのノードプールが再作成されます。
gcloud container clusters update CLUSTER_NAME --enable-network-policy
Trusted Cloud コンソールで [Google Kubernetes Engine] ページに移動します。
[add_box 作成] をクリックします。
[クラスタを作成] ダイアログで、GKE Standard の [構成] をクリックします。
選択したとおりにクラスタを構成します。
ナビゲーション パネルの [クラスタ] の下の [ネットワーキング] をクリックします。
[ネットワーク ポリシーを有効にする] チェックボックスを選択します。
[作成] をクリックします。
Trusted Cloud コンソールで [Google Kubernetes Engine] ページに移動します。
クラスタのリストで、変更するクラスタの名前をクリックします。
[ネットワーキング] の [ネットワーク ポリシー] フィールドで、edit [ネットワーク ポリシーを編集] をクリックします。
[マスターのネットワーク ポリシーの有効化] チェックボックスをオンにして、[変更を保存] をクリックします。
変更が適用されるのを待ってから、edit [ネットワーク ポリシーを編集] を再度クリックします。
[ノードのネットワーク ポリシーの有効化] チェックボックスをオンにします。
[変更を保存] をクリックします。
projects.zones.clusters.create または projects.zones.clusters.update に渡す
cluster
オブジェクト内にnetworkPolicy
オブジェクトを指定します。networkPolicy
オブジェクトには、使用するネットワーク ポリシー プロバイダを指定する列挙値と、ネットワーク ポリシーを有効にするかどうかを指定するブール値が必要です。ネットワーク ポリシーを有効にしてもプロバイダを設定しないと、create
コマンドとupdate
コマンドはエラーを返します。
コンソール
新しいクラスタの作成時にネットワーク ポリシーの適用を有効にするには:
既存のクラスタに対するネットワーク ポリシーの適用を有効にするには:
API
ネットワーク ポリシーの適用を有効にするには、次のようにします。
Standard クラスタでネットワーク ポリシーの適用を無効にする
ネットワーク ポリシーの適用は、gcloud CLI、 Trusted Cloud コンソール、または GKE API を使用して無効にできます。Autopilot クラスタまたは GKE Dataplane V2 を使用するクラスタでネットワーク ポリシーの適用を無効にすることはできません。
この変更を行うにはノードの再作成が必要になり、実行中のワークロードが中断する可能性があります。この変更について詳しくは、ノード アップグレード戦略に従ってノードを再作成し、メンテナンス ポリシーを遵守する手動変更の表で対応する行をご覧ください。ノードの更新の詳細については、ノードの更新による中断の計画をご覧ください。
gcloud
-
In the Trusted Cloud console, activate Cloud Shell.
At the bottom of the Trusted Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.
ネットワーク ポリシーの適用を無効にするには、次の操作を行います。
- クラスタでネットワーク ポリシーの適用を無効にします。
gcloud container clusters update CLUSTER_NAME --no-enable-network-policy
CLUSTER_NAME
は、クラスタの名前に置き換えます。このコマンドを実行すると、GKE はネットワーク ポリシーの適用を無効にしたクラスタ ノードプールを再作成します。
すべてのノードが再作成されたことを確認します。
kubectl get nodes -l projectcalico.org/ds-ready=true
オペレーションが成功すると、出力は次のようになります。
No resources found
出力が次のような場合は、GKE がノードプールの更新を完了するまで待つ必要があります。
NAME STATUS ROLES AGE VERSION gke-calico-cluster2-default-pool-bd997d68-pgqn Ready,SchedulingDisabled <none> 15m v1.22.10-gke.600 gke-calico-cluster2-np2-c4331149-2mmz Ready <none> 6m58s v1.22.10-gke.600
ネットワーク ポリシーの適用を無効にすると、構成されたメンテナンスの時間枠または除外がクラスタにある場合、GKE がすぐにはノードを更新しないことがあります。詳細については、クラスタの更新が遅いをご覧ください。
すべてのノードが再作成されたら、アドオンを無効にします。
gcloud container clusters update CLUSTER_NAME --update-addons=NetworkPolicy=DISABLED
Trusted Cloud コンソールで [Google Kubernetes Engine] ページに移動します。
クラスタのリストで、変更するクラスタの名前をクリックします。
[ネットワーキング] の [ネットワーク ポリシー] フィールドで、edit [ネットワーク ポリシーを編集] をクリックします。
[ノードのネットワーク ポリシーの有効化] チェックボックスをオフにして、[変更を保存] をクリックします。
変更が適用されるのを待ってから、edit [ネットワーク ポリシーを編集] を再度クリックします。
[マスターのネットワーク ポリシーの有効化] チェックボックスをオフにします。
[変更を保存] をクリックします。
setNetworkPolicy
API を使用して、networkPolicy.enabled: false
を使用するようにクラスタを更新します。gcloud CLI を使用して、すべてのノードが再作成されたことを確認します。
kubectl get nodes -l projectcalico.org/ds-ready=true
オペレーションが成功すると、出力は次のようになります。
No resources found
出力が次のような場合は、GKE がノードプールの更新を完了するまで待つ必要があります。
NAME STATUS ROLES AGE VERSION gke-calico-cluster2-default-pool-bd997d68-pgqn Ready,SchedulingDisabled <none> 15m v1.22.10-gke.600 gke-calico-cluster2-np2-c4331149-2mmz Ready <none> 6m58s v1.22.10-gke.600
ネットワーク ポリシーの適用を無効にすると、構成されたメンテナンスの時間枠または除外がクラスタにある場合、GKE がすぐにはノードを更新しないことがあります。詳細については、クラスタの更新が遅いをご覧ください。
updateCluster
API を使用して、update.desiredAddonsConfig.NetworkPolicyConfig.disabled: true
を使用するようにクラスタを更新します。
コンソール
既存のクラスタに対するネットワーク ポリシーの適用を無効にするには、次のようにします。
API
既存のクラスタに対するネットワーク ポリシーの適用を無効にするには、次のようにします。
ネットワーク ポリシーを作成する
ネットワーク ポリシーは、Kubernetes Network Policy API を使用して作成できます。
ネットワーク ポリシーの作成について詳しくは、Kubernetes ドキュメントの次のトピックをご覧ください。
ネットワーク ポリシーと GKE 用 Workload Identity 連携
GKE 用 Workload Identity 連携でネットワーク ポリシーを使用する場合は、Pod が GKE メタデータ サーバーと通信できるように、次の IP アドレスへの下り(外向き)を許可する必要があります。
- GKE バージョン 1.21.0-gke.1000 以降を実行しているクラスタでは、ポート
988
で169.254.169.252/32
への下り(外向き)を許可します。 - 1.21.0-gke.1000 より前の GKE バージョンを実行しているクラスタでは、ポート
988
で127.0.0.1/32
への下り(外向き)を許可します。 - GKE Dataplane V2 を実行しているクラスタでは、ポート
80
で169.254.169.254/32
への下り(外向き)を許可します。
これらの IP アドレスとポートへの下り(外向き)を許可しない場合は、自動アップグレード中にサービスの中断が発生する可能性があります。
Calico から GKE Dataplane V2 への移行
ネットワーク ポリシーを Calico から GKE Dataplane V2 に移行する場合は、次の制限事項を考慮してください。
NetworkPolicy
マニフェストのipBlock.cidr
フィールドに Pod または Service の IP アドレスを使用することはできません。ワークロードはラベルを使用して参照する必要があります。たとえば、次の構成は無効です。- ipBlock: cidr: 10.8.0.6/32
NetworkPolicy
マニフェストで空のports.port
フィールドを指定することはできません。プロトコルを指定する場合は、ポートも指定する必要があります。たとえば、次の構成は無効です。ingress: - ports: - protocol: TCP
アプリケーション ロードバランサの操作
Ingress を Service に適用してアプリケーション ロードバランサを構築する場合は、Service の背後にある Pod に適用されるネットワーク ポリシーを構成して、適切なアプリケーション ロードバランサのヘルスチェック IP 範囲を許可する必要があります。内部アプリケーション ロードバランサを使用する場合は、プロキシ専用サブネットを許可するようにネットワーク ポリシーを構成する必要もあります。
ネットワーク エンドポイント グループでコンテナネイティブのロード バランシングを使用しない場合は、Service のノードポートが他のノードの Pod に接続を転送する可能性があります。これを回避するには、Service の定義で externalTrafficPolicy
を Local
に設定します。externalTrafficPolicy
を Local
に設定しない場合は、ネットワーク ポリシーでクラスタ内の他のノード IP からの接続も許可する必要があります。
ipBlock ルールへの Pod IP 範囲の追加
特定の Pod のトラフィックを制御するには、NetworkPolicy の上り(内向き)ルールまたは下り(外向き)ルールで namespaceSelector
フィールドと podSelector
フィールドを使用して、Namespace または Pod ラベルごとに Pod を選択します。Pod の IP アドレス範囲を意図的に選択するために ipBlock.cidr
フィールドを使用することは避けてください。これは本質的にエフェメラルです。Kubernetes プロジェクトで、Pod の IP アドレス範囲が含まれている場合の ipBlock.cidr
フィールドの動作は明確に定義されていません。Pod の IP アドレス範囲を含めて、このフィールドに広い CIDR 範囲(0.0.0.0/0
など)を指定すると、NetworkPolicy のさまざまな実装で予期しない結果が生じる可能性があります。
以下のセクションでは、GKE における NetworkPolicy のさまざまな実装で、ipBlock.cidr フィールドで指定した IP アドレス範囲がどのように評価され、それらが幅広い CIDR 範囲に本質的に含まれる Pod IP アドレス範囲にどのように影響するかについて説明します。実装間の動作の違いを理解しておくと、別の実装に移行する際の結果に備えることができます。
GKE Dataplane V2 での ipBlock の動作
NetworkPolicy の GKE Dataplane V2 実装では、Pod のトラフィックは ipBlock
ルールの対象外です。したがって、cidr: '0.0.0.0/0'
などの広範なルールを定義しても、Pod トラフィックは含まれません。たとえば、これは、Pod からのトラフィックを許可せずに、Namespace 内の Pod がインターネットからのトラフィックを受信することを許可する場合に便利です。Pod トラフィックも含めるには、NetworkPolicy の上り(内向き)ルールまたは下り(外向き)ルールの定義で、追加の Pod または Namespace セレクタを使用して、Pod を明示的に選択します。
Calico での ipBlock の動作
NetworkPolicy の Calico 実装では、Pod トラフィックが ipBlock
ルールの対象となります。この実装で、Pod トラフィックを許可せずに広範な CIDR 範囲を構成するには、次の例のように、クラスタの Pod CIDR 範囲を明示的に除外します。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-non-pod-traffic
spec:
ingress:
- from:
- ipBlock:
cidr: '0.0.0.0/0'
except: ['POD_IP_RANGE']
この例の POD_IP_RANGE
は、クラスタの Pod の IPv4 アドレス範囲です(例: 10.95.0.0/17
)。複数の IP 範囲がある場合は、配列に個別に含めることができます(例: ['10.95.0.0/17', '10.108.128.0/17']
)。
externalTrafficPolicy
を使用してネットワーク ポリシーの動作を制御する
Service の externalTrafficPolicy
設定は、Kubernetes がネットワーク ポリシーを適用する方法に影響します。この設定により、Pod が受信トラフィックに対して認識する送信元 IP アドレスが決まります。これは、Kubernetes が NetworkPolicy ルールを評価する方法に影響する可能性があります。
externalTrafficPolicy
で使用可能な値は次の 2 つです。
Cluster
:externalTrafficPolicy
がCluster
に設定されている場合、宛先 Pod は送信元 IP アドレスを、トラフィックが最初に受信されたノードの IP アドレスと見なします。クライアント IP アドレスに基づいてトラフィックを拒否する NetworkPolicy があり、リモートノードの IP アドレスが含まれていない場合、ポリシールールで指定された外部クライアントからの外部トラフィックが意図せずブロックされる可能性があります。これを回避するには、クラスタ内のすべてのノードからのトラフィックを許可するポリシーを作成します。ただし、このポリシーでは、任意の外部クライアントからのトラフィックが許可されます。Local
:externalTrafficPolicy
がLocal
に設定されている場合、Pod は送信元 IP アドレスを元のクライアント IP アドレスと見なします。これにより、実際のクライアント IP アドレスに基づいてルールを定義できるため、ネットワーク ポリシーでよりきめ細かい制御が可能になります。
トラブルシューティング
Pod が Private Service Connect を使用するクラスタ上のコントロール プレーンと通信できない
コントロール プレーンの内部 IP アドレスへの Pod の下り(外向き)が下り(外向き)ネットワークで制限されている場合、Private Service Connect を使用する GKE クラスタの Pod でコントロール プレーンとの通信に問題が発生する可能性があります。
この問題には次のように対処してください。
クラスタで Private Service Connect を使用していることを確認します。Private Service Connect を使用するクラスタで、サブネットの作成時に
master-ipv4-cidr
フラグを使用すると、GKE はmaster-ipv4-cidr
で定義した値から各コントロール プレーンに内部 IP アドレスを割り当てます。それ以外の場合は、GKE はクラスタノード サブネットを使用して、各コントロール プレーンに内部 IP アドレスを割り当てます。コントロール プレーンの内部 IP アドレスへのトラフィックを許可するように、クラスタの下り(外向き)ポリシーを構成します。
コントロール プレーンの内部 IP アドレスを確認するには:
gcloud
privateEndpoint
を探すには、次のコマンドを実行します。gcloud container clusters describe CLUSTER_NAME
CLUSTER_NAME
はクラスタの名前で置き換えます。このコマンドは、指定したクラスタの
privateEndpoint
を取得します。コンソール
Trusted Cloud コンソールで [Google Kubernetes Engine] ページに移動します。
ナビゲーション パネルの [クラスタ] で、内部 IP アドレスを確認するクラスタをクリックします。
[クラスタの基本] で、内部 IP アドレスが表示されている
Internal endpoint
に移動します。
privateEndpoint
またはInternal endpoint
が見つかったら、コントロール プレーンの内部 IP アドレスへのトラフィックを許可するようにクラスタの下り(外向き)ポリシーを構成します。詳細については、ネットワーク ポリシーを作成するをご覧ください。
クラスタの更新が遅い
既存のクラスタでネットワーク ポリシーの適用を有効または無効にすると、クラスタにメンテナンスの時間枠または除外が構成されている場合、GKE によってノードが直ちに更新されない場合があります。
ノードプールを手動でアップグレードするには、--cluster-version
フラグを、コントロール プレーンが実行中のものと同じ GKE バージョンに設定します。この操作は、Google Cloud CLI で行う必要があります。詳細については、メンテナンス時間枠の注意点をご覧ください。
手動でデプロイした Pod のスケジューリングが解除される
既存のクラスタのコントロール プレーンでネットワーク ポリシーの適用を有効にすると、GKE は、手動でデプロイされた ip-masquerade-agent や calico ノードの Pod のスケジュールを解除します。
クラスタノードでネットワーク ポリシーの適用が有効になり、ノードが再作成されるまで、GKE はこれらの Pod の再スケジュールを行いません。
メンテナンスの時間枠または除外を構成している場合は、これによって中断が延長される可能性があります。
この中断期間を最小限に抑えるために、次のラベルをクラスタノードに手動で割り当てできます。
node.kubernetes.io/masq-agent-ds-ready=true
projectcalico.org/ds-ready=true
ネットワーク ポリシーが機能しない
NetworkPolicy が有効でない場合は、次の手順でトラブルシューティングを行います。
ネットワーク ポリシーの適用が有効になっていることを確認します。使用するコマンドは、クラスタで GKE Dataplane V2 が有効かどうかによって異なります。
クラスタで GKE Dataplane V2 が有効になっている場合は、次のコマンドを実行します。
kubectl -n kube-system get pods -l k8s-app=cilium
出力が空の場合、ネットワーク ポリシーの適用は有効になっていません。
クラスタで GKE Dataplane V2 が有効になっていない場合は、次のコマンドを実行します。
kubectl get nodes -l projectcalico.org/ds-ready=true
出力が空の場合、ネットワーク ポリシーの適用は有効になっていません。
Pod のラベルを確認します。
kubectl describe pod POD_NAME
POD_NAME
は、Pod の名前で置き換えます。出力は次のようになります。
Labels: app=store pod-template-hash=64d9d4f554 version=v1
ポリシーのラベルが Pod のラベルと一致することを確認します。
kubectl describe networkpolicy
出力は次のようになります。
PodSelector: app=store
この出力では、
app=store
ラベルは前の手順のapp=store
ラベルと一致します。ワークロードを選択するネットワーク ポリシーがあるかどうかを確認します。
kubectl get networkpolicy
出力が空の場合、Namespace に NetworkPolicy が作成されておらず、何もワークロードを選択していません。出力が空でない場合は、ポリシーでワークロードが選択されていることを確認します。
kubectl describe networkpolicy
出力は次のようになります。
... PodSelector: app=nginx Allowing ingress traffic: To Port: <any> (traffic allowed to all ports) From: PodSelector: app=store Not affecting egress traffic Policy Types: Ingress
既知の問題
Calico を使用した StatefulSet Pod の終了
Calico ネットワーク ポリシーが有効になっている GKE クラスタでは、Pod の削除時に StatefulSet Pod が既存の接続を切断するという問題が発生する場合があります。Pod が Terminating
状態になると、Pod 仕様の terminationGracePeriodSeconds
構成が優先されて、StatefulSet Pod との接続がすでに存在する他のアプリケーションが中断します。この問題の詳細については、Calico 問題 #4710 をご覧ください。
この問題は、次の GKE バージョンに影響します。
- 1.18
- 1.19~1.19.16-gke.99
- 1.20~1.20.11-gke.1299
- 1.21~1.21.4-gke.1499
この問題を軽減するには、GKE コントロール プレーンを次のいずれかのバージョンにアップグレードします。
- 1.19.16-gke.100 以降
- 1.20.11-gke.1300 以降
- 1.21.4-gke.1500 以降
Pod が containerCreating
状態で停止する
Calico ネットワーク ポリシーが有効になっている GKE クラスタで、Pod が containerCreating
状態のままになる可能性があります。
Pod の [イベント] タブに、次のようなメッセージが表示されます。
plugin type="calico" failed (add): ipAddrs is not compatible with
configured IPAM: host-local
この問題を軽減するには、GKE クラスタの calico-ipam を使用するのではなく Calico のホストローカル ipam を使用します。