説明
セレクターを使う Service は、同じネームスペース内で一致する Pod を選択してトラフィックを転送します。実際の Pod ラベルが一致しない場合や、targetPort がアプリケーションの待ち受けポートと異なる場合は、接続に失敗することがあります。
containerPort の宣言だけでアプリケーションの待ち受けポートは変わりません。セレクターなしで個別に管理する EndpointSlice を使う Service も有効なため、実際の接続方式を確認する必要があります。
想定される影響
- 準備済みの対象がなく要求が失敗したり、誤ったポートへ転送されたりする場合があります。
- Service が存在してもアプリケーションが応答せず、障害の診断が難しくなる場合があります。
対処方法
- Service のセレクターと、同じネームスペースの実際の Pod ラベルを確認してください。Deployment などが作る Pod では template のラベルを確認してください。
- targetPort を実際の待ち受けポート番号か、宣言したポート名に合わせてください。EndpointSlice の対象と準備状態を確認し、実際の接続を試してください。
例
Pod ラベルの違いを比較する既存の例です。nginx のデフォルトの待ち受けポートは 80 で、containerPort: 9377 の宣言だけでは変わりません。9377 で待ち受けるようアプリケーションを設定するか、targetPort を実際のポートに合わせる必要があります。
変更前
yaml
apiVersion: v1
kind: Service
metadata:
name: helloworld
spec:
selector:
app: helloworld
ports:
- port: 9377
targetPort: 9377
---
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: different-label
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 9377
セレクターとラベルが一致せず、この Pod は選択されません。他に一致する Pod があるかも確認してください。
変更後
yaml
apiVersion: v1
kind: Service
metadata:
name: helloworld
spec:
selector:
app: helloworld
ports:
- port: 9377
targetPort: 9377
---
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels:
app: helloworld
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 9377
ラベルを合わせて、この Pod を選択できるようにします。準備状態と実際の待ち受けポートは別途確認する必要があります。