Podは障害や更新で作り直され、そのたびにIPアドレスが変わります。利用者や別のアプリケーションがPodのIPを直接追いかけずに済むよう、Service が安定した宛先を提供します。

Serviceの3つの基本type
| type | 到達範囲 | 主な用途 |
|---|---|---|
| ClusterIP | クラスタ内部 | 内部API、Ingressの転送先 |
| NodePort | 各Nodeの特定ポート | 検証、上位ロードバランサーとの接続 |
| LoadBalancer | クラウドLB経由 | 1つのTCP/UDPサービスを外部・内部公開 |
既定値はClusterIPです。公開範囲は「とりあえず大きく」せず、必要な入口だけを外へ出します。
ClusterIPで内部公開する
apiVersion: v1
kind: Service
metadata:
name: example-api
namespace: YOUR_NAMESPACE
spec:
type: ClusterIP
selector:
app: example-api
ports:
- name: http
port: 80
targetPort: 8080
同じNamespaceからは通常 http://example-api、別Namespaceからは http://example-api.YOUR_NAMESPACE.svc.cluster.local のようなDNS名で参照できます。
port はServiceが受けるポート、targetPort はPodのコンテナが待ち受けるポートです。Serviceのselectorに一致し、readinessが成功したPodが転送先になります。
kubectl get service,endpointslices -n YOUR_NAMESPACE
kubectl describe service example-api -n YOUR_NAMESPACE
Serviceはあるのに通信できない場合、最初にselectorとPodラベル、EndpointSliceの転送先を確認します。
NodePortはNodeのポートを開く
spec:
type: NodePort
selector:
app: example-api
ports:
- port: 80
targetPort: 8080
protocol: TCP
NodePortは各NodeのIPと割り当てポートでServiceを公開します。しかしGKEの外部公開では、ファイアウォール、Node到達性、可用性まで自分で考える必要があります。エンドユーザー向けHTTPを単純にNodePortだけで公開する構成は一般的ではありません。
LoadBalancerはクラウドLBを作る
apiVersion: v1
kind: Service
metadata:
name: example-tcp
namespace: YOUR_NAMESPACE
spec:
type: LoadBalancer
selector:
app: example-tcp
ports:
- port: 443
targetPort: 8443
protocol: TCP
GKEではGoogle Cloudロードバランサーと外部または内部IPが構成されます。作成には数分かかることがあり、その間 kubectl get service の EXTERNAL-IP が <pending> になる場合があります。
EXTERNAL-IPとexternalIPsは別物
kubectl get service の EXTERNAL-IP列 は、外部から利用する宛先の表示です。一方、マニフェストの spec.externalIPs はKubernetesがIPを割り当てる機能ではなく、現在は非推奨です。新規構成で「外部IPが欲しいから externalIPs を書く」という使い方はしません。
IngressでHTTP/HTTPSを集約する
Ingress はServiceのtypeではなく、複数のClusterIP ServiceへHTTP/HTTPSを振り分ける別のAPIです。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
namespace: YOUR_NAMESPACE
spec:
rules:
- host: app.example.invalid
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: example-api
port:
number: 80
example.invalid は説明用で、実在サービスには到達しません。本番では管理するドメイン、DNS、TLS証明書、静的IP、ヘルスチェックを設計します。
GKEのIngress controllerはIngressを監視し、Google Cloudロードバランサーを構成します。Ingressオブジェクトだけでは通信経路は生まれず、controllerの実装が必要です。
GKEではロードバランサーのbackend方式にも注意します。インスタンスグループ経由のbackendではServiceにNodePortが必要です。コンテナネイティブ負荷分散でNEGを使う構成ならClusterIP Serviceを利用できます。クラスタやServiceがNEGの自動設定条件を満たすかを確認し、必要な場合は公式手順に従って cloud.google.com/neg annotationを明示します。
IngressとGateway API
Ingress APIは安定しており、削除予定はありません。ただし機能追加は凍結され、Kubernetesは新しい拡張の中心をGateway APIへ移しています。既存GKE資産や基本HTTP公開を理解するためにIngressは重要ですが、新規の複雑なルーティングではGKE Gateway controllerも比較します。
公開後の確認順
kubectl get ingress,service,pods -n YOUR_NAMESPACE
kubectl describe ingress example-ingress -n YOUR_NAMESPACE
kubectl get endpointslices -n YOUR_NAMESPACE
kubectl get events -n YOUR_NAMESPACE --sort-by=.metadata.creationTimestamp
- PodがReadyか
- ServiceのselectorとEndpointSliceが正しいか
- Ingressのbackend名とポートが正しいか
- Ingressイベントにエラーがないか
- Google Cloud側のLB・ヘルスチェック・DNSが整ったか
入口からではなく、まず最も内側のPodとServiceを確認すると原因を切り分けやすくなります。
コストにも注意する
type: LoadBalancer やIngressはクラウドのロードバランサー、IP、転送などの費用を発生させます。小さなServiceごとに外部LBを作るより、要件が合えば1つのIngress/GatewayへHTTP経路をまとめる方が管理と費用を抑えられます。