このページでは、Kubernetes Ingress オブジェクトを作成して外部アプリケーション ロードバランサを構成する方法について説明します。
このページをお読みになる前に、GKE ネットワーキングのコンセプトを理解しておく必要があります。
始める前に
作業を始める前に、次のことを確認してください。
- Google Kubernetes Engine API を有効にします。 Google Kubernetes Engine API の有効化
- このタスクに Google Cloud CLI を使用する場合は、gcloud CLI をインストールして初期化します。すでに gcloud CLI をインストールしている場合は、
gcloud components update
を実行して最新のバージョンを取得します。
HttpLoadBalancing
アドオンを有効にする
クラスタで HttpLoadBalancing
アドオンが有効になっている必要があります。このアドオンはデフォルトで有効になっています。Autopilot クラスタでは、このアドオンを無効にできません。
HttpLoadBalancing
アドオンを有効にするには、Google Cloud コンソールまたは Google Cloud CLI を使用します。
コンソール
Google Cloud コンソールで 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 に転送するように外部アプリケーション ロードバランサを構成します。
このタスクを Google Cloud コンソールで直接行う際の順を追ったガイダンスについては、「ガイドを表示」をクリックしてください。
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
ごとに Google Cloud バックエンド サービスを作成します。クライアントが URL パス
/
を使用してロードバランサにリクエストを送信すると、GKE はポート 60000 でリクエストをhello-world-1
Service に転送します。クライアントが URL パス/v2
を使用してロードバランサにリクエストを送信すると、GKE はポート 80 でリクエストをhello-world-2
Service に転送します。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 コントローラでは、上り(内向き)トラフィックと Google Cloud ヘルスチェックのトラフィックの両方を許可するファイアウォール ルールを作成できます。
以下に、Ingress リソースログに存在する可能性があるイベントの例を示します。このエラーは、権限が正しく構成されていないときに、Ingress コントローラが Google Cloud ヘルスチェックの上り(内向き)トラフィックを許可するファイアウォール ルールを作成できない場合に発生します。
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 | このアノテーションを使用して、Service に関連付けられるバックエンド サービスを構成します。詳細については、Ingress の構成をご覧ください。 |
cloud.google.com/neg | このアノテーションを使用して、ロードバランサがネットワーク エンドポイント グループを使用するように指定します。コンテナ ネイティブのロードバランサの使用をご覧ください。 |
次のステップ
- GKE での外部アプリケーション ロードバランサ用 Ingress のコンセプトを確認する。
- チュートリアルで Ingress で外部アプリケーション ロードバランサを設定する。
GKE における Service のコンセプトの概要を確認する。
基本的な外部 Ingress を実装する。