Files
keycloak-pattern/docs/experiment-d2-version-upgrade.md
DongHyeonkaandClaude Opus 5 cdac9b8178 docs: give the twelve experiments that had no architecture diagram one
An audit against the standard the series set — concepts, procedure,
commands, architecture diagram, evidence table, terminal output — found the
three new experiments met it while twelve of the original ones had no
diagram at all: A-0, A-1, A-3, A-4, A-5, A-6, A-8, B-0, B-2, B-7, C-2, D-2.

Each now has one drawn from what that experiment actually found, not filler:
A-0 shows sharing going through PostgreSQL rather than between the caches;
A-3 the gap between the 200 and the WAL flush, with both failed injections;
A-5 the three silent injection failures; A-6 the two places latency is
multiplied; B-0 the repository keyed by principal with no session id; B-2
the primary key that causes the overwrite; D-2 why the rolling update
stopped the accident halfway.

Also corrected the index's stale claim of 11 experiments without a
screenshot — it is 14, and the reason is recorded: those experiments were
measured from terminals, the database and logs, and the observability stack
does not scrape Redis, the BFF or PostgreSQL, so there is no console to
photograph.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-04 21:44:36 +09:00

8.9 KiB
Raw Permalink Blame History

D-2 — 버전을 올리고 내릴 때 무엇이 일어나는가

브랜치 feature/keycloak-d2-version-upgrade · 증거 docs/evidence/d2-version-upgrade/ · 2026-09-04 17:0517:15 KST

선행: D-1백업이 전제다 · A-8 — 롤링 재시작이 안전하다는 것이 전제

★ 정정 — 이 문서의 결론은 조건부다

이 문서는 "롤백이 안 된다" 고 단정했다. 나중에 후속 문서 에서 26.7.0 ↔ 26.7.3 을 시험하니 롤백이 성공했다.

버전 차 databasechangelog 롤백
26.7.0 → 26.0 체크섬 불일치 불가
26.7.0 ↔ 26.7.3 210 → 210, 변화 없음 가능

판단 기준은 버전 번호가 아니라 databasechangelog 의 행 수가 바뀌었는가다. 아래 본문은 스키마가 바뀐 경우에 해당한다.


구조

D-2 — 방향에 따라 갈리는 결과

다이어그램 규약은 diagrams/_style.md. 실험대 전체 구조는 diagrams/lab-topology.svg.


0. 결론부터

확인 결과
롤백이 되는가 ★ 안 된다. liquibase ValidationFailedException: 1 changesets check sum
그때 서비스는 ★ 살아 있다. 한 파드가 남아 외부 200
앞으로 되돌리기 된다. 정상 복구, 데이터 무사
세션 유지 (4개 그대로)

"롤백 계획"을 세워두었다면 그 계획은 동작하지 않는다. 대신 StatefulSet 의 롤링 업데이트가 사고를 절반에서 멈춰줬다.


1. 전제 — 먼저 백업한다

D-1 에서 확인한 절차 그대로.

kubectl -n keycloak-lab exec deploy/postgres -- pg_dump -U keycloak -d keycloak \
  --clean --if-exists > /tmp/pre-upgrade.sql
  백업: 396333 bytes
  현재 이미지: quay.io/keycloak/keycloak:26.7.0
  총 마이그레이션 수: 210
  현재 세션: 4

개념 — databasechangelog

Keycloak 은 Liquibase 로 스키마를 관리한다. 적용한 변경 하나하나를 databasechangelog 테이블에 기록한다.

컬럼
id / author / filename 변경을 식별
md5sum 그 변경 정의의 체크섬
orderexecuted 적용 순서

210개가 쌓여 있다. 이것이 "이 DB 는 어느 버전까지 올라갔는가"의 기록이다.


2. 롤백을 시도했다 — 26.7.0 → 26.0

kubectl -n keycloak-lab set image statefulset/keycloak keycloak=quay.io/keycloak/keycloak:26.0
  +20초   keycloak-0:Running(1/1)  keycloak-1:Running(0/1)
  +80초   keycloak-0:Running(1/1)  keycloak-1:Error(0/1)
  +140초  keycloak-0:Running(1/1)  keycloak-1:CrashLoopBackOff(0/1)
ERROR: Failed to start server in (production) mode
ERROR: liquibase.exception.ValidationFailedException: Validation Failed:
         1 changesets check sum

왜 실패하는가 — 체크섬 불일치

   26.7.0 이 적용한 변경    →  databasechangelog 에 md5sum 기록
   26.0 이 기동하며 검증     →  자기가 아는 그 변경의 md5sum 과 비교
                              └─ 다르다 → ValidationFailedException

"모르는 변경이 있다" 가 아니라 "아는 변경인데 정의가 다르다" 이다. 같은 changeset 이 버전 사이에 수정된 것이며, 더 엄격한 실패다.

Liquibase 는 안전을 위해 기동 자체를 거부한다. 스키마를 반쯤 아는 상태로 서비스하느니 안 뜨는 쪽을 고른 설계다.


3. 그런데 서비스는 살아 있었다

  https://auth.hyeonworks.com/realms/master  HTTP 200
  ready 주소: [10.42.1.140]                   ← 한 파드만
  statefulset desired/ready/updated: 2 / 1 / 1

StatefulSet 의 롤링 업데이트가 한 번에 하나씩 바꾸기 때문이다.

   keycloak-1 을 26.0 으로 → 기동 실패 → Ready 가 안 됨
     └─ StatefulSet 은 keycloak-0 을 건드리지 않는다
          └─ keycloak-0 (26.7.0) 이 계속 서비스한다

A-8 에서 "무중단은 replica ≥ 2 와 readiness 의 조합" 이라고 썼는데, 여기서는 그 조합이 잘못된 배포를 절반에서 멈춰줬다.

replica 1 이었다면
유일한 파드가 CrashLoopBackOff 전면 장애
되돌리려면 사람이 개입 그동안 계속 다운

4. 앞으로 되돌리기

kubectl -n keycloak-lab set image statefulset/keycloak keycloak=quay.io/keycloak/keycloak:26.7.0
  partitioned roll out complete: 2 new pods have been updated...
  keycloak-0  1/1 Running
  keycloak-1  1/1 Running   28s

  realms|clients|migrations|sessions = 2|15|210|4
  외부 진입점 HTTP 200

정상 복구. 마이그레이션 수도 세션도 그대로다 — 실패한 기동은 스키마를 건드리지 못했다. Liquibase 가 검증 단계에서 멈췄기 때문이다.


5. 그래서 업그레이드 계획은 어떻게 세워야 하는가

   ✘ "문제가 생기면 이미지 태그를 되돌린다"
        └─ 스키마가 이미 바뀌었으면 옛 버전이 안 뜬다

   ✔ "문제가 생기면 백업에서 DB 를 되돌리고 이미지도 되돌린다"
        └─ D-1 에서 확인한 절차가 여기서 필요하다
단계
1 백업 (D-1) — 이것이 유일한 되돌리기 수단이다
2 이미지 태그 변경
3 첫 파드만 관찰 — StatefulSet 이 멈춰준다
4 실패하면 이미지를 되돌린다 (스키마가 안 바뀌었으면 이것으로 충분)
5 스키마가 이미 바뀌었으면 DB 도 복구해야 한다

4와 5를 가르는 것이 "Liquibase 가 검증에서 멈췄는가, 이미 적용했는가" 다. 이번에는 검증에서 멈춰 4로 끝났다.


6. 이 실험이 확인한 것과 못 한 것

✔ 롤백이 안 된다는 것 체크섬 불일치로 기동 거부
✔ 실패가 안전하게 격리된다 StatefulSet + readiness
✔ 실패한 기동은 스키마를 안 건드린다 마이그레이션 210 그대로
정방향 업그레이드 26.7.0 보다 새 이미지가 없어 시험하지 못했다
✘ 마이그레이션 중 장애 스키마 변경 도중 죽으면?
✘ 대규모 마이그레이션 시간 데이터가 작아 순식간이다

정방향을 시험하지 못한 것을 감춰서는 안 된다. 다만 역방향이 더 위험한 방향이고, 그것이 실패한다는 사실이 "롤백 계획" 을 무효로 만든다는 점에서 실무적으로 더 중요한 결과다.

새 버전이 나오면 같은 절차(백업 → 태그 변경 → 첫 파드 관찰)로 반복한다.



증거 파일

증거 수집 시각: 2026-09-04 15:00 16:15 KST (파일 mtime 기준. 문서 상단의 시각 표기는 작성 시점이라 다를 수 있다.)

파일 종류
01-pre-upgrade.txt 터미널 원문
02-rollback-attempt.txt 터미널 원문
03-roll-forward.txt 터미널 원문
d2-upgrade-window.png 스크린샷

파일별 상세는 evidence/d2-version-upgrade/README.md.

7. 재현 절차 (명령어)

# 1. 백업 먼저 (D-1)
kubectl -n keycloak-lab exec deploy/postgres -- pg_dump -U keycloak -d keycloak \
  --clean --if-exists > pre-upgrade.sql

# 2. 현재 마이그레이션 수를 기록
kubectl -n keycloak-lab exec deploy/postgres -- psql -U keycloak -d keycloak -tAc \
  "select count(*) from databasechangelog"

# 3. 버전 변경
kubectl -n keycloak-lab set image statefulset/keycloak keycloak=quay.io/keycloak/keycloak:<tag>

# 4. ★ 첫 파드만 본다. 실패하면 StatefulSet 이 멈춘다
kubectl -n keycloak-lab get pods -w
kubectl -n keycloak-lab logs keycloak-1 | grep -iE "liquibase|changeset|validation"

# 5. 서비스가 살아 있는지 (남은 파드가 받는다)
kubectl -n keycloak-lab get endpoints keycloak -o jsonpath='{.subsets[*].addresses[*].ip}'

# 6. 되돌리기 — 스키마가 안 바뀌었으면 이미지만으로 충분
kubectl -n keycloak-lab set image statefulset/keycloak keycloak=quay.io/keycloak/keycloak:26.7.0

8. 다음에 남기는 것

D-3 비밀 관리 업그레이드 시 Secret 도 같이 검토된다
운영 롤백 = 백업 복구다. 태그만 되돌리는 계획은 반쪽이다
운영 replica ≥ 2 가 잘못된 배포를 절반에서 멈춘다
미검증 정방향 업그레이드, 마이그레이션 중 장애, 대규모 소요 시간