GKE

GKE のベスト プラクティス: Ingress と Service を使用した GKE アプリケーションの公開

#containers

※この投稿は米国時間 2020 年 7 月 17 日に、Google Cloud blog に投稿されたものの抄訳です。

Google Kubernetes Engine(GKE)で実行するエンタープライズ アプリケーションの設計において重要なことの一つは、アプリケーションがクライアントからどのように使用されるかを検討することです。たとえば、アプリケーションをクラスタ外に公開して、外部クライアントが他の内部クライアントと同じくらい簡単に使用できるようにする場合もあれば、世界中のパブリック クライアントからのアプリケーションへのトラフィックをルーティングする場合もあります。 

どのようにすべきかは、さまざまな要因に左右されます。クライアントはインターネットからアクセスするか、それとも内部ネットワークからか。アプリケーションが使用するネットワーク プロトコルは何か。アプリケーションは単一のリージョンやクラスタでホストされているか、それともグローバルにデプロイされているか。アプリケーションの公開に使用するソリューションを決定するには、いくつかの主要な領域でのアプリケーション要件を考慮する必要があります。これらの要件を個別に評価するのではなく、総合的に判断して、アプリケーションを公開するのに最も適したネットワーキング ソリューションを決定します。 

ここでは、GKE でアプリケーションを公開する際に考慮すべきさまざまな要因を順に見ていき、それらがアプリケーションの公開にどのように影響するかを説明し、それぞれの要件がどのネットワーキング ソリューションにつながるかに焦点を当てます。ここでは、Deployment、Service、Ingress リソースといった Kubernetes の概念を理解していることを前提として、内部、外部、マルチクラスタなど、さまざまな公開方法を区別して解説します。

アプリケーションの公開を理解する

アプリケーションを外部クライアントに公開するには、次の 3 つの主要な要素が必要となります。これらが組み合わさることで、トラフィックをアプリケーションにルーティングできるようになります。 

  • フロントエンド: ロードバランサのフロントエンドは、クライアントがアクセスしてトラフィックをロードバランサに送信できるスコープを定義します。トラフィックをリッスンするネットワークの場所であり、そうした場所としては、ネットワーク、ネットワーク内の特定のリージョンまたはサブネット、ネットワーク内の 1 つ以上の IP、ポート、特定のプロトコル、安全な接続を確立するために提示される TLS 証明書などが挙げられます。
  • ルーティングと負荷分散: ルーティングと負荷分散は、トラフィックの処理方法とルーティング方法を定義します。プロトコル、HTTP ヘッダー、HTTP パスなどのパラメータに基づいて、トラフィックをサービスにルーティングできます。使用するロードバランサによっては、複数のゾーンやリージョンにトラフィックを分散して、ユーザーのためにレイテンシの短縮や復元力の向上を図る場合もあります。
  • バックエンド: バックエンドは、エンドポイントのタイプ、アプリケーション プラットフォーム、バックエンド サービス ディスカバリの統合によって定義されます。GKE などの特定のアプリケーション環境には、サービス ディスカバリの統合が利用されており、これによってロードバランサのバックエンドは、GKE エンドポイントの増減に合わせて動的に更新されます。

次の図は、外部トラフィックと内部トラフィックという 2 つの異なるタイプのトラフィック フローを使用してこれらの概念を示しています。外部 HTTP(S) ロードバランサは、世界各地にある何百もの Google の接続拠点を通過する公共のインターネット上のトラフィックをリッスンします。このグローバルなフロントエンドにより、トラフィックを Google データセンターでバックエンドに負荷分散する前に、クライアントに近いエッジでトラフィックを終端できます。ここに示す内部 HTTP(S) ロードバランサは、VPC ネットワークのスコープ内でリッスンし、内部でプライベート通信を行えるようにします。こうしたロードバランサの特性を、アプリケーションのさまざまなユースケースに合わせて活用できます。

1 vpc network.jpg

Ingress コントローラと Service コントローラによる GKE の負荷分散

GKE クラスタの外部にアプリケーションを公開するために、GKE には組み込みの GKE Ingress コントローラ と GKE Service コントローラが用意されており、これらが GKE ユーザーに代わって Google Cloud ロードバランサ(GCLB)をデプロイします。これらは仮想マシンで使用されるロードバランサと同じですが、ライフサイクルが GKE によって完全に自動化、制御される点が異なります。GKE のネットワーク コントローラは、Ingress API および Service API の標準に準拠した独自の高レベルなインターフェースを介して、Pod IP へのコンテナ ネイティブの負荷分散を行います。 

次の図は、GKE のネットワーク コントローラがロードバランサの作成を自動化する方法を示しています。アプリ管理者あるいはインフラストラクチャ管理者が、GKE クラスタに対して宣言型マニフェストをデプロイします。Ingress コントローラは GKE ネットワーク リソース(Ingress や MultiClusterIngress オブジェクトなど)を監視し、マニフェストに基づいて Cloud ロードバランサ(および IP アドレス指定やファイアウォール ルールなど)をデプロイします。コントローラは引き続きこれらのリソースを管理し、環境やトラフィックの変化に基づいてロードバランサのバックエンドを更新します。そのため、GKE のロード バランシングは開発者向けのシンプルなインターフェースを備えた、動的で持続可能なロードバランサになります。
2 GKE load balancing.jpg

アプリケーションの公開に影響する要因

GKE でアプリケーションを公開する方法の選択に影響を与える要因は数多くあります。ディシジョン ツリーの根元にいくつかのコア要因があり、これを使用してネットワーキング ソリューション セットを絞り込むことができます。この要因とは、クライアント ネットワーク、プロトコル、アプリケーションのリージョンです。 

クライアント ネットワークは、アプリケーション クライアントがアプリケーションにアクセスするネットワークです。これは、ロードバランサのフロントエンドがリッスンする場所に影響を及ぼします。たとえば、クライアントがアプリケーションと同じ GKE クラスタ内にあるとします。この場合、クライアントはクラスタ ネットワーク内からアプリケーションにアクセスし、Kubernetes ネイティブの ClusterIP 負荷分散を使用できます。クライアントが内部ネットワーク クライアントの場合は、Google Cloud VPC 内から、または Google Cloud Interconnect を介してオンプレミス ネットワークからアプリケーションにアクセスします。また、クライアントが外部ネットワーク クライアントの場合は、公共のインターネットを介してアプリケーションにアクセスします。ネットワークのタイプごとに、異なる負荷分散トポロジが必要です。

プロトコルとは、アプリケーションがそのクライアントと通信する言語です。音声、ゲーム、低レイテンシのアプリケーションは通常、TCP または UDP 上で直接通信するため、L4 できめ細かく制御できるロードバランサが必要です。その他のアプリケーションは HTTP、HTTPS、gRPC、HTTP2 で通信しますが、これらのプロトコルに基づいて負荷を分散するには、ロードバランサがそのプロトコルを理解できる必要があります。プロトコルの要件では、どの種類のアプリケーションが最適であるかさらに定義しています。 

アプリケーションのリージョンとは、アプリケーションが複数の GCP リージョンや GKE クラスタ間で分散される度合いを示します。アプリケーションの単一のインスタンスをホストするのと、2 つの独立した GKE クラスタ間でアクティブ / パッシブなアプリケーションをホストするのとでは、要件が異なります。5 つの GKE クラスタ間で地理的に分散したアプリケーションをホストして、エンドユーザーのより近くにワークロードを配置してレイテンシを短縮するには、さらにロードバランサがマルチクラスタやマルチリージョンに対応している必要があります。 

ネットワーク設計に影響を与える要因は、以下で対象としているもの以外にもある場合があります。たとえば、レイテンシ要件、送信元 IP アドレスの維持、高帯域幅などが挙げられます。このリストは完全なものではありませんが、これを活用して、ソリューションの選択肢を絞り込み、要件間のトレードオフについて理解を深めるのにお役立てください。

Ingress および Services を使用したアプリケーションの公開

GKE のネイティブの Ingress コントローラと Service コントローラのスイートを使用すると、デフォルトでアプリケーションをシームレスかつ安全に本番環境に公開できます。これらのネットワーク コントローラは GCLB と密接に統合されているため、Kubernetes ネイティブのインターフェースで、コンテナ IP にネイティブに負荷分散する GCLB をデプロイできます。次の表では、GKE の Ingress と Service のすべてのタイプを分類して示し、それぞれの主な特長について詳述します。GKE と Anthos Ingress のすべての機能の詳細な比較については、Ingress 機能をご覧ください。
3 GKE and Anthos Ingress.jpg

さまざまなネイティブのオプションがあり、プロトコル、ネットワーク アクセス、リージョンの観点からそれぞれ異なる機能を備えています。次のセクションでは、これらのネットワーキング ソリューションを上記の要因別に分類します。 

クライアント ネットワーク

GKE のロードバランサは、内部ロードバランサと外部ロードバランサに大別できます。内部とは VPC ネットワークを指し、インターネットから直接アクセスできない内部プライベート ネットワークです。外部とは、公共のインターネットを指します。ClusterIP Service は単一の GKE クラスタに対して内部となるため、VPC ネットワークよりもさらに小さなネットワークが対象となります。

4 Client network.jpg

*パブリック GKE クラスタは各 GKE ノードにパブリック IP とプライベート IP を提供するため、NodePort Service に内部と外部の両方からアクセスできます。 

プロトコル

ロードバランサは多くの場合、ポートやプロトコルなどのネットワーク情報に基づいてトラフィックをルーティングするレイヤ 4(L4)と、クライアント セッションなどのアプリケーション情報を認識するレイヤ 7(L7)に分類されます。GKE ロードバランサも、L4 と L7 に分類でき、下の表に示すように特定のプロトコルをサポートします。

5 Protocol.jpg

アプリケーションのリージョン

GKE 負荷分散ソリューションのリージョンは、次の 2 つの領域に分類できます。 

  • バックエンドのスコープ(またはクラスタのスコープ)は、ロードバランサが複数の GKE クラスタにわたってバックエンドにトラフィックを送信できるかどうかを示します。Ingress for Anthos(またはマルチクラスタ Ingress)は、異なるクラスタや異なる Google Cloud リージョンから Pod にトラフィックを転送する単一の VIP を公開する機能を備えています。
  • フロントエンドのスコープは、ロードバランサ IP が単一のリージョン内でリッスンするか複数のリージョンにわたってリッスンするかを示します。すべての外部ロードバランサは、本質的にマルチリージョンであるインターネット上でリッスンしますが、一部の内部ロードバランサは単一のリージョン内のみでリッスンします。

下の表は、この 2 つの区分で GKE の負荷分散ソリューションを分類したものです。

6 Application regionality.jpg

これらはアプリケーション ネットワーキングのすべての側面を網羅しているわけではありませんが、上記の各要因を検討することで、さまざまな側面を考慮したうえでアプリケーションに最適なソリューションを決定できます。ほとんどの GKE 環境では、数多くのさまざまなタイプのアプリケーションをホストしており、それぞれに固有の要件があります。そのため、特定のクラスタで複数のソリューションを使用する可能性もあります。それらの機能の詳細については、次のリソースをご覧ください。 

GKE アプリケーション公開用のその他のソリューション

Kubernetes のエコシステムは巨大で、アプリケーションの公開に使用できるソリューションは上記以外にもあります。ネイティブの GKE ロードバランサの代替または補完として、以下のソリューションを実行できる場合もあります。 

クラスタ内 Ingress

クラスタ内 Ingress はソフトウェアによる Ingress コントローラを指し、Ingress プロキシを Kubernetes クラスタ自体の内部でホストします。これは、負荷分散インフラストラクチャを Kubernetes クラスタと分離してホスト、管理する Cloud Ingress コントローラとは区別されます。これらのサードパーティ ソリューションは通常、クラスタ オペレータが自分でデプロイし、自分で管理します。istio-ingressgatewaynginx-ingress の 2 つは、よく使用される、オープンソースのクラスタ内 Ingress コントローラの例です。クラスタ内 Ingress コントローラは通常、Kubernetes Ingress 仕様に準拠しており、さまざまな機能と高い操作性を備えています。オープンソースのソリューションには、より厳密な管理とより高レベルの技術的専門知識が求められる可能性がありますが、アプリケーションに必要な特定の機能を提供するものであれば、ニーズに適している場合があります。また、オープンソース コミュニティが中心となって構築された、高度な機能とエンタープライズ サポートを提供する巨大なエコシステム、Enterprise Ingress ソリューションもあります。 

スタンドアロン NEG

GKE の Ingress コントローラと Service コントローラによる Google Cloud Load Balancing のデプロイは、自動化された宣言型の Kubernetes ネイティブな方法です。また、ロードバランサを GKE バックエンドに手動でデプロイするのが有効なユースケースもあります。たとえば、ロードバランサを直接、より詳細に制御する場合や、コンテナと VM バックエンド間で負荷分散を行う場合などが挙げられます。スタンドアロン NEG は、ネットワーク エンドポイント グループ(NEG)の Pod バックエンド IP を動的に更新しますが、ロードバランサのフロントエンドを Google Cloud API を介して手動でデプロイできるようにすることで、この機能を提供します。これにより、GKE クラスタによって制御される動的バックエンドを維持しながら、ロードバランサを最大限に直接制御できます。 

サービス メッシュ

サービス メッシュは、集中コントロール プレーンを通じてクライアント側の負荷分散を行います。Istio プロジェクトで内部通信のために Kubernetes に L7 のサービス メッシュが導入された一方で、サービス メッシュのエコシステムはスコープや機能を急速に拡大してきました。Traffic DirectorAnthos Service Mesh では、GKE クラスタ間、リージョン間、またコンテナと VM 間で内部トラフィックを負荷分散する機能が強化されています。これにより、内部負荷分散(East-West トラフィック)と、アプリケーションの公開(North-South トラフィック)の線引きがあいまいになってきました。最新のサービス メッシュ コントロール プレーンでは柔軟性や達成度が向上しており、同じサービス メッシュ スコープ内にクライアントとサーバーの両方を維持できるようになってきています。上記の GKE Ingress や Service のソリューションでは通常、独自のサイドカー プロキシを持たないクライアントに中間プロキシのロードバランサをデプロイします。ただし、クライアントとサーバーが同じメッシュ内にある場合、従来のアプリケーションの公開は、中間プロキシの負荷分散ではなく、メッシュを介して処理できます。 

サービスにおける GKE

Google Cloud では、ユースケースに応じて、GKE アプリケーションをサービスとして公開するさまざまな方法をサポートしています。GKE がコンテナのあらゆるユースケースに対して、最も包括的なサポートを提供していることは間違いないでしょう。このブログ投稿がアプリケーション アクセスの設計方法の理解に役立った方は、他の方も理解できるよう、この投稿を自由に共有していただければ幸いです。 

- カスタマー エンジニア Harrison Sweeney、プロダクト マネージャー Mark Church