このページでは、Google Kubernetes Engine(GKE)で内部 HTTP(S) 負荷分散に Ingress を設定して使用する方法について説明します。内部 HTTP(S) 負荷分散に設定された Ingress は、GKE Ingress コントローラ経由で内部負荷分散の組み込みサポートを提供します。
内部 HTTP(S) 負荷分散で使用する Ingress でサポートされる機能の詳細については、Ingress の機能をご覧ください。内部 HTTP(S) 負荷分散で使用する Ingress の仕組みについては、内部 HTTP(S) 負荷分散で使用する Ingress をご覧ください。
始める前に
Kubernetes Ingress API を使用してロードバランサ リソースをデプロイする前に、指定されたリージョンにロードバランサのプロキシをデプロイできるように、ネットワーク環境を準備する必要があります。プロキシ専用サブネットをデプロイする手順については、ネットワークとサブネットの構成をご覧ください。
この手順は、内部 HTTP(S) 負荷分散に Ingress をデプロイする前に完了する必要があります。
内部 HTTP(S) 負荷分散用の Ingress でプロキシ専用サブネットを使用する必要がある理由について詳しくは、必要なネットワーク環境をご覧ください。
要件
内部 HTTP(S) 負荷分散用の Ingress には次の要件があります。
- クラスタで 1.16.5-gke.10 より後の GKE バージョンを使用している。
- クラスタを VPC ネイティブ(エイリアス IP)モードで実行している。詳細については、VPC ネイティブ クラスタをご覧ください。
- クラスタで HTTP 負荷分散アドオンが有効になっている。デフォルトでは、クラスタで HTTP 負荷分散が有効になっています。このアドオンを無効にしないでください。
- Service のバックエンドとしてネットワーク エンドポイント グループ(NEG)を使用している。
内部 HTTP(S) 負荷分散用に Ingress をデプロイする
次の演習では、内部 HTTP(S) 負荷分散用の Ingress をデプロイする方法を説明します。
クラスタの作成
このセクションでは、内部 HTTP(S) 負荷分散の Ingress で使用できるクラスタを作成します。このクラスタを作成するには、gcloud
コマンドライン ツールまたは Google Cloud Console を使用します。
gcloud
次のフィールドを使用してクラスタを作成します。
gcloud container clusters create CLUSTER_NAME \
--cluster-version=VERSION_NUMBER \
--enable-ip-alias \
--zone=ZONE \
--network=NETWORK
--
以下を置き換えます。
- CLUSTER_NAME: クラスタの名前を追加します。
- VERSION_NUMBER: 1.16.5-gke.10 より後のバージョンを追加します。
--release-channel
フラグを使用して、デフォルト バージョンが 1.16.5-gke.10 より後のリリース チャネルを選択することもできます。 --enable-ip-alias
により、エイリアス IP が有効になります。内部 HTTP(S) 負荷分散に Ingress を使用するクラスタは、VPC ネイティブ(エイリアス IP)モードで実行する必要があります。詳細については、VPC ネイティブ クラスタの作成をご覧ください。- ZONE: クラスタを作成するゾーンを追加します。ネットワークとサブネットの構成で内部 HTTP(S) ロードバランサに作成したプロキシ サブネットと同じリージョンのゾーンを選択する必要があります。
- NETWORK: クラスタを作成するネットワークの名前を追加します。このネットワークは、プロキシ サブネットと同じ VPC ネットワークにする必要があります。
Console
Cloud Console で Google Kubernetes Engine のメニューに移動します。
[クラスタを作成] ボタンをクリックします。
[クラスタの基本] セクションで、次の操作を行います。
- クラスタの名前を [名前] に入力します。
- [ロケーション タイプ] で、クラスタのゾーンを選択します。ネットワークとサブネットの構成で内部 HTTP(S) ロードバランサに作成したプロキシ サブネットと同じリージョンのゾーンを選択する必要があります。
- [マスターのバージョン] で、1.16.5-gke.10 より後の静的バージョンを選択します。
または
[マスターのバージョン] の [リリース チャンネル] で、1.16.5-gke.10 より後のデフォルト バージョンを指定します。
ナビゲーション パネルで [ネットワーキング] をクリックします。
- [ネットワーク] プルダウンで、クラスタを作成するネットワークを選択します。このネットワークは、プロキシ サブネットと同じ VPC ネットワークにする必要があります。
- [ネットワークの詳細オプション] で、[VPC ネイティブのトラフィック ルーティングを有効にする(エイリアス IP を使用)] と [HTTP 負荷分散を有効にする] が選択されていることを確認します。
[保存] をクリックします。
ウェブ アプリケーションのデプロイ
このセクションでは、Deployment を作成します。
Deployment を作成するには:
次の Deployment リソースをコピーして、
web-deployment.yaml
というファイル名で保存します。# web-deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: labels: app: hostname name: hostname-server spec: selector: matchLabels: app: hostname minReadySeconds: 60 replicas: 3 template: metadata: labels: app: hostname spec: containers: - image: k8s.gcr.io/serve_hostname:v1.4 name: hostname-server ports: - containerPort: 9376 protocol: TCP terminationGracePeriodSeconds: 90
この Deployment ファイルでは、HTTPS サーバーのポート 9376 でリッスンするコンテナ イメージを使用します。また、この Deployment はアプリケーションの Pod を管理します。各 Pod は、HTTPS サーバーに接続して 1 つのアプリケーション コンテナを実行します。このサーバーは、レスポンスとしてアプリケーション サーバーのホスト名を返します。Pod の名前が Pod のデフォルトのホスト名になります。また、このコンテナではグレースフルな終了処理を行います。
Deployment ファイルを作成したら、クラスタにリソースを適用します。
kubectl apply -f web-deployment.yaml
ネットワーク エンドポイント グループ(NEG)として Service をデプロイする
このセクションでは、Service リソースを作成します。Service がラベルを使用してバックエンド コンテナを選択し、Ingress コントローラがバックエンド エンドポイントとしてコンテナのプログラムを作成します。内部 HTTP(S) 負荷分散のための Ingress では、バックエンドとして NEG を使用する必要があります。この機能は、インスタンス グループをバックエンドに使用することをサポートしていません。NEG バックエンドが必要なため、Ingress を通じて公開される Service をデプロイするときには、次の NEG アノテーションが必要です。
annotations:
cloud.google.com/neg: '{"ingress": true}'
以下のすべての条件が満たされると、Service に自動的に cloud.google.com/neg: '{"ingress": true}'
アノテーションが付けられます。
- GKE クラスタ 1.17.6-gke.7 以降で Service を作成した。
- VPC ネイティブ クラスタを使用している。
- 共有 VPC を使用していない。
- GKE ネットワーク ポリシーを使用していない。
NEG を使用すると、Ingress コントローラがコンテナ ネイティブの負荷分散を実行できます。トラフィックは、ノード IP または kube-proxy ネットワーキングを移動するのではなく、Ingress プロキシから直接 Pod IP に負荷分散されます。また、Kubernetes の readiness / liveness チェックだけでなく、負荷分散の観点からも Pod の健全性を判断するため、Pod の readiness ゲートが実装されます。Pod の readiness ゲートを使用すると Pod の起動、Pod やノードの損失などのライフサイクル イベントでトラフィックが破棄されることを防げます。
NEG アノテーションを追加しないと、警告が Ingress オブジェクトで表示され、内部 HTTP(S) ロードバランサを構成できなくなります。また、NEG アノテーションが含まれていない場合は、Ingress で Kubernetes イベントが生成されます。次のメッセージは、イベント メッセージの例です。
Message
-------
error while evaluating the ingress spec: could not find port "8080" in service "default/no-neg-svc"
Ingress が Service を参照するまで NEG は作成されません。Ingress とその参照先の Service の両方が存在するまで NEG は Compute Engine に表示されません。NEG はゾーンリソースです。マルチゾーン クラスタの場合は、各ゾーンで Service ごとに 1 つ作成されます。
Service を作成するには:
次の Service リソースをコピーして、
web-service.yaml
というファイル名で保存します。# web-service.yaml apiVersion: v1 kind: Service metadata: name: hostname namespace: default annotations: cloud.google.com/neg: '{"ingress": true}' spec: ports: - name: host1 port: 80 protocol: TCP targetPort: 9376 selector: app: hostname type: NodePort
Service ファイルを作成したら、クラスタにリソースを適用します。
kubectl apply -f web-service.yaml
Ingress をデプロイする
このセクションでは、Ingress コントローラを介して Compute Engine 負荷分散のデプロイをトリガーする Ingress リソースを作成します。内部 HTTP(S) 負荷分散の Ingress には、次のアノテーションが必要です。
annotations:
kubernetes.io/ingress.class: "gce-internal"
Ingress を作成するには:
次の Ingress リソースをコピーして、
internal-ingress.yaml
というファイル名で保存します。# internal-ingress.yaml apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: ilb-demo-ingress namespace: default annotations: kubernetes.io/ingress.class: "gce-internal" spec: backend: serviceName: hostname servicePort: 80
Ingress ファイルを作成したら、クラスタにリソースを適用します。
kubectl apply -f internal-ingress.yaml
Ingress のデプロイ成功を検証する
このセクションでは、デプロイが成功したかどうかを検証します。
Ingress リソースが完全にプロビジョニングされるまでに数分かかることがあります。この間に、Ingress コントローラは転送ルール、バックエンド サービス、URL マップ、NEG などの項目を作成します。
前のセクションで作成した Ingress リソースのステータスを取得するには、次のコマンドを実行します。
kubectl get ingress ilb-demo-ingress
出力は次の例のようになります。
NAME HOSTS ADDRESS PORTS AGE
ilb-demo-ingress * 10.128.0.58 80 59s
ADDRESS
フィールドに値が入力されると、Ingress は準備完了になります。このフィールドの RFC 1918 アドレスは、VPC 内の内部 IP であることを意味します。
内部 HTTP(S) ロードバランサはリージョン ロードバランサであるため、仮想 IP(VIP)には同じリージョンの VPC 内のクライアントからのみアクセスできます。ロードバランサの VIP を取得したら、curl
などのツールを使用して、VPC 内から VIP に対して HTTP GET
呼び出しを発行できます。
HTTP GET
呼び出しを発行するには、次の手順を行います。
VPC 内から Ingress VIP にアクセスするには、クラスタと同じリージョンとネットワークに VM をデプロイします。
たとえば、Deployment、Service、Ingress を作成する上記の手順を実行して、デフォルト ネットワークと
us-central1-a
ゾーンにクラスタを作成した場合は、次のコマンドを使用します。gcloud compute instances create l7-ilb-client-us-central1-a \ --image-family=debian-9 \ --image-project=debian-cloud \ --network=default \ --subnet=default \ --zone=us-central1-a \ --tags=allow-ssh
インスタンスの作成の詳細については、VM インスタンスの作成と起動をご覧ください。
VM 内から内部 VIP にアクセスするには、
curl
を使用します。前の手順で作成した VM に SSH 接続します。
gcloud compute ssh l7-ilb-client-us-central1-a \ --zone=us-central1-a
curl
を使用して内部アプリケーション VIP にアクセスします。curl 10.128.0.58 hostname-server-6696cf5fc8-z4788
成功を示す HTTP レスポンスとバックエンド コンテナのホスト名が返された場合、完全な負荷分散パスが正常に機能しています。
Ingress リソースを削除する
Ingress と Service のリソースを削除すると、関連する Compute Engine のロードバランサ リソースも削除されます。リソースのリークを防ぐため、不要になった Ingress リソースを破棄します。 また、Compute Engine 負荷分散リソースが孤立する前に、Ingress リソースと Service リソースを削除する必要があります。
Ingress を削除するには、次の手順を行います。
Ingress を削除します。たとえば、このページで作成した Ingress を削除するには、次のコマンドを実行します。
kubectl delete ingress ilb-demo-ing
Ingress を削除すると、この Ingress リソースに関連付けられた転送ルール、バックエンド サービス、URL マップが削除されます。
Service を削除します。たとえば、このページで作成した Service を削除するには、次のコマンドを実行します。
kubectl delete service hostname
Service を削除すると、Service に関連する NEG が削除されます。
静的 IP アドレスの指定
内部 Ingress リソースでは、静的 IP アドレスとエフェメラル IP アドレスの両方がサポートされます。IP アドレスを指定しない場合、GKE ノードのサブネットから使用可能な IP アドレスが自動的に割り振られます。ただし、Ingress リソースは内部専用サブネットの IP アドレスをプロビジョニングしません。これは、このサブネットが、内部プロキシの使用に対してのみ利用されるからです。これらのエフェメラル IP アドレスは、内部 Ingress リソースのライフサイクルに対してのみ Ingress に割り振られます。ただし、Ingress を削除して同じマニフェスト ファイルから新しい Ingress を作成しても、同じ外部 IP アドレスが得られる保証はありません。
内部 Ingress リソースのライフサイクルとは独立した永続的な IP アドレスが必要な場合は、リージョン静的内部 IP アドレスを予約する必要があります。その後、Ingress リソースで kubernetes.io/ingress.regional-static-ip-name
アノテーションを使用して静的 IP アドレスを指定できます。
次の例は、このアノテーションを追加する方法を示しています。
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: my-ingress
annotations:
kubernetes.io/ingress.regional-static-ip-name: STATIC_IP_NAME
kubernetes.io/ingress.class: "gce-internal"
STATIC_IP_NAME は、次の条件を満たす静的 IP 名で置き換えます。
- Ingress をデプロイする前に静的 IP を作成します。ロードバランサは、静的 IP が存在するまでデプロイされません。また、存在しない IP アドレス リソースを参照しても、静的 IP は作成されません。
- Google Cloud IP アドレス リソースを、IP アドレスではなく、名前によって参照するようにします。
- この IP アドレスは、GKE クラスタと同じリージョン内のサブネットからのものである必要があります。リージョン(プロキシ専用サブネットを除く)内で使用可能なプライベート サブネットを使用できます。Ingress リソースごとに異なるサブネットからのアドレスを持つこともできます。
クライアントとロードバランサ間の HTTPS
内部負荷分散の Ingress は、クライアントへの TLS 証明書の配信をサポートします。TLS 証明書は、Kubernetes Secret または Google Cloud の事前共有リージョン SSL 証明書を通じて提供できます。Ingress リソースごとに複数の証明書を指定することもできます。
以下では、Google Cloud で証明書を作成し、Ingress を介して内部クライアントに配布する方法について説明します。
リージョン証明書を作成します。
gcloud compute ssl-certificates create CERT_NAME \ --certificate CERT_FILE_PATH \ --private-key KEY_FILE_PATH \ --region REGION
以下を置き換えます。
- CERT_NAME: 証明書の名前を追加します。
- CERT_FILE_PATH: ローカル証明書ファイルへのパスを追加してセルフ マネージド証明書を作成します。証明書は PEM 形式にする必要があります。
- KEY_FILE_PATH: ローカルの秘密鍵ファイルのパスを追加します。秘密鍵は PEM 形式にして、RSA または ECDSA 暗号化を使用する必要があります。
- REGION: 証明書のリージョンを追加します。
Ingress を作成します。次の
ingress-pre-shared-cert.yaml
という名前の YAML ファイルは、作成する必要のある Ingress リソースの一例です。# ingress-pre-shared-cert.yaml apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: name: ilb-demo-ing namespace: default annotations: ingress.gcp.kubernetes.io/pre-shared-cert: "CERT_NAME" kubernetes.io/ingress.class: "gce-internal" kubernetes.io/ingress.allow-http: "false" spec: rules: - host: DOMAIN http: paths: - backend: serviceName: SERVICE_NAME servicePort: 80
以下を置き換えます。
- DOMAIN: ドメインを追加します。
- CERT_NAME: 前のセクションで作成した証明書の名前を追加します。
- SERVICE_NAME: Service の名前を追加します。
Ingress を作成したら、クラスタにリソースを適用します。
kubectl apply -f ingress-pre-shared-cert.yaml
内部 Ingress アノテーションの概要
次の表は、内部 HTTP(S) 負荷分散用の Ingress に Ingress リソースと Service リソースを作成するときに追加できるアノテーションを示しています。
Ingress アノテーション
アノテーション | 説明 |
---|---|
kubernetes.io/ingress.class | 内部 Ingress に対しては "gce-internal" と指定されます。クラスが指定されていない場合、Ingress リソースはデフォルトで外部 Ingress として解釈されます。 |
kubernetes.io/ingress.allow-http | クライアントと HTTP(S) ロードバランサ間の HTTP トラフィックを許可するかどうかを指定します。有効な値は true と false です。
デフォルト値は true ですが、内部負荷分散に HTTPS を使用している場合は、このアノテーションを false に設定する必要があります。詳しくは、HTTP の無効化をご覧ください。 |
ingress.gcp.kubernetes.io/pre-shared-cert | 証明書と鍵を Google Cloud プロジェクトにアップロードできます。このアノテーションを使用して証明書と鍵を参照します。詳細については、HTTP(S) 負荷分散での複数の SSL 証明書の使用をご覧ください。 |
Ingress に関連する Service アノテーション
アノテーション | 説明 |
---|---|
cloud.google.com/backend-config | このアノテーションを使用して、servicePort に関連付けられるバックエンド サービスを構成します。詳細については、Ingress の機能をご覧ください。 |
cloud.google.com/neg | このアノテーションを使用して、ロードバランサがネットワーク エンドポイント グループを使用するように指定します。詳しくは、コンテナ ネイティブの負荷分散を使用するをご覧ください。 |
トラブルシューティング
Ingress の状態を把握して監視する場合、関連するリソースの調査を行います。よく発生する問題としては、負荷分散リソースが適切に作成されない、トラフィックがバックエンドに到達しない、バックエンドが正常な状態でない、などの問題があります。
一般的なトラブルシューティングの手順は次のとおりです。
- クライアント トラフィックがロードバランサと同じリージョンおよび VPC 内から送信されていることを確認します。
- Pod とバックエンドが正常な状態であることを確認します。
- VIP へのトラフィック パスを確認します。Compute Engine ヘルスチェックの場合は、そのパスがファイアウォール ルールでブロックされていないことを確認します。
- Ingress リソース イベントのエラーを確認します。
- Ingress リソースの説明を参照して、Compute Engine リソースとのマッピングを確認します。
- Compute Engine 負荷分散リソースが存在し、正しく構成され、エラーが報告されていないことを確認します。
Ingress イベントのフィルタリング
次のクエリを実行すると、クラスタ内のすべての Ingress イベントのエラーをフィルタリングできます。
kubectl get events --all-namespaces --field-selector involvedObject.kind=Ingress
オブジェクトやオブジェクト名でフィルタすることもできます。
kubectl get events --field-selector involvedObject.kind=Ingress,involvedObject.name=hostname-internal-ingress
次のエラーは、Ingress によって参照されている Service が存在しないことを示しています。
LAST SEEN TYPE REASON OBJECT MESSAGE
0s Warning Translate ingress/hostname-internal-ingress error while evaluating the ingress spec: could not find service "default/hostname-invalid"
Compute Engine ロードバランサ リソースの検査
次のコマンドを実行すると、Ingress リソースの完全な出力が表示されます。これにより、Ingress コントローラによって作成された Compute Engine リソースへのマッピングを確認できます。
kubectl get ing INGRESS_FILENAME -o yaml
INGRESS_FILENAME を Ingress リソースのファイル名に置き換えます。
出力は次の例のようになります。
apiVersion: v1
items:
- apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
ingress.kubernetes.io/backends: '{"k8s1-241a2b5c-default-hostname-80-29269aa5":"HEALTHY"}'
ingress.kubernetes.io/forwarding-rule: k8s-fw-default-ilb-demo-ingress--241a2b5c94b353ec
ingress.kubernetes.io/target-proxy: k8s-tp-default-ilb-demo-ingress--241a2b5c94b353ec
ingress.kubernetes.io/url-map: k8s-um-default-ilb-demo-ingress--241a2b5c94b353ec
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"networking.k8s.io/v1beta1","kind":"Ingress","metadata":{"annotations":{"kubernetes.io/ingress.class":"gce-internal"},"name":"ilb-demo-ingress","namespace":"default"},"spec":{"backend":{"serviceName":"hostname","servicePort":80}}}
kubernetes.io/ingress.class: gce-internal
creationTimestamp: "2019-10-15T02:16:18Z"
finalizers:
- networking.gke.io/ingress-finalizer
generation: 1
name: ilb-demo-ingress
namespace: default
resourceVersion: "1538072"
selfLink: /apis/networking.k8s.io/v1beta1/namespaces/default/ingresses/ilb-demo-ingress
uid: 0ef024fe-6aea-4ee0-85f6-c2578f554975
spec:
backend:
serviceName: hostname
servicePort: 80
status:
loadBalancer:
ingress:
- ip: 10.128.0.127
kind: List
metadata:
resourceVersion: ""
selfLink: ""
ingress.kubernetes.io/backends
アノテーションには、バックエンドとそのステータスの一覧が表示されています。バックエンドが HEALTHY
になっていることを確認します。
Ingress で作成された Compute Engine リソースの場合は、直接クエリを送信してステータスと構成を確認できます。これらのクエリを実行すると、トラブルシューティングでも役立ちます。
Compute Engine 転送ルールの一覧を取得するには:
gcloud compute forwarding-rules list
出力例:
NAME REGION IP_ADDRESS IP_PROTOCOL TARGET
k8s-fw-default-hostname-internal-ingress--42084f6a534c335b us-central1 10.128.15.225 TCP us-central1/targetHttpProxies/k8s-tp-default-hostname-internal-ingress--42084f6a534c335b
バックエンド サービスの状態を一覧表示するには、まずバックエンド サービスを一覧表示し、検査するバックエンド サービスの名前をコピーします。
gcloud compute backend-services list
出力例:
NAME BACKENDS PROTOCOL
k8s1-42084f6a-default-hostname-80-98cbc1c1 us-central1-a/networkEndpointGroups/k8s1-42084f6a-default-hostname-80-98cbc1c1 HTTP
これで、バックエンド サービス名を使用してヘルスチェックのクエリを実行できるようになりました。
gcloud compute backend-services get-health k8s1-42084f6a-default-hostname-80-98cbc1c1 \
--region us-central1
出力例:
backend: https://www.googleapis.com/compute/v1/projects/user1-243723/zones/us-central1-a/networkEndpointGroups/k8s1-42084f6a-default-hostname-80-98cbc1c1
status:
healthStatus:
- healthState: HEALTHY
次のステップ
GKE での HTTP(S) ロードバランサの Ingress のコンセプトを確認する。
GKE における Service のコンセプトの概要を確認する。
GKE で Compute Engine の内部 TCP / UDP ロードバランサを作成する方法について学習します。