StatefulSet の Headless Service 接続の確認

serviceName、実際の Headless Service、Pod セレクターが一致するか確認してください。

説明

StatefulSet は serviceName で指定した Headless Service を使い、Pod ごとの安定したネットワーク名を提供します。その Service は同じネームスペースに別途作成し、セレクターを StatefulSet の Pod ラベルに合わせる必要があります。名前の指定だけで Service が自動作成されたり、DNS と接続が保証されたりするわけではありません。

想定される影響

  • Pod ごとの名前解決やメンバー間の通信に失敗する場合があります。
  • Service のセレクターが別の Pod を指すと、意図したワークロードへの接続に障害が生じる場合があります。

対処方法

  • 同じネームスペースに clusterIP: None の Headless Service を用意し、serviceName をその名前に合わせてください。セレクター、Pod ラベル、実際の待ち受けポートも確認してください。
  • 既存の通常の Service を Headless に変更する前に、再作成と接続中断の影響を計画してください。適用後に EndpointSlice、Pod の準備状態、Pod ごとの DNS と実際の接続を確認してください。

例

app ネームスペースを使う既存の nginx の例です。ネームスペースは別途用意し、10.0.0.20 はクラスターの Service アドレス範囲内で利用可能な値にする必要があります。通常の Service から Headless への変更では、Service の再作成が必要になる場合があります。

変更前

yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx
  namespace: app
spec:
  clusterIP: 10.0.0.20
  selector:
    app: other
  ports:
    - port: 80
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
  namespace: app
spec:
  serviceName: nginx
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.25

通常の ClusterIP Service で、セレクターも StatefulSet の Pod ラベルと異なります。必要な Pod ごとの Headless Service 接続を提供しません。

変更後

yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx
  namespace: app
spec:
  clusterIP: None
  selector:
    app: nginx
  ports:
    - port: 80
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
  namespace: app
spec:
  serviceName: nginx
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:1.25

同じ nginx という名前の Service を Headless にし、セレクターを Pod ラベルに合わせます。準備状態とクラスターのネットワークを踏まえ、実際の DNS と接続を確認する必要があります。

参考資料