Infra & Network

[Kubernetes | Part 2] Redis on Kubernetes

hrbds 2026. 5. 3. 21:05

목차

  • WHY — 왜 Redis on K8s를 배우는가
  • StatefulSet vs Deployment
  • PersistentVolume / PersistentVolumeClaim
  • Helm — K8s 패키지 매니저
  • StatefulSet으로 Redis 구성
  • 데이터 영속성 확인
  • 전체 요약

1. WHY — 왜 Redis on K8s를 배우는가

실제 운영 환경에서는 K8s 위에서 Redis를 올려야 한다.

일반 Deployment로 Redis를 올리면 Redis Pod 재배포 시 데이터 유지 되지 않는 문제가 생긴다.

Deployment로 Redis 배포 시
├── Pod 재시작 시 데이터 날아감
├── Pod 이름이 랜덤하게 바뀜 (redis-75fd-hsk82)
└── Redis Cluster 구성이 깨짐
    (노드 이름이 바뀌면 클러스터 인식 불가)

Redis는 상태를 가진(Stateful) 앱이라 일반 Deployment가 아닌 → StatefulSet + PersistentVolume 구성 필요


2. StatefulSet vs Deployment

항목 Deployment StatefulSet
Pod 이름 랜덤 (nginx-75fd-hsk82) 고정 (redis-0, redis-1, redis-2)
Pod 생성 순서 동시에 생성 순서대로 생성 (0 → 1 → 2)
데이터 삭제 시 소멸 PV로 영구 보존
스토리지 공유 또는 임시 Pod마다 개별 PVC 자동 생성
용도 무상태 앱 (Spring Boot, Vue.js, Nginx 등) 상태 앱 (Redis, MySQL, Kafka)

Pod 생성 순서

StatefulSet은 순서를 보장한다.

redis-0 Running 확인
    │
    ▼
redis-1 생성 시작
    │
    ▼
redis-1 Running 확인
    │
    ▼
redis-2 생성 시작

Redis Cluster에서 노드가 순서 없이 뜨면 클러스터 구성이 꼬일 수 있어서 순서 보장이 중요하다.


3. PersistentVolume / PersistentVolumeClaim

개념

PersistentVolume (PV)
→ 실제 스토리지 (디스크)
→ 클러스터 관리자가 미리 생성하거나 동적으로 생성

PersistentVolumeClaim (PVC)
→ Pod가 PV를 요청하는 티켓
→ "나 100Mi짜리 스토리지 필요해"라고 K8s에 요청
→ K8s가 조건에 맞는 PV를 찾아서 연결

StatefulSet에서 PVC 동작

volumeClaimTemplates 설정 시
├── redis-0 생성 → redis-data-redis-0 (PVC) 자동 생성 → PV 연결
├── redis-1 생성 → redis-data-redis-1 (PVC) 자동 생성 → PV 연결
└── redis-2 생성 → redis-data-redis-2 (PVC) 자동 생성 → PV 연결

각 Pod가 자기만의 독립된 스토리지를 가진다. Redis 노드마다 데이터가 분리되어야 하기 때문이다.

Pod 재시작 시 PVC 재연결

redis-0 (Pod) 삭제
    │
    ▼
redis-data-redis-0 (PVC) → 유지 (Pod와 독립적으로 존재)
    │
    ▼
redis-0 (Pod) 재생성 → 같은 PVC 재연결 → 데이터 그대로

 

4. StatefulSet으로 Redis 구성

yaml 파일 작성

# redis-statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet          # Deployment 대신 StatefulSet 사용
metadata:
  name: redis
spec:
  serviceName: redis       # Headless Service 이름 (Pod DNS 생성에 필요)
                           # redis-0.redis, redis-1.redis 형태로 접근 가능
  replicas: 3              # Pod 3개 (순서대로 생성)
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
      - name: redis
        image: redis:7.2
        ports:
        - containerPort: 6379
        volumeMounts:
        - name: redis-data
          mountPath: /data   # 컨테이너 내부 /data 경로에 볼륨 마운트
                             # Redis 데이터 저장 경로

  volumeClaimTemplates:      # Pod마다 개별 PVC 자동 생성 (StatefulSet 핵심)
  - metadata:
      name: redis-data
    spec:
      accessModes: ["ReadWriteOnce"]  # 하나의 Node에서만 읽기/쓰기
      resources:
        requests:
          storage: 100Mi     # 각 Pod마다 100MB PV 요청

 

Deployment와 핵심 차이

# Deployment
# volumeClaimTemplates 없음
# 모든 Pod가 같은 Volume 공유 또는 임시 Volume 사용

# StatefulSet
volumeClaimTemplates:
- metadata:
    name: redis-data       # 이 이름 + Pod 이름으로 PVC 자동 생성
                           # redis-data-redis-0
                           # redis-data-redis-1
                           # redis-data-redis-2

배포

kubectl apply -f redis-statefulset.yaml
kubectl get pods

NAME      READY   STATUS    RESTARTS   AGE
redis-0   1/1     Running   0          95s   ← 먼저 생성
redis-1   1/1     Running   0          85s   ← 다음
redis-2   1/1     Running   0          84s   ← 마지막

PVC / PV 확인

kubectl get pvc

NAME                 STATUS   VOLUME                  CAPACITY   ACCESS MODES
redis-data-redis-0   Bound    pvc-79146dad-...         100Mi      RWO
redis-data-redis-1   Bound    pvc-d8ce2d9c-...         100Mi      RWO
redis-data-redis-2   Bound    pvc-d13806cf-...         100Mi      RWO
kubectl get pv

NAME                    CAPACITY   RECLAIM POLICY   STATUS   CLAIM
pvc-79146dad-...        100Mi      Delete           Bound    redis-data-redis-0
pvc-d8ce2d9c-...        100Mi      Delete           Bound    redis-data-redis-1
pvc-d13806cf-...        100Mi      Delete           Bound    redis-data-redis-2

각 Redis Pod마다 독립된 PVC → PV가 자동으로 생성됐다.


5. 데이터 영속성 확인

데이터 저장

kubectl exec -it redis-0 -- redis-cli set ari:card:1 "legendary"
# OK

kubectl exec -it redis-0 -- redis-cli get ari:card:1
# "legendary"

Pod 강제 삭제 후 데이터 유지 확인

kubectl delete pod redis-0
# pod "redis-0" deleted

kubectl get pods
# NAME      READY   STATUS    RESTARTS   AGE
# redis-0   1/1     Running   0          4s    ← 자동 복구, 이름 고정
# redis-1   1/1     Running   0          5m24s
# redis-2   1/1     Running   0          5m23s

 

Deployment와 차이

 

Deployment  → 삭제 후 nginx-75fd-abc12 (랜덤 이름)
StatefulSet → 삭제 후 redis-0 (고정 이름) ✅
kubectl exec -it redis-0 -- redis-cli get ari:card:1
# "legendary" ← 데이터 그대로 유지 ✅

Pod가 삭제되고 재생성됐는데도 데이터가 살아있다. PVC가 Pod와 독립적으로 존재하기 때문이다.


6. 전체 요약

Redis on K8s 핵심 원칙
├── StatefulSet: 상태 앱 배포 표준
│   ├── Pod 이름 고정 (redis-0, redis-1, redis-2)
│   ├── 순서대로 생성/삭제
│   └── Pod 재시작 시 같은 이름으로 복구
├── volumeClaimTemplates: Pod마다 개별 PVC 자동 생성
│   ├── redis-data-redis-0 (redis-0 전용)
│   ├── redis-data-redis-1 (redis-1 전용)
│   └── redis-data-redis-2 (redis-2 전용)
├── PVC는 Pod 삭제 시 유지 → 데이터 영속성 보장
└── Helm uninstall 후 PVC는 수동 삭제 필요

앱별 K8s 배포 방식
├── Stateless (Spring Boot, Vue.js, Nginx) → Deployment
└── Stateful (Redis, MySQL, Kafka)         → StatefulSet