
운영 중인 데이터베이스가 갑자기 사라진다면?
새벽 2시에 갑작스러운 알람을 받고 클러스터에 접속했을 때, 데이터베이스 포드가 깨져 있거나 스토리지 연결이 끊겨 있다면 그 당혹감은 이루 말할 수 없어요. 특히 일반적인 디플로이먼트(Deployment)와 달리 스테이트풀셋(StatefulSet)은 포드의 순서와 이름, 그리고 데이터가 담긴 볼륨의 연결 관계가 매우 엄격하게 관리돼요. 명령어를 잘못 입력해서 포드 번호가 꼬이거나 스토리지 연결이 해제되는 순간, 서비스 전체에 치명적인 장애가 발생할 수 있어요.
많은 엔지니어가 클라우드 마이그레이션을 진행하면서 가장 어려워하는 부분이 바로 이 상태 유지 작업이에요. 단순히 컨테이너를 띄우는 것을 넘어, 각 포드가 고유한 정체성을 유지하며 기존 데이터를 정확히 물고 다시 살아나게 만드는 과정이 필요하거든요. 스테이트풀셋을 다루는 kubectl 명령어는 일반적인 명령어보다 훨씬 더 정밀한 접근이 요구돼요.
이 글에서는 실무 현장에서 운영자가 매일 마주하게 되는 상황을 중심으로 핵심 명령어들을 정리했어요. 단순히 명령어 리스트를 나열하는 것이 아니라, 어떤 상황에서 어떤 옵션을 써야 안전한지 실전 가이드를 제공할게요. 이 글을 다 읽고 나면 스테이트풀셋 운영에 대한 자신감을 얻으실 수 있어요.
- 스테이트풀셋 상태를 정확히 확인하고 모니터링하는 방법
- 안전하게 리소스를 생성하고 규모를 조절하는 실전 커맨드
- 업데이트와 롤링 업데이트 시 발생하는 이슈 대응법
- 로그와 실행 명령을 활용한 고난도 디버깅 기술
작업 시작 전 반드시 확인해야 할 기본 개념
스테이트풀셋 작업을 시작하기 전에 반드시 머릿속에 그려두어야 할 개념이 있어요. 바로 오디널리티(Ordinality)와 안정적인 네트워크 식별자예요. 일반적인 앱은 포드가 죽고 새로 살아나도 이름이 무작위로 바뀌지만, 스테이트풀셋은 반드시 0번부터 순서대로 이름이 부여되고 유지되어야 해요. 만약 이 순서가 깨지면 데이터베이스 클러스터의 합의 알고리즘이 망가질 수 있어요.
또한, 사용 중인 스토리지 클래스(StorageClass)와 영구 볼륨 클레임(PVC)의 관계도 명확히 이해해야 해요. 스테이트풀셋을 삭제한다고 해서 연결된 데이터(PVC)가 자동으로 사라지지 않는 이유는 데이터 보호를 위한 설계 때문이에요. 이 메커니즘을 모르면 리소스 정리 과정에서 혼란을 겪기 쉬워요.
디플로이먼트와 스테이트풀셋 비교
두 리소스의 차이점을 명확히 아는 것이 실수를 줄이는 첫걸음이에요. 아래 표를 통해 운영 관점에서 무엇이 다른지 확인해 보세요.
| 구분 항목 | 디플로이먼트(Deployment) | 스테이트풀셋(StatefulSet) |
|---|---|---|
| 포드 식별자 | 무작위 해시값 (예: app-abc12) | 순차적 번호 (예: db-0, db-1) |
| 데이터 보존 | 포드와 함께 소멸 가능성 높음 | 고유 PVC와 1:1 매핑 유지 |
| 배포 방식 | 병렬 또는 무작위 배포 | 순차적 생성 및 삭제 (0번부터) |
| 주요 용도 | 웹 서버, API 서버 등 무상태 앱 | DB, Kafka, Zookeeper 등 상태 저장 앱 |
스테이트풀셋은 포드가 하나씩 생성되고 하나씩 삭제되는 과정을 거쳐요. 이는 데이터 정합성을 보장하기 위한 안전장치이지만, 배포 속도가 디플로이먼트보다 느릴 수 있다는 점을 고려해야 해요.
명령어를 실행하기 전에 현재 클러스터의 권한(RBAC)이 스테이트풀셋과 PVC를 모두 제어할 수 있는지 먼저 확인하는 습관을 들이는 것이 좋아요. 권한이 부족하면 명령어는 성공한 것처럼 보여도 실제 백엔드 작업은 실패하는 경우가 발생할 수 있기 때문이에요.
스테이트풀셋 운영을 위한 실전 kubectl 명령어 가이드
이제 본격적으로 실무에서 바로 사용할 수 있는 명령어들을 단계별로 살펴볼게요. 모든 명령어는 운영 환경의 안정성을 최우선으로 고려하여 구성했어요.
STEP 1. 상태 조회 및 모니터링 명령어
가장 먼저 수행해야 할 작업은 현재 스테이트풀셋이 어떤 상태인지, 포드들이 정상적으로 배치되었는지 확인하는 것이에요. 단순히 목록을 보는 것 이상의 정보가 필요해요.
kubectl get statefulset: 현재 네임스페이스에 있는 스테이트풀셋의 목록과 준비된 포드 수를 확인해요.kubectl get sts -o wide: 각 스테이트풀셋이 어떤 노드에 배치되었는지 더 자세한 정보를 얻을 때 유용해요.kubectl describe sts [이름]: 가장 중요한 명령어예요. 스테이트풀셋의 설정값뿐만 아니라, 이벤트(Events) 섹션을 통해 왜 포드가 생성되지 않는지, 왜 스케일링이 멈췄는지 원인을 파악할 수 있어요.kubectl get pods -l app=[라벨]: 스테이트풀셋에 속한 특정 포드들만 필터링해서 볼 때 사용해요.
운영 중에 실시간으로 상태 변화를 감시해야 한다면 -w(watch) 옵션을 꼭 붙여주세요. 포드가 순차적으로 올라오는 모습을 실시간으로 확인할 수 있어요.
STEP 2. 리소스 생성, 수정 및 스케일링
스테이트풀셋은 한 번 생성하면 설정을 변경할 때 매우 신중해야 해요. 잘못된 수정은 데이터 유실이나 클러스터 분절을 초래할 수 있거든요.
kubectl apply -f [파일명].yaml: 정의된 YAML 파일을 통해 스테이트풀셋을 생성하거나 변경 사항을 적용해요.kubectl scale sts [이름] --replicas=[숫자]: 클러스터의 규모를 조절해요. 예를 들어 DB 노드를 3개에서 5개로 늘릴 때 사용해요. 이때 주의할 점은 숫자를 줄일 때 가장 높은 번호의 포드부터 순차적으로 삭제된다는 점이에요.kubectl patch sts [이름] -p '{"spec":{"replicas":3}}': YAML 파일을 수정하기 번거로울 때 명령줄에서 빠르게 레플리카 수를 변경할 수 있어요.
스케일 다운(Replicas 감소) 시, 해당 포드가 사용하던 PVC는 삭제되지 않고 남아요. 이는 데이터 보호를 위한 것이지만, 비용 관리를 위해서는 수동으로 정리해줘야 한다는 사실을 잊지 마세요.
STEP 3. 업데이트 및 롤링 업데이트 제어
이미지 버전을 올리거나 설정을 변경할 때 사용하는 롤링 업데이트(Rolling Update)는 스테이트풀셋 운영의 꽃이에요. 한 번에 모든 포드가 죽지 않도록 순차적으로 교체하는 과정이죠.
kubectl rollout status sts [이름]: 현재 진행 중인 업데이트가 완료되었는지 실시간으로 체크해요.kubectl rollout pause sts [이름]: 업데이트 중에 문제가 발견되면 즉시 중단하고 싶을 때 사용해요.kubectl rollout resume sts [이름]: 일시 정지했던 업데이트를 다시 재개해요.kubectl rollout undo sts [이름]: 긴급 상황 시 필수 명령어예요. 업데이트 후 장애가 발생했다면 이전 버전으로 즉시 되돌릴 수 있어요.
STEP 4. 고난도 디버깅 및 로그 확인
포드가 CrashLoopBackOff 상태에 빠졌다면, 단순한 조회만으로는 부족해요. 직접 포드 내부로 들어가거나 로그를 파헤쳐야 해요.
kubectl logs [포드이름]: 포드 내 애플리케이션이 남긴 표준 출력 로그를 확인해요.kubectl logs [포드이름] -p: 포드가 재시작되었다면, 이전 컨테이너의 로그를 확인하는 옵션이에요. 왜 죽었는지 파악할 때 결정적인 단서가 돼요.kubectl exec -it [포드이름] -- /bin/bash: 포드 내부 쉘에 접속하여 네트워크 상태나 파일 시스템을 직접 점검해요.kubectl debug [포드이름] -it --image=[디버깅이미지]: 포드가 너무 망가져서 쉘 접속조차 안 될 때, 임시 컨테이너를 붙여서 분석하는 고급 기술이에요.
STEP 5. 실전 시나리오: 데이터베이스 이미지 업데이트하기
실무에서 가장 자주 발생하는 “새로운 DB 버전으로의 안전한 업데이트” 시나리오를 예로 들어볼게요.
- 먼저 현재 버전을 확인해요:
kubectl get sts my-db -o jsonpath='{.spec.template.spec.containers[0].image}' - YAML 파일에서 이미지 태그를 수정하고 적용해요:
kubectl apply -f my-db-updated.yaml - 업데이트 진행 상황을 실시간 모니터링해요:
kubectl rollout status sts my-db - 만약 0번 포드가 뜨지 않고 에러가 난다면? 즉시 롤백해요:
kubectl rollout undo sts my-db
이 과정을 통해 서비스 중단 시간을 최소화하면서도 안전하게 인프라를 개선할 수 있어요.
자주 하는 실수와 해결법 + FAQ
자주 하는 실수와 해결법
현장에서 엔지니어들이 가장 빈번하게 저지르는 실수들과 그 해결책을 정리했어요.
- ❌ 실수: 스테이트풀셋을 삭제했는데 데이터(PVC)가 그대로 남아있어 리소스가 낭비됨
👉 이유: 스테이트풀셋은 데이터 보호를 위해 PVC를 자동으로 삭제하지 않도록 설계되었어요.
✅ 해결법: 삭제 후kubectl delete pvc -l app=[라벨]명령어를 사용하여 연결된 볼륨들을 수동으로 정리해줘야 해요. - ❌ 실수: 스케일 다운 시 데이터 유실이 걱정됨
👉 이유: 스테이트풀셋은 포드 번호가 큰 것부터 지우지만, 볼륨은 남겨두기 때문에 데이터 자체는 안전해요.
✅ 해결법: 다만, 애플리케이션 레벨에서 데이터 재분산(Rebalancing)이 필요한 경우(예: Kafka) 반드시 애플리케이션 명령어로 먼저 처리한 뒤 kubectl로 스케일링을 진행하세요. - ❌ 실수: 업데이트 중 포드가 무한 루프에 빠짐
👉 이유: 잘못된 설정값이 포함된 YAML을 적용했기 때문이에요.
✅ 해결법:kubectl rollout undo명령어로 즉시 이전 상태로 복구하는 것이 최선이에요. - ❌ 실수: 포드 이름이 바뀌어서 서비스가 끊김
👉 이유: 스테이트풀셋이 아닌 디플로이먼트를 사용했거나, 헤드리스 서비스(Headless Service) 설정이 누락되었을 가능성이 커요.
✅ 해결법: 스테이트풀셋 전용 서비스가 정의되어 있는지, 그리고 포드가 고유한 도메인 이름을 갖는지 확인하세요. - ❌ 실수: 스토리지 용량을 늘렸는데 포드에 반영이 안 됨
👉 이유: PVC 크기 수정 후 파일 시스템 확장이 자동으로 이루어지지 않는 경우가 있어요.
✅ 해결법: 사용 중인 StorageClass가 allowVolumeExpansion 옵션을 지원하는지 확인하고, 필요시 포드를 재시작하거나 직접 명령어로 마운트된 볼륨을 확장해야 해요.
자주 묻는 질문
Q. 스테이트풀셋 포드가 계속 Pending 상태로 있어요. 어떻게 하나요?
가장 먼저 kubectl describe pod [포드이름]을 실행해 보세요. 대부분의 경우 스토리지 클래스에서 볼륨을 할당하지 못했거나, 요청한 용량만큼의 노드 자원이 부족한 경우가 많아요. 이벤트 로그의 마지막 부분을 확인하면 명확한 이유가 나와요.
Q. 스테이트풀셋 업데이트 방식을 바꿀 수 있나요?
네, 가능해요. YAML 설정의 spec.updateStrategy 필드를 수정하면 돼요. 기본값인 RollingUpdate 외에도, 모든 포드를 한꺼번에 교체하는 OnDelete 방식을 선택할 수 있어요. 하지만 운영 환경에서는 안전한 RollingUpdate를 강력히 권장해요.
Q. 포드 번호(0, 1, 2…)를 임의로 바꿀 수 있나요?
아니요, 스테이트풀셋이 관리하는 포드 이름은 자동 생성되는 것이라 직접 수정할 수 없어요. 만약 특정 번호의 포드만 교체하고 싶다면, 해당 포드를 삭제한 뒤 스테이트풀셋이 다시 동일한 번호로 생성하도록 유도해야 해요.
Q. PVC가 너무 많이 생성되어 비용이 걱정돼요.
스테이트풀셋은 안전을 위해 삭제 시 PVC를 남겨두는 것이 원칙이에요. 비용 절감이 중요하다면, 스테이트풀셋 삭제 후 kubectl get pvc로 남은 항목을 확인하고, 사용하지 않는 볼륨을 수동으로 삭제하는 프로세스를 자동화하는 것이 좋아요.
Q. 롤링 업데이트 중 포드가 너무 느리게 올라와요.
스테이트풀셋의 업데이트 속도는 각 포드가 ‘Running’과 ‘Ready’ 상태가 될 때까지 기다리는 방식이에요. 만약 데이터베이스 초기화 시간이 길다면, 업데이트 시간을 충분히 확보하거나 포드의 readinessProbe 설정을 최적화하여 정상 상태를 더 빨리 판단하게 해야 해요.
안정적인 운영을 위한 마지막 점검
스테이트풀셋은 강력하지만 그만큼 다루기 까다로운 리소스예요. 하지만 오늘 배운 명령어들을 손에 익힌다면, 어떤 긴급 상황에서도 침착하게 대응할 수 있을 거예요. 운영자의 실력은 장애가 발생했을 때 어떤 명령어를 가장 먼저 입력하느냐에서 갈린다는 점을 꼭 기억해 주세요.
- 상태 확인은
get보다describe를 통해 이벤트를 보는 것이 정확해요. - 스케일 다운 시 데이터 볼륨(PVC)은 자동으로 삭제되지 않으니 주의하세요.
- 업데이트 오류 시에는 주저하지 말고
rollout undo를 사용하세요. - 디버깅의 핵심은
logs -p를 통한 이전 컨테이너의 기록 확인이에요. - 모든 작업 전에는 반드시 현재 포드의 오디널리티(번호)를 확인하세요.
오늘 배운 내용을 바탕으로 지금 바로 스테이트풀셋 명령어를 연습해 보세요. 운영 환경에 적용하기 전, 반드시 격리된 스테이징(Staging) 환경에서 동일한 명령어를 실행하며 결과값을 확인하는 과정이 필요해요. 실습 환경에서 직접 적용해 보시고, 진행 중에 막히는 부분이 있거나 이해가 안 되는 명령어가 있다면 언제든지 댓글로 질문을 남겨 주세요. 함께 고민해 드릴게요!
다음 단계로 나아가고 싶다면, 스테이트풀셋의 기반이 되는 쿠버네티스 스테이트풀셋 기본 개념 글이나 클러스터의 안정성을 높이는 클러스터 구축 입문 글을 함께 읽어보시는 것을 추천드려요.