docs: B-5 — the pod stays Ready while every request hangs
Stopping Redis returns HTTP 000 rather than an error because the client waits on reconnect, and the pod keeps serving traffic because the redis health indicator is not in the readiness group even though /actuator/health returns 503. That is the mirror image of A-2, where Keycloak put its database check in readiness and the pods left the Service. Turning on AOF with config set created the appendonlydir and still lost everything on pod deletion, because /data was the container filesystem; adding a PVC makes the same setting work. Volume first, persistence setting second. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
7dc0a3e5da
commit
f45a2a2aaa
@@ -24,9 +24,24 @@ stringData:
|
|||||||
# Base64 in etcd is not encryption — see D-3.
|
# Base64 in etcd is not encryption — see D-3.
|
||||||
KEYCLOAK_CLIENT_SECRET: bff-lab-secret
|
KEYCLOAK_CLIENT_SECRET: bff-lab-secret
|
||||||
---
|
---
|
||||||
# Redis. No persistence yet: `--save ""` and no appendonly, so a restart loses
|
# Redis. B-5 measured that turning on AOF with `redis-cli config set` changes
|
||||||
# everything. B-5 and B-6 compare that against RDB and AOF, which is easier to
|
# nothing here, because /data is the container filesystem and dies with the
|
||||||
# reason about when the starting point is "nothing survives".
|
# container — the appendonlydir was created and then thrown away. Persistence
|
||||||
|
# configuration without a volume is decoration.
|
||||||
|
#
|
||||||
|
# So the volume comes first, and only then does `--appendonly yes` mean anything.
|
||||||
|
apiVersion: v1
|
||||||
|
kind: PersistentVolumeClaim
|
||||||
|
metadata:
|
||||||
|
name: redis-data
|
||||||
|
namespace: keycloak-lab
|
||||||
|
spec:
|
||||||
|
accessModes: [ReadWriteOnce]
|
||||||
|
storageClassName: local-path
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
storage: 1Gi
|
||||||
|
---
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
@@ -47,16 +62,25 @@ spec:
|
|||||||
containers:
|
containers:
|
||||||
- name: redis
|
- name: redis
|
||||||
image: redis:7.4-alpine
|
image: redis:7.4-alpine
|
||||||
args: ["redis-server", "--save", "", "--appendonly", "no"]
|
# appendfsync everysec 이 기본값이다 — 1초 분량을 잃을 수 있다.
|
||||||
|
# Keycloak 의 synchronous_commit OFF(A-3)와 같은 모양의 트레이드오프다.
|
||||||
|
args: ["redis-server", "--appendonly", "yes", "--dir", "/data"]
|
||||||
ports:
|
ports:
|
||||||
- containerPort: 6379
|
- containerPort: 6379
|
||||||
name: redis
|
name: redis
|
||||||
readinessProbe:
|
readinessProbe:
|
||||||
exec: { command: ["redis-cli", "ping"] }
|
exec: { command: ["redis-cli", "ping"] }
|
||||||
initialDelaySeconds: 3
|
initialDelaySeconds: 3
|
||||||
|
volumeMounts:
|
||||||
|
- name: data
|
||||||
|
mountPath: /data
|
||||||
resources:
|
resources:
|
||||||
requests: { memory: 32Mi, cpu: 20m }
|
requests: { memory: 32Mi, cpu: 20m }
|
||||||
limits: { memory: 128Mi }
|
limits: { memory: 128Mi }
|
||||||
|
volumes:
|
||||||
|
- name: data
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: redis-data
|
||||||
---
|
---
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Service
|
kind: Service
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
=== 기준선 ===
|
||||||
|
Redis 키: 1
|
||||||
|
PostgreSQL 토큰: 1 행
|
||||||
|
Redis 영속화 설정:
|
||||||
|
save = save
|
||||||
|
appendonly no
|
||||||
|
|
||||||
|
=== 외부 진입점 정상 확인 ===
|
||||||
|
https://app1.hyeonworks.com/ HTTP 200
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
=== ① Redis 정지 ===
|
||||||
|
정지: 14:26:30
|
||||||
|
deployment.apps/redis scaled
|
||||||
|
삭제 완료
|
||||||
|
|
||||||
|
=== 로그인한 사용자의 다음 요청은 어떻게 되는가 ===
|
||||||
|
/ HTTP 200
|
||||||
|
/bff/token-boundary HTTP 000
|
||||||
|
/actuator/health HTTP 503
|
||||||
|
--- token-boundary 응답 본문 ---
|
||||||
|
|
||||||
|
|
||||||
|
=== 파드 상태 — readiness 가 Redis 를 보는가 ===
|
||||||
|
bff-555df79c97-6j86w 1/1 Running 0 17m
|
||||||
|
bff-555df79c97-vgg6g 1/1 Running 0 16m
|
||||||
|
|
||||||
|
=== health 상세 ===
|
||||||
|
|
||||||
|
|
||||||
|
=== BFF 로그 ===
|
||||||
|
at java.base/sun.nio.ch.Net.pollConnect(Native Method) ~[na:na]
|
||||||
|
at java.base/sun.nio.ch.Net.pollConnectNow(Unknown Source) ~[na:na]
|
||||||
|
at java.base/sun.nio.ch.SocketChannelImpl.finishConnect(Unknown Source) ~[na:na]
|
||||||
|
at io.netty.channel.socket.nio.NioSocketChannel.doFinishConnect(NioSocketChannel.java:336) ~[netty-transport-4.1.135.Final.jar!/:4.1.135.Final]
|
||||||
|
at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.finishConnect(AbstractNioChannel.java:339) ~[netty-transport-4.1.135.Final.jar!/:4.1.135.Final]
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
=== health 그룹별 응답 — 왜 파드는 Ready 인가 ===
|
||||||
|
/actuator/health HTTP server
|
||||||
|
/actuator/health/readiness HTTP 200
|
||||||
|
/actuator/health/liveness HTTP 200
|
||||||
|
|
||||||
|
=== /actuator/health 본문 (Redis 항목이 있는가) ===
|
||||||
|
|
||||||
|
|
||||||
|
=== /actuator/health/readiness 본문 ===
|
||||||
|
{"status":"UP"}
|
||||||
|
|
||||||
|
=== Service 엔드포인트 — 트래픽을 계속 받는가 ===
|
||||||
|
ready: [10.42.0.52 10.42.1.124]
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
=== 복구 ===
|
||||||
|
deployment.apps/redis scaled
|
||||||
|
deployment "redis" successfully rolled out
|
||||||
|
/actuator/health HTTP 200
|
||||||
|
/bff/token-boundary HTTP 302
|
||||||
|
BFF 재시작 필요했나: 0,0 회 재시작
|
||||||
|
|
||||||
|
=== ② 영속화 — 지금 설정으로 재시작하면 무엇이 남는가 ===
|
||||||
|
키 심음: before-restart
|
||||||
|
dbsize: 4
|
||||||
|
|
||||||
|
--- AOF 를 켜고 다시 심는다 (영속화가 켜져 있으면 살아남는가) ---
|
||||||
|
appendonly yes
|
||||||
|
total 12
|
||||||
|
drwxr-xr-x 3 redis redis 4096 Sep 4 05:26 .
|
||||||
|
drwxr-xr-x 1 root root 4096 Sep 4 05:26 ..
|
||||||
|
drwx------ 2 redis redis 4096 Sep 4 05:26 appendonlydir
|
||||||
|
|
||||||
|
--- 파드를 지운다 ---
|
||||||
|
deployment "redis" successfully rolled out
|
||||||
|
재기동 후:
|
||||||
|
dbsize: 0
|
||||||
|
b5:probe
|
||||||
|
b5:aof
|
||||||
|
appendonly no
|
||||||
|
persistentvolumeclaim/redis-data created
|
||||||
|
deployment.apps/redis configured
|
||||||
|
deployment "redis" successfully rolled out
|
||||||
|
|
||||||
|
=== 영속 볼륨 위에서 다시 시험 ===
|
||||||
|
appendonly yes
|
||||||
|
키 심음: written-on-pvc
|
||||||
|
sed: -e expression #1, char 8: unknown option to 's'
|
||||||
|
|
||||||
|
--- 파드를 지운다 ---
|
||||||
|
deployment "redis" successfully rolled out
|
||||||
|
재기동 후:
|
||||||
|
dbsize: 1
|
||||||
|
b5:pvc written-on-pvc
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# B-5 — Redis 상실과 영속화 증거
|
||||||
|
|
||||||
|
2026-09-04 15:35–15:50 KST
|
||||||
|
해설: [`docs/experiment-b5-redis-loss-persistence.md`](../../experiment-b5-redis-loss-persistence.md)
|
||||||
|
|
||||||
|
| 파일 | 무엇을 보여주는가 |
|
||||||
|
|---|---|
|
||||||
|
| `01-baseline.txt` | 정지 전 — Redis 1키, PostgreSQL 1행, `save`/`appendonly no`, 외부 200 |
|
||||||
|
| `02-redis-down.txt` | 정지 후 — `/bff/token-boundary` **`HTTP 000`(멈춤)**, `/actuator/health` 503, **파드는 1/1 Ready 유지**, Lettuce 재연결 스택 |
|
||||||
|
| `03-health-groups.txt` | **핵심** — `/actuator/health` 503 인데 `/actuator/health/readiness` 는 `{"status":"UP"}`. Service 엔드포인트에 두 파드 모두 남아 있다 |
|
||||||
|
| `04-persistence.txt` | 복구는 자동(재시작 0회) · **AOF 를 켰는데 파드 삭제 후 `dbsize 0`** · PVC 를 붙인 뒤 `written-on-pvc` **생존** |
|
||||||
|
|
||||||
|
## 핵심 세 줄
|
||||||
|
|
||||||
|
1. **파드가 Ready 를 유지한 채 계속 실패한다.** `redis` 헬스 지표가 readiness 그룹에 없기 때문이며, A-2 에서 Keycloak 이 NotReady 가 된 것과 정반대다.
|
||||||
|
2. **오류가 아니라 멈춤이다.** `HTTP 000` — 빠른 실패가 안 되어 있어 사용자는 멈춘 화면을 본다.
|
||||||
|
3. **볼륨 없이 AOF 만 켜는 것은 장식이다.** `appendonlydir` 까지 만들어지지만 컨테이너와 함께 사라진다.
|
||||||
@@ -0,0 +1,254 @@
|
|||||||
|
# B-5 — Redis 가 죽으면, 그리고 재시작하면 무엇이 남는가
|
||||||
|
|
||||||
|
브랜치 `feature/keycloak-b5-redis-loss-persistence` ·
|
||||||
|
증거 [`docs/evidence/b5-redis-loss/`](evidence/b5-redis-loss/) ·
|
||||||
|
2026-09-04 15:35–15:50 KST
|
||||||
|
|
||||||
|
선행: [`B-2`](experiment-b2-multi-instance-session.md) — 세션(Redis)과 토큰(PostgreSQL)이 나뉘어 있어야 각각 죽여볼 수 있다
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 0. 결론부터
|
||||||
|
|
||||||
|
| | 결과 |
|
||||||
|
|---|---|
|
||||||
|
| Redis 정지 시 요청 | **오류가 아니라 멈춘다** (`HTTP 000`) |
|
||||||
|
| `/actuator/health` | **503** |
|
||||||
|
| **파드 readiness** | **★ `UP` 유지 — 트래픽을 계속 받으며 계속 실패한다** |
|
||||||
|
| 복구 | 자동. **BFF 재시작 0회** |
|
||||||
|
| **AOF 를 켰는데 재시작 후 전부 소실** | **볼륨이 없었다.** 영속화 설정만으로는 아무것도 안 남는다 |
|
||||||
|
| PVC 를 붙인 뒤 | **살아남는다** |
|
||||||
|
|
||||||
|
**A-2(Keycloak DB 상실)와 정반대의 실패 모양이다.** 거기서는 헬스체크가
|
||||||
|
파드를 트래픽에서 빼줬는데, 여기서는 안 빼준다.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Redis 정지 — 오류가 아니라 정지다
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl -n keycloak-lab scale deployment/redis --replicas=0
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
/ HTTP 200 ← permitAll 정적 페이지
|
||||||
|
/bff/token-boundary HTTP 000 ← ★ 응답이 없다
|
||||||
|
/actuator/health HTTP 503
|
||||||
|
```
|
||||||
|
|
||||||
|
`000` 은 curl 이 응답을 못 받았다는 뜻이다. **오류를 돌려주는 것이 아니라
|
||||||
|
매달려 있다.** Lettuce 가 재연결을 시도하며 타임아웃을 기다리기 때문이다.
|
||||||
|
|
||||||
|
```
|
||||||
|
io.netty.channel.socket.nio.NioSocketChannel.doFinishConnect
|
||||||
|
java.base/sun.nio.ch.Net.pollConnect
|
||||||
|
```
|
||||||
|
|
||||||
|
> **"빨리 실패하기(fail fast)"가 안 되어 있다.** 사용자는 오류 화면 대신
|
||||||
|
> **멈춘 화면**을 본다. 이것이 A-6(지연 주입)에서 본 것과 같은 문제다 —
|
||||||
|
> **느린 실패가 빠른 실패보다 나쁘다.**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. 그런데 파드는 Ready 를 유지한다 — 가장 중요한 발견
|
||||||
|
|
||||||
|
```
|
||||||
|
/actuator/health HTTP 503
|
||||||
|
/actuator/health/readiness HTTP 200 {"status":"UP"}
|
||||||
|
/actuator/health/liveness HTTP 200
|
||||||
|
|
||||||
|
Service ready: [10.42.0.52 10.42.1.124] ← 둘 다 트래픽을 받는다
|
||||||
|
```
|
||||||
|
|
||||||
|
### 개념 — health group
|
||||||
|
|
||||||
|
Spring Boot 는 헬스 지표를 **그룹**으로 나눈다.
|
||||||
|
|
||||||
|
```
|
||||||
|
/actuator/health 모든 지표의 합 ← redis 지표가 여기 있다
|
||||||
|
/actuator/health/readiness readiness 그룹 ← 기본값은 readinessState 뿐
|
||||||
|
/actuator/health/liveness liveness 그룹
|
||||||
|
```
|
||||||
|
|
||||||
|
**`redis` 헬스 지표는 자동으로 readiness 그룹에 들어가지 않는다.**
|
||||||
|
그래서 전체 상태는 `DOWN` 인데 readiness 는 `UP` 이다.
|
||||||
|
|
||||||
|
kubelet 은 `/actuator/health/readiness` 를 보므로 **파드를 빼지 않는다.**
|
||||||
|
|
||||||
|
### A-2 와의 대비
|
||||||
|
|
||||||
|
| | A-2 (Keycloak · DB 상실) | **B-5 (BFF · Redis 상실)** |
|
||||||
|
|---|---|---|
|
||||||
|
| 의존 대상 헬스 지표 | **readiness 에 포함** | **포함 안 됨** |
|
||||||
|
| 파드 상태 | **NotReady** | **Ready 유지** |
|
||||||
|
| Service 엔드포인트 | **비었다** | 둘 다 남는다 |
|
||||||
|
| 외부 응답 | **503** (즉시, 명확) | **000** (멈춤) |
|
||||||
|
|
||||||
|
**Keycloak 은 자기 의존성을 readiness 에 넣었고, 이 BFF 는 안 넣었다.**
|
||||||
|
어느 쪽이 옳은지는 상황에 달렸다.
|
||||||
|
|
||||||
|
| readiness 에 넣으면 | 넣지 않으면 |
|
||||||
|
|---|---|
|
||||||
|
| 의존 대상이 죽으면 **전 파드가 빠진다** → 전면 장애 | 파드가 남아 **실패를 계속 서빙한다** |
|
||||||
|
| 부분 기능이라도 살릴 수 없다 | 부분 기능(정적 페이지 등)은 살아 있다 |
|
||||||
|
| A-2 처럼 **명확한 503** | **멈춤** — 진단이 어렵다 |
|
||||||
|
|
||||||
|
**의도적으로 골라야 하는 설정이며, 기본값에 맡기면 후자가 된다.**
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
management:
|
||||||
|
endpoint:
|
||||||
|
health:
|
||||||
|
group:
|
||||||
|
readiness:
|
||||||
|
include: readinessState, redis # 넣으려면 명시해야 한다
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. 복구는 자동이다
|
||||||
|
|
||||||
|
```
|
||||||
|
/actuator/health HTTP 200
|
||||||
|
/bff/token-boundary HTTP 302 (세션이 사라져 로그인으로 보냄)
|
||||||
|
BFF 재시작: 0, 0 회
|
||||||
|
```
|
||||||
|
|
||||||
|
**Lettuce 가 스스로 재연결했다.** A-2 에서 Keycloak 의 커넥션 풀이 그랬던
|
||||||
|
것과 같다. **liveness 를 Redis 에 걸었다면 파드가 재시작됐을 것**이고,
|
||||||
|
회복이 더 늦어졌을 것이다.
|
||||||
|
|
||||||
|
`302` 는 세션이 사라졌기 때문이다 — Redis 가 비었으므로 로그인 상태가 없다.
|
||||||
|
**사용자는 로그아웃된다.**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. 영속화 — 설정만으로는 아무것도 안 남는다
|
||||||
|
|
||||||
|
### 시도 ① AOF 를 켜고 파드를 지운다
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl -n keycloak-lab exec deploy/redis -- redis-cli config set appendonly yes
|
||||||
|
kubectl -n keycloak-lab exec deploy/redis -- redis-cli set b5:aof "written-with-aof"
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
appendonly yes
|
||||||
|
/data 내용: appendonlydir ← 파일이 실제로 만들어졌다
|
||||||
|
```
|
||||||
|
|
||||||
|
파드를 지운 뒤
|
||||||
|
|
||||||
|
```
|
||||||
|
dbsize: 0
|
||||||
|
b5:probe (없음)
|
||||||
|
b5:aof (없음)
|
||||||
|
appendonly no ← 설정도 되돌아갔다
|
||||||
|
```
|
||||||
|
|
||||||
|
**전부 사라졌다.**
|
||||||
|
|
||||||
|
| 왜 | |
|
||||||
|
|---|---|
|
||||||
|
| `/data` 가 **컨테이너 파일시스템** | 볼륨이 없으므로 컨테이너와 함께 사라진다 |
|
||||||
|
| `CONFIG SET` 은 **런타임 전용** | 재기동하면 매니페스트의 `args` 가 이긴다 |
|
||||||
|
|
||||||
|
> **쿠버네티스에서 영속화 설정만 켜는 것은 장식이다.**
|
||||||
|
> `appendonly yes` 를 켜고 안심하는 것이 가장 위험하다 — **파일은 만들어지고
|
||||||
|
> 로그도 정상이며, 사라지는 것은 재시작 순간뿐**이다.
|
||||||
|
|
||||||
|
### 시도 ② PVC 를 붙인다
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
volumeMounts:
|
||||||
|
- name: data
|
||||||
|
mountPath: /data
|
||||||
|
volumes:
|
||||||
|
- name: data
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: redis-data
|
||||||
|
args: ["redis-server", "--appendonly", "yes", "--dir", "/data"]
|
||||||
|
```
|
||||||
|
|
||||||
|
```
|
||||||
|
appendonly yes
|
||||||
|
키 심음: written-on-pvc
|
||||||
|
--- 파드 삭제 후 ---
|
||||||
|
dbsize: 1
|
||||||
|
b5:pvc written-on-pvc ← 살아남았다
|
||||||
|
```
|
||||||
|
|
||||||
|
### 비교
|
||||||
|
|
||||||
|
| 구성 | 파드 삭제 후 |
|
||||||
|
|---|---|
|
||||||
|
| AOF **끔**, 볼륨 없음 | 전부 소실 |
|
||||||
|
| AOF **켬**, 볼륨 없음 | **전부 소실** (설정은 켰는데) |
|
||||||
|
| AOF **켬**, **PVC** | **생존** |
|
||||||
|
|
||||||
|
**순서가 있다 — 볼륨이 먼저고 설정이 나중이다.**
|
||||||
|
|
||||||
|
### `appendfsync` 는 여전히 트레이드오프다
|
||||||
|
|
||||||
|
```
|
||||||
|
appendfsync everysec ← 기본값
|
||||||
|
```
|
||||||
|
|
||||||
|
**1초 분량을 잃을 수 있다.** A-3 에서 본 PostgreSQL 의
|
||||||
|
`synchronous_commit OFF` 와 **같은 모양의 맞바꿈**이다.
|
||||||
|
|
||||||
|
| 설정 | 잃는 양 | 비용 |
|
||||||
|
|---|---|---|
|
||||||
|
| `always` | 없음 | 쓰기마다 fsync — 느리다 |
|
||||||
|
| **`everysec`** | **최대 1초** | 기본값 |
|
||||||
|
| `no` | OS 에 맡김 | 가장 빠름 |
|
||||||
|
|
||||||
|
**세션 저장소에서 1초를 잃는다는 것은 그 사이 로그인한 사용자가
|
||||||
|
다시 로그인해야 한다는 뜻이다.** A-3 에서 Keycloak 이 같은 판단을 했다.
|
||||||
|
|
||||||
|
### PVC 도 노드에 못박힌다
|
||||||
|
|
||||||
|
`local-path` PVC 이므로 **A-4 에서 본 것과 같다** — 노드가 죽으면
|
||||||
|
볼륨도 함께 접근 불가가 된다. **영속화는 재시작을 견디게 하지만
|
||||||
|
노드 상실을 견디게 하지는 않는다.**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. 재현 절차 (명령어)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# ① 정지
|
||||||
|
kubectl -n keycloak-lab scale deployment/redis --replicas=0
|
||||||
|
curl -s -o /dev/null -w '%{http_code}\n' https://app1.hyeonworks.com/bff/token-boundary # 000
|
||||||
|
|
||||||
|
# ② 왜 파드가 안 빠지는가 — 그룹별로 본다
|
||||||
|
kubectl -n keycloak-lab exec <bff-pod> -- wget -qO- http://localhost:8083/actuator/health
|
||||||
|
kubectl -n keycloak-lab exec <bff-pod> -- wget -qO- http://localhost:8083/actuator/health/readiness
|
||||||
|
kubectl -n keycloak-lab get endpoints bff -o jsonpath='{.subsets[*].addresses[*].ip}'
|
||||||
|
|
||||||
|
# ③ 복구
|
||||||
|
kubectl -n keycloak-lab scale deployment/redis --replicas=1
|
||||||
|
|
||||||
|
# ④ 영속화 — 볼륨 없이 AOF 만 켜본다
|
||||||
|
kubectl -n keycloak-lab exec deploy/redis -- redis-cli config set appendonly yes
|
||||||
|
kubectl -n keycloak-lab exec deploy/redis -- redis-cli set k v
|
||||||
|
kubectl -n keycloak-lab delete pod -l app=redis
|
||||||
|
kubectl -n keycloak-lab exec deploy/redis -- redis-cli dbsize # 0
|
||||||
|
|
||||||
|
# ⑤ PVC 를 붙이고 다시
|
||||||
|
kubectl apply -f deploy/lab/k8s/bff-redis.yaml
|
||||||
|
kubectl -n keycloak-lab exec deploy/redis -- redis-cli set k v
|
||||||
|
kubectl -n keycloak-lab delete pod -l app=redis
|
||||||
|
kubectl -n keycloak-lab exec deploy/redis -- redis-cli get k # v
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. 다음 실험에 남기는 것
|
||||||
|
|
||||||
|
| 실험 | 이 실험이 준 것 |
|
||||||
|
|---|---|
|
||||||
|
| **B-6** 암호화 key 교체 | Redis 가 이제 영속적이므로 **key 를 바꾸면 옛 데이터가 남아 있다** |
|
||||||
|
| **D-1** 백업·복구 | `local-path` PVC 는 **노드에 묶여 있다** — 노드가 안 돌아오면 백업뿐 |
|
||||||
|
| 구성 | **readiness 그룹에 무엇을 넣을지 명시적으로 정한다** |
|
||||||
|
| 구성 | Redis 클라이언트에 **타임아웃**을 걸어 빠르게 실패시킨다 |
|
||||||
Reference in New Issue
Block a user