CTS-KB

ClusterIP・NodePort・LoadBalancer・Ingress:GKEの通信経路を理解する

⏱ 約 4 分で読めます
#Kubernetes#GKE#Service#Ingress#Load Balancer

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

Kubernetes ServiceとIngressの公開範囲

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 serviceEXTERNAL-IP<pending> になる場合があります。

EXTERNAL-IPとexternalIPsは別物

kubectl get serviceEXTERNAL-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
  1. PodがReadyか
  2. ServiceのselectorとEndpointSliceが正しいか
  3. Ingressのbackend名とポートが正しいか
  4. Ingressイベントにエラーがないか
  5. Google Cloud側のLB・ヘルスチェック・DNSが整ったか

入口からではなく、まず最も内側のPodとServiceを確認すると原因を切り分けやすくなります。

コストにも注意する

type: LoadBalancer やIngressはクラウドのロードバランサー、IP、転送などの費用を発生させます。小さなServiceごとに外部LBを作るより、要件が合えば1つのIngress/GatewayへHTTP経路をまとめる方が管理と費用を抑えられます。

参考資料