このドキュメントでは、GKE で Google Cloud 外部パススルー ネットワーク ロードバランサと内部パススルー ネットワーク ロードバランサのリソースを作成して、マルチネットワーク Pod を内部クライアントまたは外部クライアントに公開する方法について説明します。マルチネットワーク LoadBalancer サービスに必要な構成、機能、制限について説明します。
ワークロードを複数の VPC ネットワークに接続する場合は、タイプ LoadBalancer の Kubernetes Service を使用して、特定のセカンダリ ネットワーク上の Pod にトラフィックを転送します。Service を作成すると、GKE はこのトラフィックを管理するパススルー ネットワーク ロードバランサを作成します。
GKE のマルチネットワーキングの詳細については、Pod のマルチネットワーク サポートについてをご覧ください。
マルチネットワーク LoadBalancer Service の仕組み
マルチネットワーク ワークロードを公開するには、type: LoadBalancer の Service を作成します。Service には、セカンダリ インターフェースのネットワークに基づいて Pod をターゲットとする特別なセレクタを含める必要があります。内部ロードバランサと外部ロードバランサのどちらを作成するかを指定するアノテーションを追加します。
セレクタの networking.gke.io/network ラベルは、ネットワークでエンドポイントをフィルタします。このラベルにより、ロードバランサは指定されたネットワークに接続された Pod インターフェースにのみトラフィックを送信します。
制限事項
マルチネットワーク ロードバランサには次の制限があります。
externalTrafficPolicy: Clusterを使用するサービスはサポートされていません。hostNetworkPod をターゲットとするサービスはサポートされていません。- IPv6 とデュアルスタック ネットワーキングはサポートされていません。
- 既存の Service のネットワークは変更できません。
- レイヤ 3 ネットワークのみがサポートされます。
- ターゲット プールまたはインスタンス グループのバックエンドに基づくロードバランサはサポートされていません。
- ClusterIP Service と NodePort Service は、セカンダリ(デフォルト以外)ネットワークではサポートされていません。
始める前に
始める前に、次のタスクを完了します。
- Pod のマルチネットワーク サポートを設定するの手順に沿って、VPC ネットワークを準備し、追加のネットワークを使用して GKE クラスタを作成します。
- クラスタでレイヤ 4 内部ロードバランサのサブセット化が有効になっていることを確認します。この機能を有効にするには、クラスタの作成または更新時に
--enable-l4-ilb-subsettingフラグを使用します。 - クラスタで GKE バージョン 1.37 以降が実行されていることを確認します。
マルチネットワーク Pod をデプロイする
Pod を追加のネットワークに接続するには、networking.gke.io/interfaces アノテーションを使用して Deployment を作成します。このアノテーションは、Pod のネットワークとインターフェースを指定します。
次のマニフェストを
web-app-deployment.yamlとして保存します。apiVersion: apps/v1 kind: Deployment metadata: name: web-app labels: app: web-app spec: replicas: 3 selector: matchLabels: app: web-app template: metadata: labels: app: web-app annotations: networking.gke.io/default-interface: 'eth1' networking.gke.io/interfaces: '[ {"interfaceName":"eth0","network":"default"}, {"interfaceName": "eth1","network": "dmz"} ]' spec: containers: - name: whereami image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1 ports: - containerPort: 8080このマニフェストは、3 つの Pod を持つ
web-appという名前の Deployment を作成します。Pod には、defaultネットワークに接続されたeth0とdmzネットワークに接続されたeth1の 2 つのインターフェースがあります。networking.gke.io/default-interfaceアノテーションは、Pod のデフォルト インターフェースとしてeth1を設定します。マニフェストをクラスタに適用します。
kubectl apply -f web-app-deployment.yaml
Service にデフォルト以外のインターフェースを使用する場合は、Pod 内でルーティングを構成する必要があります。ルーティングを構成するには、NET_ADMIN 機能を持つ initContainer を Pod 仕様に追加します。
次の例は、eth1 インターフェースのデフォルト ルートを追加する initContainer を示しています。
initContainers:
- name: init-routes-busybox
image: busybox
command: ['sh', '-c', 'ip route add default dev eth1 table 200 && ip rule add from 172.16.1.0/24 table 200']
securityContext:
capabilities:
add: ["NET_ADMIN"]
initContainer コマンドで、172.16.1.0/24 を Pod ネットワークのセカンダリ IP アドレス範囲に置き換えます。
内部 LoadBalancer Service をデプロイする
dmz ネットワークで web-app Deployment を公開するには、内部 LoadBalancer Service を作成します。
次のマニフェストを
internal-lb-service.yamlとして保存します。apiVersion: v1 kind: Service metadata: name: web-app-internal-lb namespace: default annotations: networking.gke.io/load-balancer-type: "Internal" spec: externalTrafficPolicy: Local ports: - port: 80 protocol: TCP targetPort: 8080 selector: networking.gke.io/network: dmz app: web-app type: LoadBalancerこのマニフェストは、次のプロパティを持つ Service を作成します。
networking.gke.io/load-balancer-type: "Internal": 内部パススルー ネットワーク ロードバランサを指定します。selector:dmzネットワークに接続されているapp: web-appラベルを持つ Pod を選択します。
マニフェストをクラスタに適用します。
kubectl apply -f internal-lb-service.yaml
外部 LoadBalancer Service をデプロイする
web-app Deployment を外部クライアントに公開するには、外部 LoadBalancer Service を作成します。
次のマニフェストを
external-lb-service.yamlとして保存します。apiVersion: v1 kind: Service metadata: name: web-app-external-lb namespace: default annotations: cloud.google.com/l4-rbs: "enabled" spec: externalTrafficPolicy: Local ports: - port: 80 protocol: TCP targetPort: 8080 selector: networking.gke.io/network: dmz app: web-app type: LoadBalancerこのマニフェストは、次のプロパティを持つ Service を作成します。
cloud.google.com/l4-rbs: "enabled": バックエンド サービスベースの外部パススルー ネットワーク ロードバランサを指定します。selector:dmzネットワークに接続されているラベルapp: web-appを持つ Pod を選択します。
マニフェストをクラスタに適用します。
kubectl apply -f external-lb-service.yaml
サービスを確認する
Service をデプロイしたら、ロードバランサが作成され、正しく構成されていることを確認します。
サービスのステータスを確認します。
kubectl get services出力は次のようになります。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE web-app-external-lb LoadBalancer 10.8.47.77 35.239.57.231 80:31550/TCP 5m web-app-internal-lb LoadBalancer 10.8.43.251 172.16.0.43 80:32628/TCP 6m kubernetes ClusterIP 10.8.32.1 <none> 443/TCP 43h内部ロードバランサの
EXTERNAL-IPアドレスはdmzネットワークに属しています。プロジェクト内の転送ルールを一覧表示します。
gcloud compute forwarding-rules list出力は次のようになります。
NAME REGION IP_ADDRESS IP_PROTOCOL TARGET af901673cc0f24907a6aa8c3ce4afc21 us-central1 35.239.57.231 TCP us-central1/backendServices/k8s2-xhvzqabw-default-web-app-external-lb-u4xbs4ot k8s2-tcp-xhvzqabw-default-web-app-internal-lb-vp1x1d6a us-central1 172.16.0.43 TCP us-central1/backendServices/k8s2-xhvzqabw-default-web-app-internal-lb-vp1x1d6a内部ロードバランサの転送ルールを説明して、正しいネットワークに接続されていることを確認します。
gcloud compute forwarding-rules describe k8s2-tcp-xhvzqabw-default-web-app-internal-lb-vp1x1d6a --region=$REGIONREGIONは、クラスタのリージョンに置き換えます。出力は次のようになります。
networkフィールドとsubnetworkフィールドがdmzネットワークの詳細と一致していることを確認します。IPAddress: 172.16.0.43 IPProtocol: TCP ... loadBalancingScheme: INTERNAL name: k8s2-tcp-xhvzqabw-default-web-app-internal-lb-vp1x1d6a network: https://www.googleapis.com/compute/v1/projects/projectId/global/networks/dmz-vpc ... subnetwork: https://www.googleapis.com/compute/v1/projects/projectId/regions/us-central1/subnetworks/dmz-subnet
ロードバランサをテストする
外部ロードバランサをテストするには、その外部 IP アドレスにリクエストを送信します。
curl EXTERNAL_LB_IP:80EXTERNAL_LB_IPは、web-app-external-lbService の外部 IP アドレスに置き換えます。内部ロードバランサをテストするには、ロードバランサと同じ VPC 内のホストからリクエストを送信します。
curl INTERNAL_LB_IP:80INTERNAL_LB_IPは、web-app-internal-lbService の IP アドレスに置き換えます。
トラブルシューティング
このセクションでは、マルチネットワーク ロードバランサに関する問題のトラブルシューティング方法について説明します。
ロードバランサの作成が失敗する
ロードバランサの作成に失敗した場合は、Service イベントでエラー メッセージを確認します。
kubectl describe service SERVICE_NAME
SERVICE_NAME は、実際の Service 名に置き換えます。
network some-other-network does not exist などのエラー メッセージは、Service セレクタで指定されたネットワークがクラスタで定義されていないことを示します。ネットワークが存在することを確認します。
kubectl get networks
ネットワークが存在する場合は、Network オブジェクトが有効な GKENetworkParamSet リソースを正しく参照していることを確認します。構成エラーを確認するには、Network リソースのステータスを調べます。
kubectl get networks NETWORK_NAME -o yaml
NETWORK_NAME はネットワーク名に置き換えてください。
有効な構成では、ParamsReady 条件と Ready 条件の両方が True です。ParamsReady が True でない場合は、Network 仕様の parametersRef が既存の GKENetworkParamSet リソースの名前、種類、グループと正しく一致していることを確認します。
Network リソースが正しいのに準備ができていない場合は、参照先の GKENetworkParamSet のステータスを調べて、サブネットの欠落などのエラーがないか確認します。
kubectl get gkenetworkparamsets GNP_NAME -o yaml
GNP_NAME は、GKENetworkParamSet の名前で置き換えます。
ロードバランサにバックエンドがない
ロードバランサがプロビジョニングされているが、正常なバックエンドがない場合は、次の操作を行います。
- Service が使用するネットワークにネットワーク インターフェースを持つノードプールが存在することを確認します。
- Service によって選択された Pod が実行されていることを確認します。
Service のエンドポイントを確認します。
kubectl describe endpointslice -l kubernetes.io/service-name=SERVICE_NAMEmultinet-endpointslice-controller.gke.ioコントローラは、マルチネットワーク エンドポイントを作成します。EndpointSlice にリストされている Pod の IP アドレスは、Service が使用するネットワークに属しています。EndpointSlice にエンドポイントがない場合は、Service セレクタのラベルが実行中の Pod と一致し、ネットワーク セレクタが Pod のネットワークと一致していることを確認します。
次のステップ
- Pod のマルチネットワーク サポートについて学習する。
- マルチネットワーク Service について学習する。