説明
StatefulSet のレプリカが同じノードに集まると、一つのノード障害で複数の Pod が影響を受けます。Pod アンチアフィニティやトポロジー分散制約で配置を制御でき、セレクターは実際の Pod ラベルに一致する必要があります。
required は配置条件を強制し、preferred は優先度として働きます。ホスト単位の分散だけで、ゾーン障害やアプリケーションの複製クォーラムまで保護されるわけではありません。
想定される影響
- 一つのノード障害で複数のレプリカが同時に停止する場合があります。
- 厳しい条件に合うノードが足りないと、Pod が Pending のままになる場合があります。
対処方法
- ワークロードの障害・クォーラム要件に合わせて podAntiAffinity やトポロジー分散制約を設定してください。実際の Pod ラベルと topologyKey を確認してください。
- 必須ルールに必要なノード数、容量、ストレージの配置条件を確認し、実際の配置を試してください。IgnoredDuringExecution は、実行中の Pod を自動移動させるものではありません。
例
既存の ZooKeeper イメージで配置ルールだけを比較します。運用にはサポートされるイメージを使い、zk-hs Headless Service を別途用意してください。変更後は、条件に合う異なるノードが最低 3 台必要です。
変更前
yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: zk
spec:
serviceName: zk-hs
replicas: 3
selector:
matchLabels:
app: zk
template:
metadata:
labels:
app: zk
spec:
containers:
- name: zookeeper
image: k8s.gcr.io/kubernetes-zookeeper:1.0-3.4.10
3 レプリカを定義しますが、この抜粋には分散ルールがありません。実際の配置と他のポリシーを確認する必要があります。
変更後
yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: zk
spec:
serviceName: zk-hs
replicas: 3
selector:
matchLabels:
app: zk
template:
metadata:
labels:
app: zk
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: zk
topologyKey: kubernetes.io/hostname
containers:
- name: zookeeper
image: k8s.gcr.io/kubernetes-zookeeper:1.0-3.4.10
app: zk の Pod が同じホストに配置されないよう強制します。適切なノードが不足すると、すべてのレプリカを実行できない場合があります。