このドキュメントでは、TCP トラフィックと UDP トラフィックの両方に混合プロトコルの外部 LoadBalancer Service を使用して、Google Kubernetes Engine(GKE)クラスタで実行されているアプリケーションをインターネットに公開する方法について説明します。
外部パススルー ネットワーク ロードバランサの詳細については、バックエンド サービスベースの外部パススルー ネットワーク ロードバランサをご覧ください。
概要
TCP プロトコルと UDP プロトコルの両方を使用するアプリケーションは、手動で調整された共有 IP アドレスを使用して、2 つの別々の GKE LoadBalancer Service を使用して公開できます。ただし、このアプローチでは、単一のアプリケーションに対して複数の Service を管理する必要があるため、非効率的です。また、構成エラーや IP アドレス割り当ての枯渇などの問題が発生する可能性があります。
混合プロトコル LoadBalancer Service を使用すると、単一の Service を使用して TCP と UDP の両方のトラフィックを管理できます。単一の Service を使用すると、両方のプロトコルに単一の IPv4 アドレスと統合された転送ルールのセットを使用できるため、構成が簡素化されます。この機能は、外部パススルー ネットワーク ロードバランサでサポートされています。
始める前に
作業を始める前に、次のタスクが完了していることを確認してください。
- Google Kubernetes Engine API を有効にする。 Google Kubernetes Engine API を有効化
- このタスクに Google Cloud CLI を使用する場合は、gcloud CLI をインストールして初期化する。gcloud CLI をインストール済みの場合は、
gcloud components updateコマンドを実行して最新のバージョンを取得します。以前のバージョンの gcloud CLI では、このドキュメントのコマンドを実行できない場合があります。
- すでに Autopilot クラスタまたは Standard クラスタが存在していることを確認する。新しいクラスタを作成するには、Autopilot クラスタの作成をご覧ください。
要件
混合プロトコルを使用する外部 LoadBalancer Service を作成するには、クラスタが次の要件を満たしている必要があります。
- 混合プロトコル ロード バランシングは、バージョン 1.34.1-gke.2190000 以降で新しく作成されたクラスタでのみ使用できます。
- クラスタで
HttpLoadBalancingアドオンが有効になっている必要があります。 - 新しい外部 LoadBalancer Service の場合、ロードバランサを実装するには、Service マニフェストで
spec.loadBalancerClassフィールドをnetworking.gke.io/l4-regional-externalに設定します。既存の Service の場合、マニフェストにはすでにcloud.google.com/l4-rbs: "enabled"アノテーションが含まれているため、アノテーションはそのままにしておきます。
制限事項
- 混合プロトコル ロードバランサは、IPv4 アドレスのみをサポートします。
次のファイナライザーを含む Service マニフェストでは、混合プロトコルを使用できません。
gke.networking.io/l4-ilb-v1gke.networking.io/l4-netlb-v1
マニフェストにこれらのファイナライザーがある場合は、上記の要件に従って Service を削除して再作成する必要があります。
料金
Google Cloud では、転送ルールごと、外部 IP アドレスごと、送信されたデータごとに課金されます。次の表に、指定された構成で使用される転送ルールと外部 IP アドレスの数を示します。詳細については、VPC ネットワークの料金をご覧ください。
| タイプ | トランスポート層 | インターネット層 | 転送ルール数 | 外部 IP アドレスの数 |
|---|---|---|---|---|
| 外部 | 単一(TCP または UDP のいずれか) | IPv4 | 1 | 1 |
| IPv6 | 1 | 1 | ||
| IPv4 と IPv6(デュアル スタック) | 2 | 2 | ||
| 混合(TCP と UDP の両方) | IPv4 | 2 | 1 |
ワークロードをデプロイする
このセクションでは、TCP ポートと UDP ポートの両方でリッスンするサンプル ワークロードをデプロイする方法について説明します。混合プロトコル LoadBalancer Service を使用しているか、2 つの個別の単一プロトコル LoadBalancer Service を使用しているかに関係なく、Deployment 構成は同じです。
次のマニフェストは、TCP と UDP の両方のトラフィックでポート 8080 をリッスンするサンプル アプリケーション用です。次のマニフェストを
mixed-app-deployment.yamlとして保存します。apiVersion: apps/v1 kind: Deployment metadata: name: mixed-app-deployment spec: replicas: 3 selector: matchLabels: app: mixed-app template: metadata: labels: app: mixed-app spec: containers: - image: gcr.io/kubernetes-e2e-test-images/agnhost:2.6 name: agnhost args: ["serve-hostname", "--port=8080", "--tcp=true", "--udp=true", "--http=false"] ports: - name: tcp8080 protocol: TCP containerPort: 8080 - name: udp8080 protocol: UDP containerPort: 8080マニフェストをクラスタに適用します。
kubectl apply -f mixed-app-deployment.yaml
混合プロトコル ロードバランサを作成する
TCP トラフィックと UDP トラフィックの両方に Deployment を公開する LoadBalancer タイプの Service を作成します。
次のマニフェストを
mixed-protocol-lb.yamlとして保存します。apiVersion: v1 kind: Service metadata: name: mixed-protocol-lb spec: loadBalancerClass: "networking.gke.io/l4-regional-external" type: LoadBalancer selector: app: mixed-app ports: - name: tcp-port protocol: TCP port: 8080 - name: udp-port protocol: UDP port: 8080上記の Service には、TCP 用と UDP 用の 2 つのポートがあり、どちらもポート 8080 にあります。
マニフェストをクラスタに適用します。
kubectl apply --server-side -f mixed-protocol-lb.yaml
混合プロトコル ロードバランサを確認する
Service を作成したら、GKE がロードバランサを正常に作成したことを確認します。
サービスの検査:
kubectl describe service mixed-protocol-lb出力には、ロードバランサの外部 IP アドレスと、TCP と UDP の両方の転送ルールが表示されます。出力で次の詳細を確認します。
status.loadBalancer.ingress.ipフィールドが入力されます。- 外部ロードバランサの次のアノテーションが存在することを確認します。
service.kubernetes.io/tcp-forwarding-ruleservice.kubernetes.io/udp-forwarding-rule
Eventsセクションにエラー メッセージが含まれていない。
混合プロトコル ロードバランサを更新する
混合プロトコル ロードバランサのポートは、Service マニフェストを編集して更新できます。Service を編集するには、次のコマンドを実行します。
kubectl edit service SERVICE_NAME
SERVICE_NAME は、実際の Service 名に置き換えます。
ポートを更新する
混合プロトコル ロードバランサのポートを更新するには、Service マニフェストの ports セクションを変更します。ポートの追加、削除、変更ができます。
次の例では、ストリーミング用の UDP ポートとゲームサーバー メタデータ用の TCP ポートを追加します。
apiVersion: v1
kind: Service
metadata:
name: mixed-protocol-lb
spec:
loadBalancerClass: "networking.gke.io/l4-regional-external"
type: LoadBalancer
selector:
app: mixed-app
ports:
- name: tcp-port
protocol: TCP
port: 8080
- name: streaming
protocol: UDP
port: 10100
- name: gameserver-metadata
protocol: TCP
port: 10400
- name: https
protocol: TCP
port: 443
単一プロトコル ロードバランサを混合プロトコルに更新する
単一プロトコル ロードバランサを混合プロトコル ロードバランサに変更するには、TCP プロトコルと UDP プロトコルの両方のポートを含むように Service を編集します。
次の例では、DNS の UDP ポートを既存の TCP 専用ロードバランサに追加します。
apiVersion: v1
kind: Service
metadata:
name: already-existing-single-protocol-lb
spec:
loadBalancerClass: "networking.gke.io/l4-regional-external"
type: LoadBalancer
selector:
app: mixed-app
ports:
- name: http
protocol: TCP
port: 80
- name: https
protocol: TCP
port: 443
- name: dns
protocol: UDP
port: 53
混合プロトコル ロードバランサを単一プロトコルに更新する
混合プロトコル ロードバランサを単一プロトコル ロードバランサに変更するには、いずれかのプロトコルのすべてのポートを削除します。
次の例では、DNS の UDP ポートを削除し、ロードバランサを TCP 専用に変換します。
apiVersion: v1
kind: Service
metadata:
name: already-existing-mixed-protocol-lb
spec:
loadBalancerClass: "networking.gke.io/l4-regional-external"
type: LoadBalancer
selector:
app: mixed-app
ports:
- name: http
protocol: TCP
port: 80
- name: https
protocol: TCP
port: 443
混合プロトコル LoadBalancer を削除する
mixed-protocol-lb 外部 LoadBalancer Service を削除するには、次のコマンドを実行します。
kubectl delete service mixed-protocol-lb
GKE は、Service 用に作成されたすべてのロードバランサ リソースを自動的に削除します。
トラブルシューティング
このセクションでは、混合プロトコルの LoadBalancer Service に関する一般的な問題を解決する方法について説明します。
エラーイベントを確認する
トラブルシューティングの最初の手順は、サービスに関連付けられているイベントを確認することです。
Service の詳細を取得します。
kubectl describe service mixed-protocol-lb出力の末尾にある
Eventsセクションで、エラー メッセージを確認します。
エラー: LoadBalancer で混合プロトコルはサポートされていません
cloud.google.com/l4-rbs: "enabled" アノテーションを使用して Service を作成した場合、混合プロトコル ロードバランサの作成後に、元のサービス コントローラから警告イベント mixed-protocol is not
supported for LoadBalancer が表示されることがあります。
新しいコントローラは混合プロトコルをサポートしており、ロードバランサを正しくプロビジョニングするため、このメッセージは無視してかまいません。
更新後にポート定義が欠落している
症状:
TCP と UDP の両方に同じポート(ポート 8080 など)を使用する Service を更新すると、更新された Service からポート定義の 1 つが欠落します。
原因:
これは Kubernetes の既知の問題です。同じポートで複数のプロトコルを使用して Service を更新すると、クライアント側のパッチ計算でポートリストが誤って統合され、ポート定義の 1 つが削除されることがあります。この問題は、kubectl apply やマージ パッチを使用する Go クライアントなど、クライアントサイド パッチ適用を使用するクライアントに影響します。
ソリューション:
この問題の回避策は、クライアントによって異なります。
kubectl の場合:
kubectl applyで--server-sideフラグを使用します。kubectl apply --server-side -f YOUR_SERVICE_MANIFEST.yamlYOUR_SERVICE_MANIFESTは、Service マニフェストの名前に置き換えます。go-client の場合: マージ パッチを使用しないでください。代わりに、更新呼び出しを使用して Service を置き換えます。これには、Service オブジェクトの仕様全体を含む HTTP
PUTリクエストが必要です。
次のステップ
- Service を使用してアプリケーションを公開する方法を確認する。
- LoadBalancer Service について確認する。