본문 바로가기
J-H-T/Redis

[REDIS-1.3단계] K8s Redis Cluster 구성 이해하기!

by METAVERSE STORY 2026. 8. 15.
반응형

 

 

이번 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 연결 구조가 거의 완성됩니다.

 

 

반응형

댓글