NodePort vs. LoadBalancer vs. Ingress: 最適なサービス公開方法の選択
Kubernetesサービスは、動的なPod群に安定したネットワーキングを提供する基盤となるオブジェクトです。サービスはクラスタ内の内部通信を処理しますが、これらのサービスを外部に公開する(ユーザーや外部アプリケーションがそれらと対話できるようにする)には、特定の構成が必要です。適切な公開方法を選択することは、セキュリティ、コスト、複雑さに影響を与えるため、非常に重要です。
この記事では、Kubernetesサービスを公開するための主要な3つの方法、NodePort、LoadBalancer、Ingressについて専門的な比較を提供します。それぞれの仕組み、適切なユースケース、および実際の要因を分析し、コンテナ化されたアプリケーションに最適なソリューションを選択するためのガイドとします。
1. サービス公開タイプ:NodePort
NodePortサービスタイプは、サービスを外部に公開する最もシンプルで基本的な方法です。サービスをNodePortとして定義すると、Kubernetesはクラスタ内のすべてのノードで特定の静的ポートを開きます。任意のノードのそのポートに向けられたトラフィックは、サービスに直接ルーティングされます。
NodePortの仕組み
- 指定された範囲内(デフォルト:30000-32767)でランダムなポートが自動的に選択されます。
- このポートはすべてのクラスタノードで開かれます。
- サービスはこのNodePortでリッスンし、適切なPodにトラフィックを転送します。
アプリケーションにアクセスするには、http://<Node_IP>:<NodePort>を使用します。
ユースケースと制限事項
| 特徴 | 説明 |
|---|---|
| ユースケース | 開発、テスト環境、または外部ロードバランシングが外部の非クラウドアプライアンスによって処理される場合。 |
| 複雑さ | 非常に低い。 |
| コスト | ゼロ(基盤となるVMコストを無視すれば)。 |
| 制限事項 | 外部ファイアウォールルールを手動で管理する必要がある。ノードIPはしばしば動的である。ポート範囲の制限 (30000-32767)。 |
NodePortの例
apiVersion: v1
kind: Service
metadata:
name: my-app-nodeport
spec:
type: NodePort
selector:
app: my-web-app
ports:
- port: 80
targetPort: 8080
# Optional: specify a NodePort, otherwise one is chosen automatically
# nodePort: 30001
⚠️ 警告: NodePortはサービスをすべてのノード経由で公開します。ノードが削除されたり、そのIPが変更されたりすると、外部アクセスが途絶えます。安定性を要求される本番環境では、一般的に推奨されません。
2. サービス公開タイプ:LoadBalancer
LoadBalancerサービスタイプは、クラウド環境(AWS EKS、GCP GKE、Azure AKS)でアプリケーションをパブリックインターネットに公開するための標準的な方法です。
LoadBalancerとしてサービスを定義すると、Kubernetesは専用のレイヤー4(L4)クラウドロードバランサー(例:AWS Classic ELB/NLB、Azure Load Balancer、GCP Network Load Balancer)を自動的にプロビジョニングします。これにより、サービスPodにトラフィックを直接ルーティングする、安定した高可用な外部IPアドレスが提供されます。
クラウドプロバイダーとの統合
LoadBalancerの主な差別化要因は、基盤となるクラウドインフラストラクチャとの深い統合です。クラウドプロバイダーがロードバランサーのライフサイクル、ヘルスチェック、ルーティングを処理します。
ユースケースとコストへの影響
| 特徴 | 説明 |
|---|---|
| ユースケース | 専用の安定したIPアドレスを必要とする、シンプルで公開向けのアプリケーション。非HTTP/Sプロトコル(TCP/UDP)に適しています。 |
| 複雑さ | 低い(設定面)。 |
| コスト | 高い。各LoadBalancerサービスは専用のクラウドインフラストラクチャをプロビジョニングし、しばしば時間単位の料金が発生します。 |
| 利点 | 即座に高可用性と自動ヘルスチェックを提供します。 |
LoadBalancerの例
apiVersion: v1
kind: Service
metadata:
name: my-app-loadbalancer
spec:
type: LoadBalancer
selector:
app: my-api-service
ports:
- protocol: TCP
port: 80
targetPort: 8080
作成されると、クラスタはクラウドプロバイダーによって管理される外部IPアドレス(サービスステータスで確認可能)を割り当てます。
3. Kubernetes Ingress: レイヤー7ルーティング
IngressはNodePortやLoadBalancerとは根本的に異なります。Ingressはサービスタイプではなく、外部アクセス、通常はHTTPおよびHTTPS(レイヤー7)のルールを定義するAPIオブジェクトです。
Ingressは中央のエントリーポイントとして機能し、ホスト名とURLパスに基づいた高度なルーティングを可能にします。このアプローチは、単一のIPアドレスの背後で複数のサービスを管理するために不可欠です。
Ingressコントローラーの役割
Ingressルールを機能させるには、まずIngressコントローラー(例:Nginx、Traefik、Istio)をデプロイする必要があります。コントローラーはIngressリソース定義を監視し、これらのルールに基づいて基盤となるリバースプロキシ/L7ロードバランサーを設定します。
重要なのは、Ingressコントローラー自体は通常、単一のLoadBalancerまたはNodePortサービスを使用して公開されることです。
Ingressの高度な機能
Ingressは、高度なトラフィック管理機能が必要な場合にその真価を発揮します。
- コスト最適化: アプリケーションサービスごとに1つのLoadBalancerを使用する代わりに、単一のクラウドLoadBalancer(コントローラーを公開するため)を使用します。
- バーチャルホスティング: ホスト名に基づいてトラフィックをルーティングします(
api.example.comはサービスAへ、www.example.comはサービスBへ)。 - パスベースルーティング: URLパスに基づいてトラフィックをルーティングします(
/v1/usersはサービスAへ、/v2/postsはサービスBへ)。 - SSL/TLSターミネーション: 証明書管理と復号化を集中して処理します。
Ingressリソースの例
この例では、api.example.com/v1へのトラフィックをmy-api-v1サービスにルーティングします。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
spec:
ingressClassName: nginx # Specify the controller in use
rules:
- host: api.example.com
http:
paths:
- path: /v1
pathType: Prefix
backend:
service:
name: my-api-v1
port:
number: 80
# ... other rules for different services/hosts
4. 比較と選択ガイド
最適な方法を選択するには、環境、複雑さ、機能セット、運用コストなどの要因を比較検討する必要があります。
機能比較表
| 特徴 | NodePort | LoadBalancer | Ingress |
|---|---|---|---|
| レイヤー | L4 (TCP/UDP) | L4 (TCP/UDP) | L7 (HTTP/S) |
| 安定性 (IP) | 不安定 (ノードIPを使用) | 安定 (専用クラウドIP) | 安定 (コントローラーのIPを使用) |
| コスト | 低い (運用オーバーヘッドが高い) | 高い (サービスごとのリソースコスト) | 中程度 (コントローラー用に1つのLoadBalancer) |
| ルーティングロジック | シンプルなポート転送 | シンプルなポート転送 | ホスト名、パス、SSL終端 |
| クラウド依存度 | なし | 高い | 高い (LoadBalancerによって公開されるコントローラーが必要) |
| 本番利用可否 | いいえ | はい (シンプルなアプリ) | はい (複雑なアプリ) |
決定基準:公開方法の選択
-
内部またはテスト専用の場合: クラスタ内での接続性をテストするだけの場合、または外部ネットワーキングを自分で管理している場合(例:ベアメタル環境)は、NodePortを使用します。
-
シンプルで専用のL4公開の場合: アプリケーションが非HTTPプロトコル(カスタムTCPプロトコルやUDPなど)を使用する場合、または即座に専用のL4アクセスを必要とする単一のパブリックアプリケーションのみがある場合は、LoadBalancerを使用します。
-
複雑なマルチサービスL7公開の場合: 複数のサービスを公開する必要がある場合、パスベースまたはホスト名ルーティングが必要な場合、集中型SSL終端が必要な場合、または単一の外部IPを共有することでクラウドコストを最小限に抑えたい場合は、Ingressを使用します。
ベストプラクティス: マネージドクラウド環境での本番デプロイメントには、一般的にIngressが推奨される選択肢です。増え続けるマイクロサービスを管理するために必要な洗練さ、セキュリティの集中化、コスト効率を提供します。
結論
Kubernetesは、基本的なL4 NodePortから、クラウド統合型のL4 LoadBalancer、さらにIngressの高度なL7ルーティング機能に至るまで、サービス公開のための幅広いソリューションを提供します。各方法の運用レイヤー、コストモデル、および必要なルーティングロジックを理解することで、エンジニアは本番ワークロードに対してスケーラブルで安全かつコスト効率の良いネットワークアーキテクチャを設計できます。