NGINX(エンジンエックス)|日本公式サイト

NGINXはF5ファミリーの一員となりました。新体制の詳細はこちらを御覧ください。

Kubernetes Networking 101

NodePort、LoadBalancer、Ingress Controller…

Kubernetesの本番利用について顧客やコミュニティと話すとき、最もよくある質問の1つが「Ingress Controllerは必要なのか?」です。この質問に対する答えは、単純な「はい」か「いいえ」で済むものではなく、Podへのトラフィックや接続の様々な方法について学ぶことが必要です。このブログでは、Kubernetesネットワークの基本を説明し、Ingress Controllerが必要かどうか、そしていつ必要かを判断できるようにします。

Kubernetesは、外部トラフィックをPodにルーティングするためのいくつかの可能なアプローチとレイヤーをサポートしていますが、それらは全て同じように作成されているわけではありません。デフォルトのモデルは kube-proxy ですが、これは実際にはプロキシではなく、トラフィックのロードバランス、API の制御、サービスの動作の監視を行うようには設計されていません。

幸い、外部トラフィックを管理する方法は他にもありますが、その前にKubernetesのコンポーネントについて簡単におさらいしておきましょう。

  • Kubernetesのデプロイは、物理的または仮想的なマシンであるノードで構成されています。
  • ノードは互いに結合してクラスターを形成します。
  • 各クラスターは、Kubernetesのネットワークおよびインフラストラクチャー・レベルにおける最小公倍数であるPodを管理します。1つまたは複数のポッドを組み合わせて、1つのサービスを構成します。
  • 各Podの内部には、1つまたは複数のコンテナ(アプリケーションのサイズに依存)が存在します。

Kubernetesはサービスを構成するPodを監視し、アプリの要件に合わせて必要に応じてスケーリングします。しかし、Podへのトラフィックはどのように確保するのでしょうか。そこで登場するのが、ServiceとIngress Controllerという2種類のKubernetesオブジェクトです。

KubernetesのServiceとは?

Kubernetesのドキュメントによると、Serviceとは「一連のPod上で動作するアプリを公開するための抽象的な方法」です。Serviceは、特定のノード上の位置が関係しないように、コンテナのクラスタまたはネットワーク内のPodを接続します。つまり、Podの位置が変わっても、あるいはPodが破壊されて再起動しても、外部トラフィックを特定のPodにルーティングすることができます。このように、Serviceは非常に基本的なリバースプロキシと同じように機能します。

Kubernetesへの外部トラフィックのルーティングに関連するサービスやサービスオブジェクトのタイプは複数存在します。これらは互いに混同されがちですが、実際にはそれぞれが非常に異なることを行うので、その機能、用途、および欠点について調べておく価値があります。

ClusterIP

ClusterIPは、クラスタ内の他のサービスがアクセスできるKubernetes内のサービスを提供するデフォルトのサービスです。クラスタの外からはアクセスできません。ClusterIP Serviceを公開する唯一の方法は、kube-proxyのようなものを使用することですが、これが役立つシナリオはほとんどありません。限られた例としては、ラップトップ上のサービスにアクセスする、サービスをデバッグする、モニタリングやメトリクスを見る、などがあります。

NodePort

NodePortサービスは、クラスタの各ノードで特定のポートを開き、そのポートでノードに送信された全てのトラフィックを対応するアプリに転送します。これはアプリにトラフィックを送るための非常に基本的な方法で、実際のトラフィック管理のユースケースにおいては多くの制限があります。NodePortごとに1つのサービスしか持つことができず、30000から32767の範囲のポートしか使うことができない。2768ポートというのは多く聞こえるかもしれませんが、Kubernetesを大規模に運用している組織ではすぐに使い切ってしまうでしょう。また、NodePortはレイヤー4のルーティングルールとLinuxのiptablesユーティリティを使用しており、レイヤー7のルーティングが制限されています。

ルーティングの制限に加え、NodePortを使用する際の大きな欠点が3つあります。

  • ダウンストリームクライアントは、ノードに接続するためにノードの IP アドレスを知っている必要があり、ノードの IP アドレスや仮想マシンホストが変更された場合に問題になります。

  • NodePortは、複数のIPアドレスにトラフィックをプロキシすることはできません。

  • 図に示すように、NodePortはKubernetesクラスタ内のロードバランシングを提供しないため、トラフィックはサービス間でランダムに分散されます。その結果、サービスの過負荷やポートの枯渇が発生する可能性があります。

LoadBalancer

ロードバランサーサービスは、外部からのトラフィックを受け付けますが、そのトラフィックのインターフェースとして外部のロードバランサーが必要です。これは、外部ロードバランサーが適切に調整され、実行中のポッドにマッピングするように再構成されていれば、レイヤー7ルーティング(ポッドのIPアドレスへのルーティング)をサポートします。ロードバランサーは、サービスを外部に公開する最も一般的な方法の1つです。クラウドプラットフォームで使用されることが最も多く、小規模で静的なデプロイメントに適した選択肢です。

マネージドKubernetesサービスを使用している場合、クラウドプロバイダによって選択されたロードバランサーが自動的に取得されます。例えば、Google Cloud PlatformではLoadBalancerサービスタイプを使用してNetwork Load Balancerをスピンアップでき、AWSではApplication Load Balancer (ALB)がデフォルトになっています。公開する各サービスは、全てのトラフィックを転送する独自のパブリックIPアドレスを取得しますが、フィルタリングやルーティングは一切行われないため、ほぼ全てのタイプのトラフィック(HTTP、TCP/UDP、WebSocketなど)を送信できます。

クラウド プロバイダのツールを使用したくない場合、たとえば、より高い機能やプラットフォームに依存しないツールが必要な場合、F5 BIG-IP(外部ロード バランサーとして)および F5 Container Ingress Services(ロード バランサーの容量で動作するオペレータとして)などのツールに置き換えるという方法もあります。このパターンの詳細については、当社のブログの「Deploying BIG-IP and NGINX Ingress Controller in the Same Architecture」を参照してください。

LoadBalancer を使用してアプリを公開することは、アプリPodが変化する需要レベルに合わせて拡張する必要がある動的な環境では困難になります。各サービスは独自の IP アドレスを取得するため、人気のあるアプリでは、管理する IP アドレスが数百、数千になることもあります。多くの場合、外部ロードバランサーは、次の図に示すように、NodePortを介して各サービスに接続します。これによってトラフィックがノード間で均等に分散されることが保証されますが、サービスに対するロードバランシングはまだ不可能で、サービスの過負荷やポートの枯渇が発生します。

Kubernetes Ingress Controllerとは?

Kubernetesのドキュメントによると、「Controllerは、クラスタの状態を監視し、必要に応じて変更を加える制御ループである」とあります。各Controllerは、現在のクラスタの状態を望ましい状態に近づけようとします。Controllerは、リソースの適切な割り当て、永続的なストレージの指定、cronジョブの管理など、多くのタスクのためにKubernetesの状態を管理するために使用されます。

ルーティングの文脈では、NodePortとLoadBalancerの制限を克服する方法として、Ingressコントローラがあります。

Ingressコントローラは、特定のサービスにラベル付けされたPodとの外部インタラクションを設定し、管理するために使用される。Ingress Controllerは、動的なレイヤー7ルーティングを優先事項として扱うように設計されています。つまり、Ingress Controllerは、より少ない労力で、より詳細な制御と管理を提供します。Ingress Controllerは、外部からトラフィックを制御するだけでなく、サービスレベルのパフォーマンス指標を提供し、セキュリティポリシーの一部として簡単に使用することができます。Ingress Controllerは、TLS終端、マルチドメインやネームスペースの処理、そしてもちろんトラフィックのロードバランシングなど、従来の外部ロードバランサーの多くの機能を備えています。Ingress Controllerはサービスレベルではなく、リクエスト単位でトラフィックをロードバランスすることができ、レイヤー7のトラフィックをより有用に見ることができ、SLAを実施するのに非常に優れた方法である。

さらに、もう一つの利点があります。Ingress Controllerは、特定のポッドから特定の外部サービスへのみ送信トラフィックを許可するegressルールを適用したり、トラフィックがmTLSを使用して相互に暗号化されていることを確認したりすることも可能です。医療、金融、通信、政府機関などの業界で規制されたサービスを提供するには、mTLSを要求することが重要です。また、エンドツーエンド暗号化(E2EE)戦略の重要なコンポーネントでもあります。また、同じツールから送信トラフィックを制御することで、サービスに対するビジネスロジックの適用を簡素化できます。Ingressとegressの両方が同じコントロールプレーンで管理されている場合、適切なリソースルールを設定するのがはるかに容易になります。

次の図は、Ingressコントローラーが、クライアントの複雑さを軽減する様子を示しています。クライアントは、SerivceのIPアドレスやポートを知る必要がなくなります。サービス間のトラフィックの負荷分散は保証されています。Ingress Controllerの中には、複数のロードバランシングアルゴリズムをサポートし、柔軟性と制御性を高めたものもあります。

ロードバランサーとIngress Controllerを導入する

BIG-IP と NGINX Ingress Controller を同じアーキテクチャで展開するで説明しているように、多くの組織では、Ingress Controller(ほとんどの場合、複数の Ingress Controllerインスタンス)を備えた外部ロードバランサーを展開することでメリットを得られるユースケースがあります。これは、組織がKubernetesをスケールする必要がある場合や、高いコンプライアンス環境で運用する場合に特によくあることです。これらのツールは通常、異なるチームによって管理され、異なる目的のために使用されます。

  • ロードバランサー(負荷分散ADC)

    • 所有者:NetOps(またはSecOps)チーム
    • 使用例:Kubernetesの外側で、クラスタ外のユーザーに配信されるサービスやアプリのための唯一の外部公開の部分。セキュリティを促進し、より高度なネットワーク管理を実現するために設計された、より汎用的なアプライアンスとして使用されます。
  • Ingress controller:

    • 所有者:プラットフォーム管理またはDevOpsチーム
    • 使用例:Kubernetes内部で、HTTP2、HTTP/HTTPS、SSL/TLS終端、TCP/UDP、WebSocket、gRPC、APIゲートウェイ機能、セキュリティとIDの一元化などの細かいロードバランシングに使用します。

この図では、ロードバランサーが複数のクラスタへのトラフィックの分散を処理し、クラスタにはIngress Controllerがあり、Serviceへの均等な分散を保証しています。

次のステップ

NGINX のエキスパートが Kubernetes ネットワーキングの入門書を提供し、Ingress Controllerについて深く掘り下げ、Ingress Controllerの状況について議論しています。

Ingress Controllerの使い方や、要件に最適なControllerの選び方については、ブログのA Guide to Choosing an Ingress Controller, Part 1: Identify Your Requirementsをご覧ください。

また、Ingress Controllerの詳細については、こちらのページKubernetes Swiss Army Knifeをご覧ください。

Cover image
Taking Kubernetes from Test to Production

A Practical Guide to Selecting and Deploying Kubernetes Traffic Management Tools

サンプルNGINX Plus 無料トライアル サンプルダウンロード資料 サンプル無料ウェビナー