Kubernetes/Kubernetes Advanced

📌 [StatefulSet 심화편 #10] StatefulSet의 Pod 강제 이동 (Node 간 재배치 방법)

ygtoken 2025. 3. 14. 10:15
728x90

 

1️⃣ 개요

 

StatefulSet은 특정 Pod가 고유한 네트워크 ID와 Persistent Volume을 유지하는 특성 때문에, 일반적인 Deployment보다 Pod를 다른 노드로 이동시키는 것이 어렵습니다.

특히, 노드 장애 발생 시 특정 Pod를 다른 노드로 강제 이동해야 하는 경우, 올바르게 처리하지 않으면 PVC가 제대로 연결되지 않거나 데이터 정합성 문제가 발생할 수 있습니다.

 

이번 글에서는 StatefulSet의 Pod를 특정 노드에서 강제로 이동하는 방법과, PVC를 유지하면서 안전하게 마이그레이션하는 전략을 설명하겠습니다. 🚀

 


2️⃣ StatefulSet Pod가 특정 노드에 고정되는 이유

 

✅ 1. StatefulSet Pod의 스케줄링 방식

 

StatefulSet Pod는 쿠버네티스의 스케줄링 정책에 따라 특정 노드에 배치됩니다.

Pod가 한 번 특정 노드에서 실행되면, 해당 Pod가 다시 생성될 때도 동일한 노드에 배치되는 경우가 많습니다.

 

📌 StatefulSet Pod가 특정 노드에 고정되는 이유

원인 설명
PVC 바인딩 Persistent Volume이 특정 노드에 종속됨
Pod Anti-Affinity 특정 Pod 간 거리 제약 조건이 설정됨
노드 셀렉터(Node Selector) 특정 노드에서만 실행되도록 설정됨
Pod가 노드 장애 이후 자동 이동되지 않음 StatefulSet의 기본 동작은 자동 재배치를 지원하지 않음

특정 노드에 고정된 StatefulSet Pod를 이동시키려면, PVC와 스케줄링 정책을 함께 고려해야 합니다.

 


3️⃣ 특정 StatefulSet Pod를 다른 노드로 이동하는 방법

 

✅ 1. 특정 Pod가 실행 중인 노드 확인

 

Pod가 현재 실행 중인 노드를 확인하려면 다음 명령어를 사용할 수 있습니다.

 

📌 현재 StatefulSet Pod가 실행 중인 노드 확인

kubectl get pods -o wide

 

출력 예시:

NAME        READY   STATUS    NODE
mysql-0     1/1     Running   node-1
mysql-1     1/1     Running   node-2
mysql-2     1/1     Running   node-3

어떤 노드에서 실행되고 있는지 확인한 후, 특정 Pod를 이동할 계획을 세울 수 있습니다.

 


✅ 2. 노드에서 StatefulSet Pod를 강제 이동하기

 

🔹 (1) 특정 노드를 스케줄링 불가능하도록 설정 (cordon)

 

Pod를 이동하려면 먼저 현재 실행 중인 노드에서 새로운 Pod가 스케줄링되지 않도록 차단해야 합니다.

 

📌 특정 노드를 스케줄링 불가능하게 설정

kubectl cordon node-1

이제 node-1에는 새로운 Pod가 스케줄링되지 않습니다.

 


🔹 (2) 기존 Pod를 강제 삭제하여 다른 노드에서 다시 생성되도록 유도

 

Pod를 삭제하면 StatefulSet 컨트롤러가 자동으로 새로운 노드에서 Pod를 생성하려고 시도합니다.

📌 기존 StatefulSet Pod 삭제

kubectl delete pod mysql-0

 

📌 새로운 노드에서 실행되는지 확인

kubectl get pods -o wide

이제 mysql-0이 다른 노드에서 생성되었는지 확인할 수 있습니다.

 


✅ 3. PVC를 유지하면서 StatefulSet Pod를 다른 노드로 이동하기

 

기본적으로 PVC는 특정 노드에 종속되지 않아야 합니다.

그러나 클라우드 환경(AWS EBS, Azure Disk 등)에서는 PVC가 특정 노드에 고정되므로, Pod가 새로운 노드에서 실행될 때 기존 PVC를 사용할 수 없을 수도 있습니다.

 

📌 PVC가 특정 노드에 종속되었는지 확인

kubectl get pvc -o wide

출력 예시:

NAME                  STATUS    VOLUME      NODE
mysql-data-mysql-0    Bound     pv-12345    node-1

PVC가 특정 노드에 종속되었다면, 수동으로 마운트를 변경해야 합니다.

 


🔹 (1) 기존 PVC를 삭제하지 않고 유지하면서 Pod 이동

 

PVC를 유지한 상태에서 Pod를 다른 노드로 이동하려면, 기존 PVC의 PersistentVolume을 다른 노드에서 사용할 수 있도록 설정해야 합니다.

 

📌 PVC의 Reclaim Policy 변경 (Retain으로 설정하여 유지)

kubectl patch pv pv-12345 -p '{"spec":{"persistentVolumeReclaimPolicy":"Retain"}}'

 

📌 PVC를 강제로 StatefulSet과의 연결 해제

kubectl patch pvc mysql-data-mysql-0 -p '{"metadata":{"ownerReferences":null}}'

이제 PVC가 특정 StatefulSet Pod와 연결되지 않고 유지됩니다.

 


🔹 (2) 기존 PVC를 새로운 노드에서 다시 연결하기

 

이제 StatefulSet이 새로운 노드에서 Pod를 실행할 때, 기존 PVC를 사용할 수 있도록 설정해야 합니다.

 

📌 Pod 삭제 후 StatefulSet이 새로운 노드에서 실행되도록 유도

kubectl delete pod mysql-0

 

📌 Pod가 새로운 노드에서 실행된 후, 기존 PVC가 정상적으로 연결되었는지 확인

kubectl get pods -o wide
kubectl get pvc -o wide

이제 PVC가 새로운 노드에서도 그대로 유지되면서 StatefulSet Pod가 실행됩니다.

 


4️⃣ StatefulSet Pod 이동 후 정상 동작 확인

 

📌 (1) StatefulSet Pod가 새로운 노드에서 정상적으로 실행되는지 확인

kubectl get pods -o wide

 

📌 (2) PVC가 정상적으로 기존 Pod와 연결되었는지 확인

kubectl get pvc

 

📌 (3) 데이터 정합성이 유지되는지 점검 (예: MySQL 데이터 확인)

kubectl exec -it mysql-0 -- mysql -u root -p -e "SHOW DATABASES;"

모든 점검이 완료되면 StatefulSet Pod 이동이 성공적으로 이루어진 것입니다.

 


🔥 5️⃣ 결론

 

StatefulSet Pod는 기본적으로 특정 노드에 고정될 가능성이 있으므로, 강제 이동이 필요할 수 있음

Pod가 특정 노드에서 실행되지 않도록 kubectl cordon을 활용하여 스케줄링을 차단해야 함

PVC가 특정 노드에 종속되지 않도록 Reclaim Policy를 변경하고, StatefulSet과의 연결을 수동 해제할 필요가 있음

Pod 삭제 후 PVC가 자동으로 연결되는지 확인해야 하며, 정상적으로 실행되었는지 점검이 필요함

모든 과정이 정상적으로 진행되었는지 kubectl get pods -o wide 및 kubectl get pvc로 확인하는 것이 중요함

728x90