適切なKubernetesサービスタイプの選択:ClusterIP vs NodePort vs LoadBalancer
Kubernetesサービスは、Podの論理的な集合と、それらにアクセスするためのポリシーを定義する不可欠な抽象化です。Kubernetesでアプリケーションをデプロイする際、正しいサービスタイプを選択することは、ネットワークアクセス性を決定する上で極めて重要です。サービスがクラスター内でのみ到達可能である必要があるのか、特定のポートを介して外部に公開される必要があるのか、それともクラウドプロバイダーのロードバランシングインフラストラクチャと直接統合される必要があるのかによって、選択は異なります。この設定を誤ると、アプリケーションにアクセスできなくなったり、不要なインフラストラクチャコストが発生したりする可能性があります。
このガイドでは、3つの基本的なKubernetesサービスタイプであるClusterIP、NodePort、LoadBalancerを包括的に比較します。それぞれのタイプのユースケース、実装メカニズム、および関連するトレードオフを理解することで、アプリケーションのネットワーク要件に完全に合致する情報に基づいた決定を下し、内部通信と外部アクセス性の両方を効果的に管理できるようになります。
Kubernetesサービスの理解
特定のタイプに踏み込む前に、Kubernetesサービスの役割を覚えておくことが重要です。Podは一時的なものであり、作成、破棄、または再スケジュールされるたびにIPアドレスが変更されます。サービスは、動的に変化するPodのセットに対して安定したエンドポイント(固定IPアドレスとDNS名)を提供し、クラスター内での信頼性の高い通信を可能にします。
サービスはServiceオブジェクトマニフェストを使用して定義され、通常、関連するPodを見つけるためのselectorと、そのサービスがどのように公開されるかを定義するためのtypeを指定します。
1. ClusterIP:内部通信
ClusterIPは、デフォルトで最も基本的なサービスタイプです。クラスター内の内部IPアドレスでサービスを公開します。このサービスは、クラスター内からのみ到達可能です。
ClusterIPのユースケース
- バックエンドサービス: 同じKubernetesクラスター内で実行されている他のサービスやフロントエンドアプリケーションとのみ通信する必要があるデータベース、内部API、キャッシングレイヤー、またはマイクロサービスに最適です。
- 内部ディスカバリ: Kubernetesの内部DNSを活用して、安定したサービスディスカバリ名(例:
my-database.namespace.svc.cluster.local)を提供します。
実装詳細
ClusterIPサービスが作成されると、Kubernetesはクラスターネットワークファブリックの内部でのみルーティング可能な仮想IPアドレスを割り当てます。外部トラフィックはこのIPに直接到達することはできません。
マニフェストの例 (ClusterIP):
apiVersion: v1
kind: Service
metadata:
name: internal-api
spec:
selector:
app: backend-service
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: ClusterIP
ヒント: すべてのコンポーネントがクラスター内に存在する分散システムのみを構築している場合、
ClusterIPは不要な外部公開を回避するため、最も安全で効率的な選択肢です。
2. NodePort:特定のクラスターノード経由でのサービスの公開
NodePortは、サービスを外部に公開する最もシンプルな方法です。クラスター内のすべてのノード(VMまたは物理マシン)で特定のポートを開放し、そのポートに到達した外部トラフィックをサービスにルーティングします。
NodePortのユースケース
- 開発とテスト: フル機能のクラウドロードバランサー設定が過剰である開発中に、外部からアクセス可能なサービスを迅速にテストするのに役立ちます。
- 非クラウド環境: ネイティブなクラウドロードバランシング統合が利用できないベアメタルまたはオンプレミスKubernetesインストールにおいて不可欠です。
実装詳細
NodePortサービスが作成されると、Kubernetesはすべてのノードで設定された範囲(デフォルトは30000~32767)の静的ポートを選択します。サービスは次の方法でアプリケーションを公開します。
http://<NodeIP>:<NodePort>
IPアドレスが10.0.0.1、10.0.0.2、10.0.0.3の3つのノードがあり、NodePortが30080の場合、これら3つのIPのいずれかを使用してポート30080でサービスにアクセスできます。
マニフェストの例 (NodePort):
apiVersion: v1
kind: Service
metadata:
name: test-web-app
spec:
selector:
app: frontend
ports:
- protocol: TCP
port: 80
targetPort: 8080
nodePort: 30080 # オプション:外部ポートを指定しない場合、Kubernetesが選択します
type: NodePort
警告: サービスはすべてのノードで公開されるため、ノードが失敗した場合、トラフィックがそのノードにルーティングされないようにする必要があります。さらに、ポート範囲(30000-32767)が他のサービスやホスト構成と競合する可能性があります。
3. LoadBalancer:クラウドネイティブな外部公開
LoadBalancerは、サポートされているクラウドプロバイダー(AWS、GCP、Azureなど)で実行している本番アプリケーションを外部に公開するための推奨される方法です。
LoadBalancerのユースケース
- 本番デプロイメント: クラウドプロバイダーのインフラストラクチャとシームレスに統合される、堅牢で高可用な外部アクセスを提供します。
- 自動IP管理: 個々のノードIPを知る必要やポートの競合を管理する必要がなくなります。
実装詳細
クラウド環境でLoadBalancerタイプのサービスが作成されると、対応するクラウドコントローラーマネージャーは外部ロードバランサー(例:AWS ELBまたはGCPロードバランサー)をプロビジョニングし、指定されたNodePort(クラウドLBが通常内部的に管理)でクラスターノードにトラフィックをルーティングするように構成します。
この外部ロードバランサーは、専用の静的外部IPアドレスを受け取ります。
マニフェストの例 (LoadBalancer):
apiVersion: v1
kind: Service
metadata:
name: public-web-service
spec:
selector:
app: public-facing
ports:
- protocol: TCP
port: 80
targetPort: 80
type: LoadBalancer
これが作成されると、出力(kubectl get svcを使用)には割り当てられた外部IPが表示されます。
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
public-web-service LoadBalancer 10.96.45.11 34.120.200.55 80:30021/TCP 1m
これで、アプリケーションはhttp://34.120.200.55経由で到達可能になります。
ベストプラクティス: HTTPS/SSL終端を必要とするサービスの場合、Kubernetes Pod内で終端ロジックを実行するのではなく、外部クラウドロードバランサー(クラウドプロバイダー固有のアノテーションを使用)を構成してTLSを処理することが推奨されます。
比較概要表
| 特徴 | ClusterIP | NodePort | LoadBalancer |
|---|---|---|---|
| 主な用途 | サービス間の内部通信 | 簡単な外部アクセス(テスト/ベアメタル) | 本番、クラウドネイティブな外部アクセス |
| 到達可能性 | クラスター内のみ | すべてのノードで静的ポート(30000-32767) | クラウドプロバイダーが管理する外部IP |
| IPの安定性 | 安定した内部IP | 安定したノードIP、ただしポートを知る必要がある | |
| クラウド依存性 | なし | なし | 高い(クラウドコントローラーマネージャーが必要) |
| コスト | 無料(外部インフラストラクチャなし) | 最小限(ノードリソースを使用) | かなり高額(外部LBリソースの料金) |
| 構成の複雑さ | 最低 | 低 | 中程度(クラウド構成が必要) |
結論:賢明な選択
適切なサービスタイプを選択することは、Kubernetesネットワークにおける基本的なステップです。
- 内部から始める (
ClusterIP): サービスがクラスターの外部からアクセスされる必要がない場合は、常にClusterIPを使用してください。これにより、攻撃対象領域とオーバーヘッドが最小限に抑えられます。 - テスト/ベアメタル (
NodePort): 基本的な外部テストが必要な場合や、主要なクラウド環境外でKubernetesを実行している場合は、NodePortが即座に、ただし堅牢性では劣るものの、外部アクセスを提供します。 - 本番クラウド (
LoadBalancer): AWS、GCP、Azureでホストされている本番アプリケーションで、耐久性があり、安定した、専用の外部エントリポイントが必要な場合は、LoadBalancerが正しい選択であり、堅牢性のためにクラウドインフラストラクチャを活用します。
サービスタイプを必要なアクセス性とデプロイメント環境に合わせることで、コンテナオーケストレーションアーキテクチャ内での最適なパフォーマンス、セキュリティ、および統合が保証されます。