🎓 レベル:標準 | 重要度:A(必須)
📎 前提:Pod・Deployment・ReplicaSet | 関連:ConfigMap・Secret・ボリューム・デプロイ戦略(ローリング・ブルーグリーン・カナリア)
要点(BLUF)
- Pod は使い捨てでIPが変わる。Service は「ラベルで選んだPod群」に対する安定した仮想IP+名前を与え、L4で負荷分散する。
- 主な Service の型:ClusterIP(内部のみ)・NodePort(ノードのポートで外出し)・LoadBalancer(クラウドのLBを払い出す)。
- Ingress は L7(HTTP)ルータ。ホスト名・パスでルーティングし、TLS終端もまとめる。複数サービスを1つの入口に束ねる。
概念 ── 動く標的に安定した宛先を
Pod は作り直されるたびにIPが変わります(Pod・Deployment・ReplicaSet)。これでは「どこに繋げばいい?」が定まらない。Service は、ラベルセレクタで該当Podを動的に追跡し、変わらない仮想IPと内部DNS名を提供します。クライアントは Service 名で繋ぐだけ。
flowchart TB
client["クライアント"] -->|"web という名前で接続"| svc["Service web(安定した仮想IP)"]
svc -->|"ラベル app=web で選別・分散"| p1["Pod(変わるIP)"]
svc --> p2["Pod"]
svc --> p3["Pod"]
これはコンテナのネットワーク名前解決(コンテナのネットワークとボリューム)を、クラスタ規模・動的Pod対応に拡張したものです。
仕組み① ── Service の型
| 型 | 公開範囲 | 用途 |
|---|---|---|
| ClusterIP(既定) | クラスタ内部のみ | サービス間通信(DB・内部API) |
| NodePort | 各ノードの固定ポート | 簡易な外部公開・検証 |
| LoadBalancer | クラウドのLB経由で外部 | 本番の外部公開(要最新確認・課金) |
apiVersion: v1
kind: Service
metadata:
name: web
spec:
selector:
app: web # このラベルのPodへ振り分ける
ports:
- port: 80 # Service の受け口
targetPort: 80 # Pod 側のポート
type: ClusterIP # 内部のみ(既定)
仕組み② ── Ingress(L7ルーティング)
Service を外に出すたびに LoadBalancer を払い出すと、LBが増えてコストも増える。Ingress は1つの入口で、HTTP のホスト名やパスを見て適切な Service へ振り分けます。TLS(HTTPS)の終端も集約できます。
flowchart TB
user["外部ユーザー"] --> ing["Ingress(1つの入口・L7)"]
ing -->|"/api → "| svcapi["Service api"]
ing -->|"/ → "| svcweb["Service web"]
ing -->|"shop.example.com → "| svcshop["Service shop"]
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: site
spec:
rules:
- host: example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api
port: { number: 80 }
- path: /
pathType: Prefix
backend:
service:
name: web
port: { number: 80 }
Ingress を効かせるにはクラスタに Ingress コントローラ(nginx 等)が要ります。L4 の負荷分散の原理や TCP/IP は コンピュータネットワーク へ。ここは「マネージド/標準部品をどう組むか」。
なぜ Service と Ingress を分けるのか
- 動的なPodを隠すため(Service):Podが入れ替わっても宛先が変わらない。負荷分散も自動。これがローリング更新(Pod・Deployment・ReplicaSet)を無停止にする土台。
- 入口を1つに集約するため(Ingress):ドメイン・パス単位のルーティング、TLS終端、LB費の節約を1か所で。サービスが増えても入口は1つ。
- 役割を分離するため:Service は L4(IP/ポート)、Ingress は L7(HTTP)。層が違うので責務も分ける。
⚠️ よくある誤解・落とし穴
- 「Pod のIPに直接繋ぐ」→ 作り直しで即無効。必ず Service 経由。
- 「全 Service を LoadBalancer 型に」→ LBが乱立しコスト増。外部公開は Ingress に集約し、内部は ClusterIP。
- 「Ingress を作れば動く」→ Ingress コントローラが未導入だと何も起きない。先にコントローラを入れる。
- 「
selectorのラベルが Pod と不一致」→ Service が空(繋がらない)。ラベルの綴りミスは定番事故。kubectl get endpointsで実際の振り先を確認。 - 「TLS証明書を手で管理」→ 失効で事故。cert-manager 等で自動更新(要最新確認)。
対応ラボ
cloud-infra-study/labs/04-03_service.yaml(前トピックの Deployment に ClusterIP Service を付け、kubectl port-forward で到達確認 → Pod を消しても Service 経由で繋がり続けることを観察)。
関連
- 振り先となる Pod 群は Pod・Deployment・ReplicaSet
- コンテナ単体の名前解決は コンテナのネットワークとボリューム
- 無停止リリースの戦略は デプロイ戦略(ローリング・ブルーグリーン・カナリア)
- 設定・秘密の注入は ConfigMap・Secret・ボリューム