Kubernetesを勉強していると登場するリソースの種類が多すぎて始めは嫌になってしまいますよね。特にServiceはさらに何種類ものタイプが存在して初心者には違いが全くわかりません。
今回は公式ドキュメントに挙げられている一般的によく使用される以下の3つのServiceのタイプの違いについて紹介します。
- ClusterIP
- NodePort
- LoadBalancer
そもそもServiceの役割とは
まずそもそもなぜServiceというリソースが必要なのかを理解しておきましょう。Serviceの基本的な役割はPodの集合から成り立っているアプリケーション外部公開です。
そもそもKubernetesの最小単位であるPodは停止することを前提としています。そのためPodへの通信を考えたときに仮にPodが停止して再生成されていた場合、生成前と後で割り当てられるIPアドレスが変わってしまう問題が生じます。

ServiceはPodやDeploymentの名前を指定することでIPアドレスの変化に依らず通信を可能にするため、通信のたびにPodのIPアドレスを探し出す必要をなくすことができるのです。
ClusterIP
デフォルトで指定されるServiceのタイプで、クラスター外と通信する必要がない場面でクラスタ内のロードバランサーとして利用されます。
内部ネットワークに仮想 IP アドレスが割り当てられ、ClusterIP 宛の通信は指定されたPod へ転送されます。例えばkubernetes API に接続するための kubernetes serviceが該当します。

マニフェストファイルは下のように記述します。わかりにくいのはspec.ports[].portとspec.ports[].targetPortの部分ですね。portはClusterIPで受けるポート番号で、targetPortとは転送先のコンテナで受けるポート番号を表します。
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: ClusterIP
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
NodePort
NodePortは各ノードが持つIP アドレスの指定したポートにおいて、受信した通信を指定されたPodに転送して外部との通信を可能にする役割を持ちます。

マニフェストファイルは下のようになります。先程と比べてtypeはもちろん変わっており、さらにspec.ports[].nodePortという項目が追加されています。このポート番号(今回は30080)を指定すると、全ノードにおいて30080宛の通信はspec.selectorで指定したコンテナに転送されることで外部との通信を可能にします。
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: NodePort
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
nodePort: 30080
なお、spec.ports[].nodePorは一般的に 30000~32767の範囲で指定する必要があります。
LoadBalancer
LoadBalancerは上2つとは異なり、クラスター外のロードバランサーに外部と通信可能な仮想 IP アドレスを払い出す役割を果たします。
外部のロードバランサーを利用するため、対応した環境(AWS/GCP/Azure/IBM Cloud など)である必要があります。
NodePortでは最終的にいずれかのノードに割り当てられたIPアドレス宛に通信を行うためそのノードが単一障害点となりやすいですが、LoadBalancerはクラスター外のロードバランサーを利用するため障害に強い特徴があります。
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: LoadBalancer
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
コメント