88. 스테이트풀셋 (StatefulSet) - 상태 저장 워크로드
⚠️ 이 문서는 아무 때나 죽이고 새로 찍어내면 되는 웹 서버(Stateless)와 달리, 데이터베이스(MySQL)나 메시지 큐(Kafka)처럼 파드(Pod) 하나하나가 각자의 영혼(순서 ID)과 고유한 디스크(Volume)를 반드시 기억하고 영원히 유지해야 하는 '상태 유지형(Stateful)' 애플리케이션을 쿠버네티스에 배포할 때 사용하는 컨트롤러를 다룹니다.
핵심 인사이트 (3줄 요약)
- 본질: 쿠버네티스 디플로이먼트(Deployment)의 일회성, 소모품(Cattle) 철학을 완전히 뒤집어, 파드 하나하나에 이름을 붙여주고 평생 아껴 키우는 반려동물(Pet) 철학의 컨트롤러다.
- 가치: 마스터 DB가 죽었을 때 쿠버네티스가 엉뚱한 빈 파드를 살려내어 데이터가 몽땅 날아가는 참사를 막고, 새로 살아난 파드가 자신이 과거에 쓰던 디스크(데이터)와 자신의 고유 번호(예:
mysql-0)를 정확히 다시 찾아가도록 운명적인 결합을 보장한다.- 기술 체계: 이름에 붙는 고유한 순서 인덱스(-0, -1, -2), DNS를 통한 고정된 네트워크 식별자(Headless Service), 그리고 파드가 죽어도 절대 지워지지 않고 다음 생에 다시 연결되는 **영구 볼륨(PVC, PersistentVolumeClaim)**이 3대 핵심 무기다.
Ⅰ. 디플로이먼트(Deployment)로 DB를 띄울 때의 재앙
무상태(Stateless)의 규칙을 상태 저장(Stateful) 시스템에 들이대면 박살이 난다.
- 무작위 이름과 기억 상실:
- 디플로이먼트로 MySQL을 3대(마스터 1, 슬레이브 2) 띄우면 이름이
mysql-ab34f,mysql-x9z2p같이 랜덤 해시값으로 찍힌다. - 만약 마스터인
ab34f가 죽으면, 쿠버네티스는 이를 버리고mysql-k8w1q라는 완전히 새로운 아기를 태어나게 한다. 이 아기는 자기가 예전에 마스터였는지 슬레이브였는지 전혀 기억하지 못한다.
- 디플로이먼트로 MySQL을 3대(마스터 1, 슬레이브 2) 띄우면 이름이
- 볼륨(디스크)의 분실:
- 새 파드가 떴을 때 과거 마스터가 쓰던 디스크(100GB짜리 고객 데이터)를 찾아야 하는데, 디플로이먼트 파드들은 공용 디스크 하나를 다 같이 쉐어하거나, 아예 휘발성 디스크를 써버려서 새 파드는 텅 빈 상태로 태어난다.
- 결론: 데이터베이스 3대끼리 "누가 마스터고 누가 1번 슬레이브인지" 서로 합의(Quorum)를 해야 하는데, 파드 이름과 IP가 매일 바뀌니 동기화가 완전히 박살 나버린다.
📢 섹션 요약 비유: 디플로이먼트가 기억 상실증에 걸린 복제 인간 3명을 찍어내어 공장(웹 서버)에서 매일 단순 노동을 시키는 것이라면, DB 서버는 매일 일기장을 쓰고 100만 원씩 빚을 갚아나가는 은행원입니다. 은행원이 죽었는데 어제 기억(데이터)이 전혀 없는 새 복제 인간을 앉혀놓으면 은행 장부가 완전히 파탄 나는 원리입니다.
Ⅱ. 스테이트풀셋의 3가지 마법: 영혼과 육체의 보존
반려동물(Pet)에게는 이름표와 자기만의 고유한 밥그릇을 주어야 한다.
- 고유한 순서 인덱스 (Ordered, Sticky Identity):
- 스테이트풀셋으로 MySQL 3대를 띄우면, 파드 이름이
mysql-0,mysql-1,mysql-2로 태어난다. - 만약
mysql-1이 죽으면, 쿠버네티스는 새 파드를 띄울 때 랜덤 이름이 아니라 반드시mysql-1이라는 이름 그대로 부활시킨다. (영원히 변하지 않는 이름표)
- 스테이트풀셋으로 MySQL 3대를 띄우면, 파드 이름이
- 고정된 네트워크 주소 (Headless Service):
- 일반 서비스(Load Balancer)는 3대 중 아무에게나 트래픽을 던지지만, DB는 "마스터(
mysql-0)에게는 Write를, 슬레이브(mysql-1)에게는 Read를 보내야 한다"는 명확한 구분이 필요하다. - 헤드리스 서비스를 통해
mysql-0.db.default.svc.cluster.local이라는 영원히 변하지 않는 호스트 주소(DNS)를 제공하여 파드 간의 정확한 통신을 보장한다.
- 일반 서비스(Load Balancer)는 3대 중 아무에게나 트래픽을 던지지만, DB는 "마스터(
- 영구 볼륨 클레임 (Volume Claim Template):
- 3대의 파드가 생성될 때, 1번부터 3번까지 각자 자기 전용 100GB짜리 디스크(PVC)를 1개씩 따로따로 창조해서 할당받는다. (1인 1밥그릇)
- 파드
mysql-1이 죽었다 살아나면, 쿠버네티스는 귀신같이 "과거의 mysql-1이 쓰던 그 2번 디스크"를 찾아내어 새 파드에 찰칵! 하고 연결해 준다. 데이터 유실이 0이 된다.
📢 섹션 요약 비유: 파드에 주민등록번호(mysql-0)를 부여하고, 그 번호에 맞는 전용 금고(볼륨)를 은행에 배정해 주는 것입니다. 그 파드가 죽었다 환생하더라도 전생의 주민등록번호를 그대로 들고 태어나기 때문에, 은행에 가서 "나 mysql-0 환생한 놈인데 내 금고 열어줘"라고 하면 100% 안전하게 전생의 돈(데이터)을 찾을 수 있는 기적의 환생 시스템입니다.
Ⅲ. 기동 및 종료의 엄격한 질서 (Sequential)
스테이트풀셋은 켤 때도, 끌 때도 무조건 순서를 지킨다.
- 순차적 생성 (Start-up Order):
- 디플로이먼트는 3개를 띄우면 3개가 동시에 우당탕 켜진다.
- 스테이트풀셋은
mysql-0이 완벽하게 켜져서 "준비 완료(Ready)"를 외치기 전까지는 절대mysql-1을 켜지 않는다. 마스터가 세팅된 후에야 슬레이브가 켜지면서 마스터에게 데이터를 동기화받을 수 있는 안전장치다.
- 역순의 종료 (Termination Order):
- 시스템을 끌 때는 반대로
mysql-2$\rightarrow$mysql-1$\rightarrow$mysql-0순서로 죽인다. 대장(마스터)은 맨 마지막까지 살아서 쫄병들이 안전하게 접속을 끊고 죽을 때까지 시스템을 지킨다.
- 시스템을 끌 때는 반대로
- 스테이트풀셋의 한계 (클라우드 네이티브 DB의 부상):
- 이렇게 완벽해 보이지만, 스토리지 성능이나 백업 복구 등의 문제로 인해 "쿠버네티스 위에는 아예 무거운 DB를 올리지 마라(K8s는 껍데기 서버용이다)"라는 회의론도 많다. 최근에는 쿠버네티스 외부에 AWS RDS 같은 완전 관리형 DB를 연동해 쓰는 것이 여전히 엔터프라이즈의 압도적 대세다.
📢 섹션 요약 비유: 회사 체육대회에서 디플로이먼트는 "선착순 3명 아무나 뛰어와!"라고 한다면, 스테이트풀셋은 "1번 부장님 착석 확인, 2번 과장님 착석 확인, 3번 대리 착석" 순서로 철저하게 의전을 차리는 깐깐한 관리자입니다. 하지만 이 깐깐함조차 관리하기 피곤해서, 요즘은 밥(DB)은 아예 외부의 5성급 뷔페(AWS RDS)에서 배달시켜 먹는 것을 선호하는 추세입니다.