1️⃣ 개요
StatefulSet에서 특정 Pod를 특정 노드에 배치하거나, 특정 노드에서 강제로 이동해야 하는 경우가 있습니다.
특히, 노드 장애 발생 시 Pod를 안전하게 재배치하거나, 고성능 스토리지가 있는 노드에 특정 StatefulSet Pod를 배치하는 것이 중요합니다.
이번 글에서는 StatefulSet의 Pod를 특정 노드에 배치하거나 이동하는 다양한 방법과 실전 활용법을 정리하겠습니다. 🚀
2️⃣ StatefulSet Pod 재배치 및 고정이 필요한 이유
📌 StatefulSet Pod 배치를 조정해야 하는 주요 상황
상황 | 설명 |
노드 장애 발생 | 특정 노드 장애 시, 다른 노드로 Pod를 이동해야 함 |
고성능 스토리지 연결 | 특정 Pod를 SSD가 있는 노드에서 실행해야 함 |
지리적 분산 배포 | 특정 노드 그룹(Region, Zone)에 Pod를 배치해야 함 |
자원 활용 최적화 | CPU, 메모리가 많은 노드에 StatefulSet을 배치 |
✅ StatefulSet에서는 Pod가 삭제되더라도 같은 이름으로 다시 생성되므로, 특정 노드에 고정하거나 강제 이동하는 방법이 필요합니다.
3️⃣ StatefulSet Pod를 특정 노드에 고정하는 방법
✅ 1. Node Selector 사용 (특정 노드에 배치 제한)
Node Selector를 사용하면 특정 라벨이 있는 노드에서만 Pod가 실행되도록 설정할 수 있습니다.
📌 특정 노드에 라벨 추가
kubectl label nodes node-1 disktype=ssd
📌 StatefulSet에서 Node Selector 적용 예제
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: mysql
replicas: 3
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
nodeSelector:
disktype: ssd # 특정 노드에서만 실행
containers:
- name: mysql
image: mysql:8
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql
volumeClaimTemplates:
- metadata:
name: mysql-data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 10Gi
✅ 이제 disktype=ssd 라벨이 있는 노드에서만 StatefulSet Pod가 실행됩니다.
✅ 2. Node Affinity 사용 (고급 배치 전략 적용)
Node Selector보다 더 유연한 조건을 설정할 수 있는 Node Affinity를 활용하면, 복수의 조건을 조합하여 StatefulSet Pod 배치가 가능합니다.
📌 Node Affinity 적용 예제 (특정 노드 그룹에서 실행하도록 설정)
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: redis
spec:
serviceName: redis
replicas: 3
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- node-1
- node-2
containers:
- name: redis
image: redis:latest
volumeMounts:
- name: redis-data
mountPath: /data
volumeClaimTemplates:
- metadata:
name: redis-data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 5Gi
✅ 이제 node-1 또는 node-2에서만 StatefulSet이 실행됩니다.
✅ 3. Taint & Toleration을 활용한 노드 격리
Taint를 설정하면, 특정 Pod만 해당 노드에서 실행되도록 설정할 수 있습니다.
📌 특정 노드에 Taint 추가 (다른 Pod는 실행되지 않도록 설정)
kubectl taint nodes node-3 special-node=true:NoSchedule
📌 StatefulSet Pod에서 해당 Taint를 허용하는 설정
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: elasticsearch
spec:
serviceName: elasticsearch
replicas: 3
template:
metadata:
labels:
app: elasticsearch
spec:
tolerations:
- key: "special-node"
operator: "Equal"
value: "true"
effect: "NoSchedule"
✅ 이제 Elasticsearch StatefulSet은 node-3에서만 실행되며, 다른 Pod는 해당 노드에서 실행되지 않습니다.
4️⃣ StatefulSet Pod를 다른 노드로 강제 이동하는 방법
✅ 1. 특정 노드에서 StatefulSet Pod를 강제 제거 (cordon & drain)
📌 노드를 스케줄링 불가능하도록 설정 (cordon)
kubectl cordon node-1
📌 현재 실행 중인 Pod를 다른 노드로 이동 (drain)
kubectl drain node-1 --ignore-daemonsets --delete-emptydir-data
✅ 이제 StatefulSet Pod는 다른 노드로 이동됩니다.
✅ 2. 특정 StatefulSet Pod를 강제로 삭제하여 다른 노드에서 실행하도록 유도
📌 Pod 삭제 후 새로운 노드에서 실행되도록 유도
kubectl delete pod mysql-0
📌 새로운 노드에서 실행되는지 확인
kubectl get pods -o wide
✅ StatefulSet 컨트롤러가 자동으로 새로운 노드에서 Pod를 실행합니다.
5️⃣ StatefulSet Pod 배치 최적화 전략
✅ 1. Pod Anti-Affinity 설정 (StatefulSet Pod 간 노드 분산 배치)
StatefulSet의 Pod가 특정 노드에 몰리는 것을 방지하려면 Pod Anti-Affinity를 활용해야 합니다.
📌 Pod Anti-Affinity 설정 예제
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchLabels:
app: kafka
topologyKey: "kubernetes.io/hostname"
✅ 이제 동일한 StatefulSet의 Pod가 같은 노드에 배치되지 않습니다.
✅ 2. 노드 그룹별 배포 정책 적용 (Region 및 Zone 고려)
📌 다른 리전에 분산 배포하도록 설정
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: topology.kubernetes.io/zone
operator: In
values:
- us-east-1a
- us-east-1b
✅ 클러스터 노드가 여러 지역(Region)에 분산된 경우, 특정 Zone에 StatefulSet Pod를 배포할 수 있습니다.
🔥 6️⃣ 결론
✔ StatefulSet Pod를 특정 노드에 배치하려면 Node Selector, Node Affinity, Toleration을 활용해야 함
✔ Pod를 특정 노드에서 제거하려면 kubectl drain, kubectl delete pod 명령어를 활용해야 함
✔ Pod Anti-Affinity를 활용하면 StatefulSet Pod가 특정 노드에 몰리는 것을 방지할 수 있음
✔ 다중 리전 및 가용 영역(Zone)에 StatefulSet을 배포하려면 Node Affinity 설정을 활용해야 함