
이번 1.3단계에서는 RedisShake는 잠시 빼고, 먼저 온프레미스 K8s 안에서 Redis Cluster 6개 Pod가 실제로 어떻게 만들어지고 연결되는지를 잡겠습니다. 이 구조를 이해하면 다음 단계에서 RedisShake가 어느 주소로 접속해야 하는지가 자연스럽게 보입니다.
🟥 1.3단계 - K8s Redis Cluster 구성 이해하기
현재 예시는 가장 흔한 구조로 잡겠습니다.
Redis Cluster
= 3 Master + 3 Replica
= Redis Pod 6개
redis-0
redis-1
redis-2
redis-3
redis-4
redis-5
그리고 Kubernetes에서는 이 Redis들을 다음 구성요소가 받쳐줍니다.
StatefulSet
│
├─ redis-0 ─ PVC-0
├─ redis-1 ─ PVC-1
├─ redis-2 ─ PVC-2
├─ redis-3 ─ PVC-3
├─ redis-4 ─ PVC-4
└─ redis-5 ─ PVC-5
│
│
Headless Service
│
│ Pod별 DNS
▼
Redis Cluster 내부 통신
그리고 별도로
Application
│
▼
일반 Service
│
▼
Redis Cluster
이게 오늘 배울 전체 그림입니다.
1.3.1 먼저 StatefulSet이 왜 필요한가?
Redis Cluster를 그냥 Deployment로 만들 수도 있을 것 같지만, Redis 같은 Stateful 애플리케이션은 일반적으로 StatefulSet이 적합합니다.
왜냐하면 Redis Cluster 노드는 각각 자기 정체성을 유지해야 하기 때문입니다.
Deployment라면 Pod 이름이 이런 식일 수 있습니다.
redis-7c97bc4f5f-x7k2q
redis-7c97bc4f5f-abc91
redis-7c97bc4f5f-z3h51
Pod가 재생성되면 이름이 달라질 수 있습니다.
반면 StatefulSet은:
redis-0
redis-1
redis-2
redis-3
redis-4
redis-5
처럼 고정된 순번을 유지합니다.
Pod가 장애로 재생성되어도:
redis-2
↓ 장애
새 Pod 생성
↓
redis-2
라는 이름을 그대로 유지합니다.
아주 쉽게
Deployment
= "아무 직원 6명"
StatefulSet
= "1번 직원, 2번 직원, 3번 직원..."
Redis Cluster에서는 후자가 훨씬 중요합니다.
1.3.2 StatefulSet과 Pod 관계
예를 들어 StatefulSet을:
replicas: 6
으로 만들었다고 합시다.
그러면:
StatefulSet: redis
│
├── redis-0
├── redis-1
├── redis-2
├── redis-3
├── redis-4
└── redis-5
6개의 Redis Pod가 만들어집니다.
중요한 점은:
StatefulSet이 Redis Cluster 자체를 만들어 주는 것은 아닙니다.
StatefulSet은 기본적으로:
Pod 6개 생성
Pod 이름 유지
PVC 연결
순차적인 생성/종료 관리
를 담당합니다.
Redis 자체에서:
누가 Master인가?
누가 Replica인가?
누가 어느 Slot을 담당하는가?
는 Redis Cluster가 결정합니다.
1.3.3 예를 들어 역할은 이렇게 될 수 있다
redis-0 = Master
redis-1 = Master
redis-2 = Master
redis-3 = Replica of redis-0
redis-4 = Replica of redis-1
redis-5 = Replica of redis-2
그래서 논리적으로:
Redis Cluster
Shard 1 Shard 2 Shard 3
redis-0 redis-1 redis-2
Master Master Master
│ │ │
│ │ │
▼ ▼ ▼
redis-3 redis-4 redis-5
Replica Replica Replica
라고 볼 수 있습니다.
다만 실제 운영에서 Pod 번호 자체가 Master 역할을 영구적으로 의미하는 것은 아닙니다.
예를 들어 장애가 발생하면:
redis-0 Master ❌
redis-3 Replica
↓
Master 승격
이 가능합니다.
따라서:
redis-0 = 무조건 Master
라고 기억하면 안 됩니다.
1.3.4 PVC는 왜 Redis Pod마다 하나씩 필요한가?
Redis는 메모리 DB지만 데이터를 디스크에도 저장할 수 있습니다.
대표적으로:
RDB
AOF
가 있습니다.
K8s Pod의 로컬 파일시스템만 사용하면:
redis-0
│
└─ /data
Pod 삭제
↓
데이터도 사라질 가능성
이 있습니다.
그래서 PVC를 연결합니다.
redis-0
│
▼
PVC redis-data-redis-0
│
▼
실제 Storage
1.3.5 Redis Pod 6개가 PVC 하나를 공유하면 안 되나?
Redis Cluster에서는 일반적으로 공유하면 안 됩니다.
예:
PVC 하나
▲
┌───────┼───────┐
│ │ │
redis-0 redis-1 redis-2
❌
이런 개념이 아닙니다.
각 Redis 인스턴스는 자기 데이터 파일을 별도로 관리합니다.
redis-0 ─→ PVC-0
redis-1 ─→ PVC-1
redis-2 ─→ PVC-2
redis-3 ─→ PVC-3
redis-4 ─→ PVC-4
redis-5 ─→ PVC-5
왜?
Master 1과 Master 2는 서로 다른 데이터를 가지고 있기 때문입니다.
redis-0
Slot 0~5460
redis-1
Slot 5461~10922
그리고 Replica도 자신의 Redis 데이터 파일을 별도로 보관합니다.
따라서:
Redis Cluster 복제는 PVC 공유가 아니라 Redis 네트워크 Replication입니다.
이 부분이 굉장히 중요합니다.
1.3.6 전체 PVC 구조
StatefulSet
│
┌────────────┼────────────┐
│ │ │
redis-0 redis-1 redis-2
Master Master Master
│ │ │
▼ ▼ ▼
PVC-0 PVC-1 PVC-2
redis-3 redis-4 redis-5
Replica Replica Replica
│ │ │
▼ ▼ ▼
PVC-3 PVC-4 PVC-5
즉:
Pod 6개
→ PVC 6개
가 기본적인 형태입니다.
1.3.7 PVC 뒤에는 실제 스토리지가 있다
PVC 자체가 디스크는 아닙니다.
Kubernetes에서는:
Redis Pod
↓
PVC
↓
PV
↓
StorageClass
↓
실제 Storage
구조입니다.
온프레미스라면 실제 Storage는 예를 들어:
SAN
Ceph
NFS
Local NVMe
CSI 기반 Storage
등이 될 수 있습니다.
Redis Cluster에서는 일반적으로 낮은 지연시간이 중요하므로 스토리지 성능도 중요합니다.
1.3.8 이제 Headless Service가 등장한다 ⭐
Redis Cluster에서는 Redis Pod들이 서로를 직접 알아야 합니다.
예:
redis-0
↕
redis-1
↕
redis-2
이때 Pod IP를 직접 사용하면 문제가 있습니다.
redis-0
현재 IP
10.244.1.10
Pod 재생성
새 IP
10.244.5.21
IP가 바뀔 수 있습니다.
그래서 고정된 DNS 이름이 필요합니다.
여기서 Headless Service를 사용합니다.
1.3.9 일반 Service와 Headless Service의 가장 큰 차이
일반 Service에는 ClusterIP가 있습니다.
Application
│
▼
redis-service
ClusterIP: 10.96.10.20
│
▼
Redis Pod
반면 Headless Service는:
clusterIP: None
입니다.
즉 중간에 대표 IP를 하나 제공하는 목적이 아니라 Pod 각각의 DNS를 제공하는 것이 핵심입니다.
1.3.10 Headless Service를 사용하면 Pod별 DNS가 생긴다
예를 들어:
StatefulSet 이름
redis
Headless Service 이름
redis-headless
Namespace
redis
라고 해보겠습니다.
그러면 개념적으로 각 Pod를:
redis-0.redis-headless.redis.svc.cluster.local
redis-1.redis-headless.redis.svc.cluster.local
redis-2.redis-headless.redis.svc.cluster.local
redis-3.redis-headless.redis.svc.cluster.local
redis-4.redis-headless.redis.svc.cluster.local
redis-5.redis-headless.redis.svc.cluster.local
처럼 찾을 수 있습니다.
이것이 상당히 중요합니다.
Pod IP가:
10.244.1.20 → 10.244.6.31
로 변경되더라도:
redis-0.redis-headless.redis.svc.cluster.local
이라는 DNS 이름은 유지됩니다.
1.3.11 일반 Service는 왜 또 필요한가?
여기서 이런 의문이 생깁니다.
"Headless Service가 있는데 일반 Service는 왜 필요하지?"
역할이 다르기 때문입니다.
Headless Service
주로:
Redis Pod ↔ Redis Pod
처럼 각 Redis Node를 구분해서 접근할 때 유용합니다.
일반 Service
주로:
Application → Redis
에서 안정적인 대표 Endpoint가 필요할 때 사용합니다.
그림으로 보면:
Application
│
▼
일반 Service
│
▼
Redis Cluster
Redis Cluster 내부
redis-0 ←──────→ redis-1
↕ ↕
redis-3 redis-4
↖ ↗
Headless Service
Pod별 DNS 제공
1.3.12 그런데 Redis Cluster는 일반 Service 하나만 쓰면 되는가?
여기서는 약간 주의해야 합니다.
Redis Cluster는 단순 웹 서버처럼:
Service → 아무 Redis Pod
에 보내기만 하면 끝나는 구조가 아닙니다.
왜냐하면 Key마다 담당 Master가 다르기 때문입니다.
예:
user:100
↓
Slot 2000
↓
redis-0
product:200
↓
Slot 7000
↓
redis-1
Redis Cluster를 사용하는 Client는 보통 Cluster-aware Client여야 합니다.
처음 한 노드에 접속한 후:
"이 Key는 다른 노드 담당이다"
라는 정보를 받아 다른 Redis 노드로 이동합니다.
즉:
Application
│
▼
Redis Cluster Endpoint
│
▼
redis-0
│
├─ Slot A → 여기 처리
│
└─ Slot B → redis-1로 Redirect
같은 구조입니다.
1.3.13 MOVED Redirect란?
Cluster에서 중요한 개념입니다.
애플리케이션이 redis-0에:
GET product:500
을 보냈다고 합시다.
그런데 그 Key의 Slot은 redis-1 담당입니다.
redis-0은:
"그 Key는 내가 담당하지 않는다.
redis-1로 가라."
라고 응답합니다.
이게 대표적인 MOVED Redirect입니다.
Cluster-aware Redis Client가 이 정보를 이해해서:
Application
│
├── redis-0
│
└── redis-1
로 직접 접속합니다.
그래서 Cluster 구조에서는 Redis Node 각각에 접근 가능해야 하는 것입니다.
이 원리가 RedisShake에도 그대로 연결됩니다.
1.3.14 지금까지 전체 연결 그림
이제 모든 것을 합쳐보겠습니다.
On-Premises Kubernetes
┌──────────────────────────────────────────────────────────┐
│ │
│ Application │
│ │ │
│ ▼ │
│ 일반 Redis Service │
│ │ │
│ ▼ │
│ Redis Cluster Endpoint │
│ │
│ ┌────────────────────────────────────────────┐ │
│ │ StatefulSet: redis │ │
│ │ │ │
│ │ Shard 1 Shard 2 Shard 3 │ │
│ │ │ │
│ │ redis-0 redis-1 redis-2 │ │
│ │ Master Master Master │ │
│ │ │ │ │ │ │
│ │ ▼ ▼ ▼ │ │
│ │ redis-3 redis-4 redis-5 │ │
│ │ Replica Replica Replica │ │
│ │ │ │
│ └────────────────────────────────────────────┘ │
│ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ PVC PVC PVC │
│ │ │ │ │
│ └──── Storage ──┘ │
│ │
│ Headless Service │
│ │ │
│ Pod별 고정 DNS 제공 │
│ │
│ redis-0.redis-headless.redis.svc.cluster.local │
│ redis-1.redis-headless.redis.svc.cluster.local │
│ ... │
│ redis-5.redis-headless.redis.svc.cluster.local │
│ │
└──────────────────────────────────────────────────────────┘
1.3.15 StatefulSet YAML에서는 어떻게 연결되는가?
개념적으로 StatefulSet에는 이런 설정이 있습니다.
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: redis
spec:
serviceName: redis-headless
replicas: 6
여기서:
serviceName: redis-headless
가 중요합니다.
StatefulSet이 Headless Service와 연결되어 각 Pod의 안정적인 네트워크 이름을 만들 수 있습니다.
그리고 아래에는:
volumeClaimTemplates:
가 존재할 수 있습니다.
개념적으로:
volumeClaimTemplates:
- metadata:
name: redis-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Gi
라고 되어 있다면 Pod마다 PVC가 생성됩니다.
redis-data-redis-0
redis-data-redis-1
redis-data-redis-2
redis-data-redis-3
redis-data-redis-4
redis-data-redis-5
1.3.16 Headless Service YAML은 아주 단순하다
핵심은:
apiVersion: v1
kind: Service
metadata:
name: redis-headless
spec:
clusterIP: None
입니다.
그리고 selector를 통해 Redis Pod를 찾습니다.
selector:
app: redis
즉:
Headless Service
│
├─ redis-0
├─ redis-1
├─ redis-2
├─ redis-3
├─ redis-4
└─ redis-5
입니다.
1.3.17 일반 Service는 이런 모양
예를 들어:
apiVersion: v1
kind: Service
metadata:
name: redis-cluster
spec:
selector:
app: redis
ports:
- port: 6379
그러면:
redis-cluster.redis.svc.cluster.local:6379
같은 대표 Endpoint가 생깁니다.
다만 앞서 설명한 것처럼 Redis Cluster에서는 Service 하나만 열어놓고 나머지 Pod 직접 접근을 막으면 문제가 생길 수 있습니다.
Cluster-aware Client와 RedisShake가 Cluster topology에 있는 Redis Node에 접근할 수 있어야 합니다.
1.3.18 RedisShake와 연결하면 어디를 보는가? ⭐
이제 RedisShake를 살짝 붙여보겠습니다.
처음 RedisShake가:
redis-cluster.redis.svc.cluster.local:6379
같은 초기 Endpoint에 접속할 수 있습니다.
그리고 Redis Cluster 정보를 확인합니다.
RedisShake
│
▼
redis-cluster Service
│
▼
redis-0
CLUSTER NODES
│
▼
redis-0
redis-1
redis-2
...
그 다음 RedisShake는 각 Master에 실제로 연결할 수 있어야 합니다.
RedisShake
/ | \
/ | \
▼ ▼ ▼
redis-0 redis-1 redis-2
Master Master Master
그래서 Headless Service와 Pod별 DNS 설계가 RedisShake에서도 매우 중요해집니다.
1.3.19 특히 서로 다른 K8s Cluster라면 문제가 커진다
같은 K8s Cluster 내부라면:
redis-0.redis-headless.redis.svc.cluster.local
주소를 RedisShake Pod가 사용할 수 있습니다.
하지만 RedisShake가 다른 Kubernetes Cluster에 있다면:
K8s Cluster A
redis-0.redis-headless.redis.svc.cluster.local
주소는 보통 Cluster B에서 해석할 수 없습니다.
Cluster B RedisShake
│
X
│
Cluster A 내부 DNS
그래서 이후 DR/다른 클러스터 구성에서는:
DNS
L4 VIP
LoadBalancer
NodePort
Routing
Redis cluster-announce-ip/hostname
문제가 굉장히 중요해집니다.
이건 RedisShake 네트워크 단계에서 별도로 깊게 다루겠습니다.
1.3.20 각 구성요소 역할을 한 번에 정리
| StatefulSet | Redis Pod를 안정적으로 생성/관리 | 아파트 관리사무소 |
| redis-0~5 | 실제 Redis 프로세스 | 각 세대 |
| PVC | 각 Redis의 영구 데이터 저장 | 개인 창고 |
| Headless Service | Pod별 고정 DNS 제공 | 각 세대 전화번호 |
| 일반 Service | 대표 접속 Endpoint | 아파트 대표번호 |
| Redis Cluster | Master/Replica/Slot 관리 | 전체 아파트 조직 |
| RedisShake | Source → Target 데이터 이전 | 이사업체 |
이 비유로 보면 상당히 쉽습니다.
아파트 관리사무소
StatefulSet
│
101호 = redis-0 ─ 개인창고 PVC-0
102호 = redis-1 ─ 개인창고 PVC-1
103호 = redis-2 ─ 개인창고 PVC-2
...
각 세대 번호
= Headless Service DNS
대표 안내번호
= 일반 Service
이사업체
= RedisShake
🎯 1.3단계에서 꼭 기억할 6가지
① StatefulSet은 Redis Pod의 안정적인 이름을 보장합니다.
redis-0 ~ redis-5
② 6개 Redis Pod라면 일반적으로 각각 별도의 PVC를 가집니다.
Pod 6개 → PVC 6개
③ PVC 공유가 Redis Replication은 아닙니다.
Master → Network Replication → Replica
입니다.
④ Headless Service는 대표 IP보다 Pod별 DNS가 핵심입니다.
redis-0.redis-headless...
redis-1.redis-headless...
⑤ 일반 Service는 Client가 Redis에 들어가는 대표 Endpoint 역할을 할 수 있습니다.
⑥ Redis Cluster에서는 Client와 RedisShake가 결국 각 Cluster Node와 통신할 수 있어야 합니다.
🔜 다음 1.4단계가 중요한 이유
다음에는 실제 K8s 네트워크 흐름을 보겠습니다.
Application Pod
↓
일반 Service
↓
Redis Master
↓ MOVED
다른 Redis Master
그리고
RedisShake Pod
↓
Service
↓
CLUSTER NODES
↓
Headless Service / Pod DNS
↓
각 Master 직접 연결
여기서 ClusterIP / Headless Service / Endpoint / DNS / Pod IP가 각각 무엇인지를 실제 kubectl get svc, kubectl get endpoints, nslookup 예제까지 붙여 설명하면 RedisShake 연결 구조가 거의 완성됩니다.
'J-H-T > Redis' 카테고리의 다른 글
| [REDIS-4단계] sync_reader / scan_reader / rdb_reader 차이! (0) | 2026.08.16 |
|---|---|
| [REDIS-3단계] Full Sync와 Incremental Sync 원리! (0) | 2026.08.15 |
| [REDIS-2단계] Source / Target / RedisShake 구성 이해! (0) | 2026.08.15 |
| [REDIS-1.4단계] K8s Redis Cluster 네트워크 흐름 이해하기! (0) | 2026.08.15 |
| [REDIS-1.2단계] Redis Cluster 구조 이해하기! (0) | 2026.08.15 |
| [REDIS-1.1단계] Redis 구조별 RedisShake 차이 이해하기! (0) | 2026.08.14 |
| [REDIS - 1단계] RedisShake가 무엇이고 K8s에서 어디에 위치하는가 ! (0) | 2026.08.14 |
| [참고] Kubernetes에서 Redis Cluster 구성 이해하기 🚀 (0) | 2026.08.13 |
댓글