NodePort、LoadBalancer、Ingress controller……これは大変!
Kubernetesを本番環境で利用できるレベルにする方法について、お客さまやコミュニティの皆さまと話す際、特によく寄せられる質問の1つが「Ingressコントローラーは必要ですか?」というものです。この質問に単純に「はい」または「いいえ」で答えられることはほとんどありません。判断するには、Podにトラフィックを到達させるさまざまな方法を理解する必要があります。このブログでは、Ingressコントローラーが必要かどうか、また必要になるのはいつかを適切に判断できるよう、Kubernetesネットワーキングの基礎を解説します。
Kubernetesでは、外部トラフィックをPodにルーティングするために、複数のアプローチとレイヤーを利用できますが、すべてが同等というわけではありません。デフォルトのモデルはkube-proxyです。ただし、実際にはプロキシではなく、トラフィックの負荷分散、APIの制御、サービスの動作監視を目的として設計されたものでもありません。
幸い、外部トラフィックを管理する方法はほかにもあります。先に進む前に、Kubernetesのコンポーネントを簡単に確認しておきましょう。
- Kubernetesデプロイメントは、物理マシンまたは仮想マシンであるノードで構成されます。
- ノードが集まって、1つの「クラスター」を形成します。
- 各クラスターは、Kubernetesのネットワークおよびインフラストラクチャレベルにおける最小構成単位であるPodを管理します。1つ以上のPodで1つのサービスが構成されます。
- 各ポッドには、アプリケーションの規模に応じて1つ以上のコンテナが含まれます。
Kubernetesは、サービスを構成するポッドを監視し、アプリの要件に合わせて必要に応じてスケーリングします。では、トラフィックをポッドに到達させるにはどうすればよいのでしょうか。そこで登場するのが、サービスとIngressコントローラーという2種類のKubernetesオブジェクトです。
Kubernetes Serviceとは?
According to the Kubernetesドキュメントによると、サービスとは「一連のPod上で実行されているアプリを公開するための抽象的な方法」です。サービスは、クラスターまたはコンテナネットワーク内のPodを接続し、特定のノード上の配置場所に依存しないようにします。そのため、Podの配置場所が変わった場合や、Podが破棄されて再起動された場合でも、外部トラフィックを特定のPodにルーティングできます。このように、サービスは非常に基本的なリバースプロキシとよく似た役割を果たします。
外部トラフィックをKubernetes内にルーティングする際に関係するサービスやServiceオブジェクトには、複数のタイプがあります。これらは混同されがちですが、実際にはそれぞれ役割が大きく異なるため、機能、用途、欠点を確認しておくことが重要です。
ClusterIP
ClusterIPは、クラスター内の他のサービスからアクセスできるサービスをKubernetes内で提供する、デフォルトのサービスタイプです。クラスター外部からはアクセスできません。ClusterIPサービスを外部に公開するには、kube-proxyなどを使用する必要がありますが、それが適切なケースはほとんどありません。例としては、ノートPCからサービスにアクセスする場合、サービスをデバッグする場合、モニタリング情報やメトリクスを確認する場合などに限られます。
NodePort
NodePortサービスは、クラスター内のすべてのノードで特定のポートを開き、そのポート宛てにノードへ送信されたトラフィックを対応するアプリに転送します。これはアプリにトラフィックを送るための非常に基本的な方法であり、実際のトラフィック管理のユースケースでは多くの制約があります。各NodePortに設定できるサービスは1つだけで、使用できるポートも30000~32767に限られます。2768個のポートは多いように思えるかもしれませんが、Kubernetesを大規模に運用する組織ではすぐに使い切ってしまいます。また、NodePortはレイヤー4のルーティングルールとLinuxのiptablesユーティリティを使用するため、レイヤー7のルーティングが制限されます。
ルーティング上の制約に加え、NodePortの使用には大きな欠点がほかにも3つあります。
- ダウンストリームクライアントが各ノードに接続するには、そのノードのIPアドレスを把握している必要があります。そのため、ノードのIPアドレスや仮想マシンのホストが変更されると問題が生じます。
- NodePortでは、複数のIPアドレスにトラフィックをプロキシできません。
- 図に示すように、NodePortはKubernetesクラスター内で負荷分散を行わないため、トラフィックは各サービスにランダムに分散されます。その結果、サービスの過負荷やポートの枯渇が発生する可能性があります。

LoadBalancer
LoadBalancerサービスは外部トラフィックを受け入れますが、そのトラフィックのインターフェースとして外部ロードバランサーが必要です。外部ロードバランサーを適切に調整し、実行中のPodにマッピングするよう再構成することで、レイヤー7ルーティング(PodのIPアドレス宛て)に対応できます。LoadBalancerは、サービスを外部に公開する方法として特に広く利用されています。主にクラウドプラットフォームで使用され、小規模で構成が固定されたデプロイに適しています。
マネージド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(LoadBalancerの役割を担うオペレーターとして)などを使用できます。このパターンの詳細については、F5のブログ記事「同一アーキテクチャへのBIG-IPとNGINX Ingress Controllerの導入」をご覧ください。
需要の変動に応じてアプリのPodをスケーリングする必要がある動的な環境では、LoadBalancerを使用してアプリを公開することが難しくなります。各サービスに固有のIPアドレスが割り当てられるため、人気の高いアプリでは、管理対象のIPアドレスが数百、場合によっては数千に達することがあります。ほとんどの場合、次の図に示すように、外部ロードバランサーはNodePort経由でサービスに接続します。これにより、トラフィックがノード間で均等に分散されることは保証されますが、サービスへの負荷分散は依然としてできないため、サービスの過負荷やポート枯渇が引き続き発生します。

Kubernetes Ingress Controllerとは?
According to the Kubernetesドキュメントによると、「コントローラーは、クラスターの状態を監視し、必要に応じて変更を実行または要求する制御ループです。各コントローラーは、クラスターの現在の状態を望ましい状態に近づけようとします」。コントローラーは、リソースの適切な割り当て、永続ストレージの指定、cronジョブの管理など、Kubernetesのさまざまなタスクで状態を管理するために使用されます。
ルーティングにおいて、IngressコントローラーはNodePortとLoadBalancerの制約を克服する手段です。
Ingressコントローラーは、特定のサービスに関連付けられたラベルを持つPodとの外部通信を設定、管理するために使用します。Ingressコントローラーは、動的なレイヤー7ルーティングを主要機能として扱うように設計されています。そのため、運用負荷を抑えながら、よりきめ細かな制御と管理が可能です。Ingressコントローラーは、受信トラフィックの制御だけでなく、サービスレベルのパフォーマンス指標の提供や、セキュリティポリシーの一部としても容易に利用できます。Ingressコントローラーには、TLS終端、複数のドメインや名前空間の処理、トラフィックの負荷分散など、従来の外部ロードバランサーが備える多くの機能があります。また、サービス単位ではなくリクエスト単位でトラフィックを負荷分散できるため、レイヤー7トラフィックをより実用的な観点から把握し、SLAをより効果的に適用できます。
さらに、もう1つの利点があります。Ingressコントローラーは、特定のPodから指定された外部サービスへの送信トラフィックのみを許可するエグレスルールを適用したり、mTLSを使用してトラフィックを相互に暗号化したりすることもできます。mTLSの必須化は、医療、金融、通信、行政などの業界で規制対象サービスを提供するうえで極めて重要であり、エンドツーエンド暗号化(E2EE)戦略の主要な要素でもあります。同じツールで送信トラフィックを制御することで、サービスへのビジネスロジックの適用も簡素化できます。イングレスとエグレスを同じコントロールプレーンで連携させると、適切なリソースルールをはるかに容易に設定できます。
次の図は、Ingressコントローラーによってクライアント側の複雑さが軽減され、サービスのIPアドレスやポートを把握する必要がなくなる仕組みを示しています。サービス間のトラフィック分散が保証されます。一部のIngressコントローラーは複数の負荷分散アルゴリズムをサポートしており、柔軟性と制御性をさらに高めることができます。

Ingress Controllerを使用したロードバランサーのデプロイ
「同一アーキテクチャへのBIG-IPとNGINX Ingress Controllerの導入」で説明しているように、多くの組織では、外部ロードバランサーをIngress Controller(多くの場合は複数のIngress Controllerインスタンス)と併用することでメリットを得られるユースケースがあります。これは、Kubernetesのスケーリングが必要な場合や、高度なコンプライアンスが求められる環境で運用する場合に特によく見られます。通常、これらのツールは異なるチームが管理し、それぞれ異なる目的で使用します。
- ロードバランサー(またはADC):
- 担当:NetOpsチーム(場合によってはSecOpsチーム)
- ユースケース:Kubernetesの外部に配置し、クラスター外のユーザーに提供するサービスやアプリの唯一の公開エンドポイントとして使用します。また、セキュリティの強化と、より高度なネットワーク管理を支援する汎用アプライアンスとしても使用します。
- Ingressコントローラー:
- 担当:Platform OpsまたはDevOpsチーム
- ユースケース:Kubernetes内でのノースサウストラフィック(HTTP2、HTTP/HTTPS、SSL/TLS終端、TCP/UDP、WebSocket、gRPC)のきめ細かな負荷分散、APIゲートウェイ機能、セキュリティとアイデンティティの一元管理。
この図は、ロードバランサーが複数のクラスター間でトラフィックを分散し、各クラスターのIngressコントローラーがサービスへの均等な分散を確保する仕組みを示しています。

次のステップ
ここまで読んでもまだよく分からない場合は、Linux Foundationのウェビナー「Ingress Controllerが必要な理由と選び方」をご覧ください。NGINXのエキスパートがKubernetesネットワーキングの基礎を解説し、Ingress Controllerを詳しく掘り下げるとともに、その全体像について説明します。
Ingressコントローラーの活用方法と、要件に最適なものを選ぶ方法について詳しくは、F5のブログ記事「Ingressコントローラー選定ガイド 第1回:要件の特定」をご覧ください。
著者について

関連するブログ記事
チュートリアル:NGINXを使用してアプリケーション向けにOpenTelemetryを構成する
OpenTelemetryを使用してNGINXサーバーの状態と健全性をより明確に把握することで、問題のトラブルシューティングを行い、Webアプリケーションのパフォーマンスを向上できます。
AkitaのNGINX Plus認定モジュールでAPIエンドポイントの問題を特定・修正
Akita SoftwareのAPIオブザーバビリティ向け新しいNGINX Plus Certified Moduleを活用して、APIエンドポイントの問題をより迅速に特定し、修正できます。
JavaプロジェクトをスキャフォールディングしてKubernetesネイティブアプリを構築する方法
Red HatのシニアプリンシパルデベロッパーアドボケイトであるDaniel Oh氏が、Javaプロジェクトをゼロから構築するためのひな形を作成し、Kubernetesネイティブアプリケーションとしてビルドする方法を解説します。
F5 NGINXaaS for Azureのご紹介:Microsoft Azureでネイティブに利用できるSaaS型ロードバランシング
NGINXaaS for Azureは、NGINX PlusをAzureネイティブのSaaSとして利用できるサービスです。NGINXの設定を容易にリフト&シフトできるため、クラウド導入とモダンアプリの展開を加速できます。

SELinuxでNGINXおよびNGINX Plusを使用する
Red Hat Enterprise Linux(RHEL)および関連ディストリビューションでSecurity-Enhanced Linux(SELinux)を有効にすると、デフォルト設定によりNGINXとNGINX Plusの一部の操作が制限されます。この記事では、すべての機能を利用できるようにSELinuxの設定を変更する方法について説明します。
NGINX PlusによるAWS Auto Scalingグループの負荷分散
新しいnginx-asg-sync統合ソフトウェアにより、NGINX PlusはAWS Auto Scalingグループの負荷を直接分散できるため、クラウドでの負荷分散がさらに柔軟になります