このページでは、Kubernetes Ingress オブジェクトを作成して外部アプリケーション ロードバランサを構成する方法について説明します。
このページを読む前に、GKE ネットワーキングのコンセプトを理解しておく必要があります。
始める前に
作業を始める前に、次のタスクが完了していることを確認してください。
- Google Kubernetes Engine API を有効にする。 Google Kubernetes Engine API の有効化
- このタスクに Google Cloud CLI を使用する場合は、gcloud CLI をインストールして初期化する。すでに gcloud CLI をインストールしている場合は、
gcloud components updateコマンドを実行して最新のバージョンを取得します。以前のバージョンの gcloud CLI では、このドキュメントのコマンドを実行できない場合があります。
- すでに Autopilot クラスタまたは Standard クラスタが存在していることを確認する。新しいクラスタを作成するには、Autopilot クラスタの作成をご覧ください。
HttpLoadBalancing アドオンを有効にする
クラスタで HttpLoadBalancing アドオンが有効になっている必要があります。このアドオンはデフォルトで有効になっています。Autopilot クラスタでは、このアドオンを無効にできません。
HttpLoadBalancing アドオンを有効にするには、 Cloud de Confiance コンソールまたは Google Cloud CLI を使用します。
コンソール
Cloud de Confiance コンソールで [Google Kubernetes Engine] ページに移動します。
変更するクラスタの名前をクリックします。
[ネットワーキング] の [HTTP 負荷分散] フィールドで、[edit HTTP 負荷分散の編集] をクリックします。
[HTTP ロード バランシングを有効にする] チェックボックスをオンにします。
[変更を保存] をクリックします。
gcloud
gcloud container clusters update CLUSTER_NAME --update-addons=HttpLoadBalancing=ENABLED
CLUSTER_NAME は、使用するクラスタの名前に置き換えます。
静的 IP アドレスを作成
外部アプリケーション ロードバランサは、1 つ以上の Service にリクエストをルーティングするために使用できる安定した IP アドレスを 1 つ提供します。永続的な IP アドレスが必要な場合は、Ingress を作成する前にグローバル静的外部 IP アドレスを予約する必要があります。
エフェメラル IP アドレスではなく静的 IP アドレスを使用するように既存の Ingress を変更すると、GKE がロードバランサの転送ルールを再作成するときに、ロードバランサの IP アドレスが変更されることがあります。
外部アプリケーション ロードバランサを作成する
この演習では、URL パスに応じてリクエストを異なる Service に転送するように外部アプリケーション ロードバランサを構成します。
Deployment と Service を作成する
hello-world-1 と hello-world-2 という名前の Service を使用する 2 つの Deployment を作成します。
次のマニフェストを
hello-world-deployment-1.yamlとして保存します。apiVersion: apps/v1 kind: Deployment metadata: name: hello-world-deployment-1 spec: selector: matchLabels: greeting: hello version: one replicas: 3 template: metadata: labels: greeting: hello version: one spec: containers: - name: hello-app-1 image: "us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0" env: - name: "PORT" value: "50000"このマニフェストでは、3 つのレプリカを含む Deployment のサンプルを記述しています。
マニフェストをクラスタに適用します。
kubectl apply -f hello-world-deployment-1.yaml次のマニフェストを
hello-world-service-1.yamlとして保存します。apiVersion: v1 kind: Service metadata: name: hello-world-1 spec: type: NodePort selector: greeting: hello version: one ports: - protocol: TCP port: 60000 targetPort: 50000このマニフェストでは、次のプロパティを持つ Service を記述しています。
greeting: helloラベルとversion: oneラベルの両方を持つすべての Pod はこの Service のメンバーです。- GKE は、TCP ポート 60000 で Service に送信されたリクエストを TCP ポート 50000 でメンバー Pod のいずれかに転送します。
- Service タイプは
NodePortです。これは、コンテナ ネイティブのロード バランシングを使用しない場合には必須です。コンテナ ネイティブのロード バランシングを使用している場合は、サービスのタイプに制限はありません。type: ClusterIPの使用をおすすめします。
マニフェストをクラスタに適用します。
kubectl apply -f hello-world-service-1.yaml次のマニフェストを
hello-world-deployment-2.yamlとして保存します。apiVersion: apps/v1 kind: Deployment metadata: name: hello-world-deployment-2 spec: selector: matchLabels: greeting: hello version: two replicas: 3 template: metadata: labels: greeting: hello version: two spec: containers: - name: hello-app-2 image: "us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0" env: - name: "PORT" value: "8080"このマニフェストでは、3 つのレプリカを含む Deployment のサンプルを記述しています。
マニフェストをクラスタに適用します。
kubectl apply -f hello-world-deployment-2.yaml次のマニフェストを
hello-world-service-2.yamlとして保存します。apiVersion: v1 kind: Service metadata: name: hello-world-2 spec: type: NodePort selector: greeting: hello version: two ports: - protocol: TCP port: 80 targetPort: 8080このマニフェストでは、次のプロパティを持つ Service を記述しています。
greeting: helloラベルとversion: twoラベルの両方を持つすべての Pod はこの Service のメンバーです。- GKE は、TCP ポート 80 で Service に送信されたリクエストを TCP ポート 8080 でメンバー Pod のいずれかに転送します。
マニフェストをクラスタに適用します。
kubectl apply -f hello-world-service-2.yaml
Ingress を作成する
リクエストの URL パスに応じて、リクエストをルーティングするためのルールを指定する Ingress を作成します。Ingress を作成すると、GKE Ingress コントローラによって外部アプリケーション ロードバランサが作成され、構成されます。
次のマニフェストを
my-ingress.yamlとして保存します。apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-ingress annotations: # If the class annotation is not specified it defaults to "gce". kubernetes.io/ingress.class: "gce" spec: rules: - http: paths: - path: /* pathType: ImplementationSpecific backend: service: name: hello-world-1 port: number: 60000 - path: /v2 pathType: ImplementationSpecific backend: service: name: hello-world-2 port: number: 80このマニフェストでは、次のプロパティを持つ Ingress を記述しています。
GKE Ingress クラスは 2 つあります。Ingress クラスを指定するには、
kubernetes.io/ingress.classアノテーションを使用する必要があります。spec.ingressClassNameを使用して GKE Ingress を指定することはできません。gceクラスは、外部アプリケーション ロードバランサをデプロイします。gce-internalクラスは、内部アプリケーション ロードバランサをデプロイします。アノテーション
spec.ingressClassNameとkubernetes.io/ingress.classのない Ingress リソースをデプロイすると、GKE によって外部アプリケーション ロードバランサが作成されます。これは、kubernetes.io/ingress.class: gceアノテーションを指定した場合と同じ動作です。詳細については、GKE Ingress コントローラの動作をご覧ください。GKE は、
backend.serviceごとに Cloud de Confiance バックエンド サービスを作成します。各バックエンド サービスは Kubernetes Service に対応し、各バックエンド サービスは Cloud de Confiance ヘルスチェックを参照する必要があります。このヘルスチェックはクラスタの外部で実装されるため、Kubernetes の liveness Probe または readiness Probe とは異なります。 詳細については、ヘルスチェックをご覧ください。クライアントが URL パス
/を使用してロードバランサにリクエストを送信すると、GKE はポート 60000 でリクエストをhello-world-1Service に転送します。クライアントが URL パス/v2を使用してロードバランサにリクエストを送信すると、GKE はポート 80 でリクエストをhello-world-2Service に転送します。pathプロパティとpathTypeプロパティの詳細については、URL パスをご覧ください。
マニフェストをクラスタに適用します。
kubectl apply -f my-ingress.yaml
外部アプリケーション ロードバランサをテストする
ロードバランサが構成されるまで 5 分ほど待ちます。構成されたら、外部アプリケーション ロードバランサをテストします。
Ingress を確認します。
kubectl get ingress my-ingress --output yaml出力には、外部アプリケーション ロードバランサの IP アドレスが表示されます。
status: loadBalancer: ingress: - ip: 203.0.113.1/パスをテストします。curl LOAD_BALANCER_IP_ADDRESS/LOAD_BALANCER_IP_ADDRESSは、ロードバランサの外部 IP アドレスに置き換えます。出力は次のようになります。
Hello, world! Version: 1.0.0 Hostname: ...出力に 404 エラーが含まれている場合は、数分待ちます。
/v2パスをテストします。curl load-balancer-ip/v2出力は次のようになります。
Hello, world! Version: 2.0.0 Hostname: ...
外部ロード バランシングでの Ingress の仕組み
外部アプリケーション ロードバランサは、クライアントとアプリケーションの間のプロキシとして機能します。クライアントからの HTTPS リクエストを受け入れるには、ロードバランサは証明書を持っていなければなりません。これにより、適切な送信先であることをクライアントに示すことができます。さらに、ロードバランサには、HTTPS handshake を完了するための秘密鍵も必要です。詳細情報
URL パス
Ingress の path フィールドでサポートされているワイルドカード文字は「*」のみです。「*」はスラッシュ(「/」)の直後に置かれる必要があり、パターンの最後の文字でなければなりません。たとえば、/*、/foo/*、/foo/bar/* は有効なパターンですが、*、/foo/bar*、/foo/*/bar は有効ではありません。
より具体的なパターンのほうが、そうでないものよりも優先されます。/foo/* と /foo/bar/* の両方を使用すると、/foo/bar/bat が /foo/bar/* と比較されます。パスの制限とパターン マッチングの詳細については、URL マップのドキュメントをご覧ください。
1.21.3-gke.1600 より前のバージョンを実行している GKE クラスタの場合、pathType フィールドでサポートされている値は ImplementationSpecific のみです。バージョン 1.21.3-gke.1600 以降を実行しているクラスタの場合、pathType には Prefix と Exact の値もサポートされています。
HTTP の無効化
クライアントとロードバランサ間のすべてのトラフィックで HTTPS を使用する場合は、HTTP を無効にできます。詳しくは、HTTP の無効化をご覧ください。
ロードバランサとアプリケーション間の HTTPS
GKE Pod で実行しているアプリケーションが HTTPS リクエストを受信できる場合は、ロードバランサがリクエストをアプリケーションに転送するときに HTTPS を使用するようにロードバランサを構成できます。詳しくは、ロードバランサとアプリケーション間の HTTPS(TLS)をご覧ください。
クライアントとロードバランサ間の HTTP/2
クライアントは HTTP/2 を使用してロードバランサにリクエストを送信できます。構成は不要です。
ロードバランサとアプリケーション間の HTTP/2
GKE Pod で実行しているアプリケーションが HTTP/2 リクエストを受信できる場合は、ロードバランサがリクエストをアプリケーションに転送するときに HTTP/2 を使用するようにロードバランサを構成できます。詳しくは、Ingress での HTTP/2 を使用した負荷分散をご覧ください。
ネットワーク エンドポイント グループ
クラスタがコンテナネイティブのロード バランシングをサポートしている場合は、ネットワーク エンドポイント グループ(NEG)を使用することをおすすめします。GKE クラスタ 1.17 以降と一定の条件下では、コンテナネイティブの負荷分散がデフォルトであり、明示的な cloud.google.com/neg: '{"ingress": true}' Service のアノテーションは必要ありません。
共有 VPC
Ingress リソースをデプロイする GKE クラスタがサービス プロジェクトにあり、GKE コントロール プレーンでホスト プロジェクトのファイアウォール リソースを管理する場合、共有 VPC を使用したクラスタのファイアウォール リソースの管理の説明のように、サービス プロジェクトの GKE サービス アカウントには、ホスト プロジェクトの適切な IAM 権限が付与されている必要があります。これにより、Ingress コントローラは、上り(内向き)トラフィックと Cloud de Confiance ヘルスチェックのトラフィックの両方を許可するファイアウォール ルールを作成できます。
以下に、Ingress リソースログに存在する可能性があるイベントの例を示します。このエラーは、権限が正しく構成されていないときに、Ingress コントローラがヘルスチェックの上り(内向き)トラフィックを許可するファイアウォール ルールを作成できない場合に発生します。 Cloud de Confiance
Firewall change required by security admin: `gcloud compute firewall-rules update <RULE_NAME> --description "GCE L7 firewall rule" --allow tcp:<PORT> --source-ranges 130.211.0.0/22,35.191.0.0/16 --target-tags <TARGET_TAG> --project <HOST_PROJECT>
ホスト プロジェクトからファイアウォール ルールを手動でプロビジョニングする場合は、Ingress リソースに networking.gke.io/suppress-firewall-xpn-error: "true" アノテーションを追加することで firewallXPNError イベントをミュートできます。
外部 Ingress アノテーションの概要
Ingress アノテーション
| アノテーション | 説明 |
|---|---|
| kubernetes.io/ingress.allow-http | クライアントと HTTP(S) ロードバランサ間の HTTP トラフィックを許可するかどうかを指定します。有効な値は true と false です。デフォルトは "true" です。HTTP の無効化をご覧ください。 |
| ingress.gcp.kubernetes.io/pre-shared-cert | このアノテーションを使用して、証明書リソースを GKE Ingress リソースに関連付けます。詳細については、外部アプリケーション ロードバランサでの複数の SSL 証明書の使用をご覧ください。 |
| kubernetes.io/ingress.global-static-ip-name | このアノテーションを使用して、以前に作成した静的外部 IP アドレスをロードバランサが使用するように指定します。HTTP(S) ロードバランサの静的 IP アドレスをご覧ください。 |
| networking.gke.io/v1beta1.FrontendConfig | このアノテーションを使用して、ロードバランサのクライアント向け構成をカスタマイズします。詳細については、Ingress の構成をご覧ください。 |
| networking.gke.io/suppress-firewall-xpn-error | Ingress ロードバランサの場合、権限不足のために Kubernetes でファイアウォール ルールを変更できないと、数分ごとに firewallXPNError イベントが作成されます。GLBC 1.4 以降では、Ingress リソースに networking.gke.io/suppress-firewall-xpn-error: "true" アノテーションを追加することで firewallXPNError イベントをミュートできます。このアノテーションを削除すると、ミュートを解除できます。有効な値は true と false です。デフォルト値は false です。 |
Ingress に関連する Service アノテーション
| アノテーション | 説明 |
|---|---|
| cloud.google.com/app-protocols | このアノテーションを使用して、ロードバランサとアプリケーション間の通信用のプロトコルを設定します。有効なプロトコルは HTTP、HTTPS、HTTP2 です。ロードバランサとアプリケーション間の HTTPS と Ingress による HTTP/2 を使用したロードバランサをご覧ください。 |
| cloud.google.com/backend-config | このアノテーションを使用して、サービスに関連付けられるバックエンド サービスを構成します。詳細については、Ingress の構成をご覧ください。 |
| cloud.google.com/neg | このアノテーションを使用して、ロードバランサがネットワーク エンドポイント グループを使用するように指定します。コンテナ ネイティブのロードバランサの使用をご覧ください。 |
次のステップ
GKE での外部アプリケーション ロードバランサ用 Ingress のコンセプトを確認する。
チュートリアルで Ingress で外部アプリケーション ロードバランサを設定する。
GKE における Service のコンセプトの概要を確認する。
基本的な外部 Ingress を実装する。