Written by subagents running under the writing-practitioner-guides skill,
one guide per experiment, 22,566 lines. Each walks a reader from baseline
capture through injection, injection verification, observation and recovery.
Section 3 carries the weight in most of them. Injection failed silently nine
times in this lab, and a failed injection looks exactly like no effect — so
the guides verify the target is actually in the intended state before
reading any result. A-4 makes virsh list the only proof because the node
reads Ready for 40 seconds after the machine is off; A-5 makes the packet
counter the sole go/no-go because a rule on the wrong node produces an empty
result that reads like a finding; A-6 quotes the run where 적용완료 was
printed between four Cannot find device "eth0" lines.
The traps the guides are built around are ones that invert a conclusion
rather than merely annoy:
A-0 emptying the session table without a restart leaves cache entries
that get counted as replication arriving
A-2 dropping -o /dev/null fuses body and status into one string
A-3 presence of "ready to accept connections" instead of its timestamp
B-2 row count alone reads an UPDATE as nothing having happened
B-4 tr ',' '\n' splits ["admin","editor"] so only admin is seen
B-7 no login screen means the cookie died and SSO re-authenticated
C-1 counting sessions without joining realm counts your own kcadm one
D-1 kubectl exec without -i restores nothing and still exits 0
D-4a "ran with error output" is what success looks like
Every quoted block is copied from docs/evidence/ and marked 실측; reshaped
commands are marked 미검증 rather than passed off as measured. Where a source
document carries a ★ correction the guides follow the corrected claim — A-7's
REVOKED_TOKEN hypothesis, C-1's session count, B-2's schema attribution.
Two hazards are stated rather than smoothed over: B-6 deletes a key that
cannot be recreated, and D-1/D-4 need host sudo, which asks for a password,
so those steps say a person must type them.
Audit over all 26: 672 interpretation pairs, 486 evidence citations, 117
undo sections, and zero occurrences of the patterns the skill forbids —
no python data processing, no deprecated kubectl get endpoints, no
placeholders, no bare kcadm.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
5.7 KiB
5.7 KiB
실험 재현 가이드 26편
각 편은 직접 쳐서 재현하는 문서다. 무엇을 발견했는지는
docs/experiment-*.md 가 적고, 여기는 그것을 다시 만들려면 무엇을
어떤 순서로 치는가를 적는다.
전제
기반 7단계가 끝나 있어야 한다. 특히 05 까지는 모든 실험의 공통 전제이고, 지표를 보는 실험은 06 도 필요하다.
각 편의 구조
이 가이드가 끝나면 · 전제 · 주의 · 표시 규약
0 왜 이 실험인가
1 기준선 ← 주입 전에 평시를 잡는다
2 주입
3 주입 검증 ← 여기가 대부분의 편에서 가장 중요하다
4 관찰
5 복구
막히면 · 다음
3번이 핵심인 편이 많다. 이 실험대에서 주입은 아홉 번 조용히 실패했고, 실패한 주입은 「아무 일도 없었다」로 보여 「영향이 없다」와 구별되지 않는다. 그래서 결과를 읽기 전에 대상이 실제로 그 상태인지를 따로 확인한다.
표시 규약
| 표시 | 뜻 |
|---|---|
| 실측 | 증거 파일에 있는 출력 원문. 그대로 나온다 |
| 형태 | 모양만 같고 값은 환경마다 다르다 |
| 미검증 | 손으로 치기 좋게 고쳐 쓴 형태. 원래 실행에서 그대로 쓰이지는 않았다 |
A층 — Keycloak 자체가 깨질 때
| 가이드 | 무엇을 직접 보게 되나 | |
|---|---|---|
| A-0 | 세션 공유 경로 | 세션을 나르는 것이 Infinispan 이 아니라 PostgreSQL 이라는 것 |
| A-1 | 7800 차단 | 세션 공유는 안 깨지고 로그아웃 전파만 깨진다 |
| A-2 | DB 정지 | 503 이 나는 동안에도 up 이 1 이다 |
| A-3 | DB 크래시 | 200 을 받은 로그인 153건 중 4건이 DB 에 없다 |
| A-4 | 노드 상실 | 죽은 노드가 40초 동안 Ready 로 읽힌다 |
| A-5 | 비대칭 분단 | 한 방향만 막으면 열린 쪽으로 재연결한다 |
| A-6 | 지연 주입 | 200밀리초가 두 단계를 지나 22.2초가 된다 |
| A-7 | volatile 비교 | 설정 하나로 A층 결론 셋이 뒤집힌다 |
| A-7a | volatile 원인 확정 | 같은 설정이 캐시 온도만으로 400·500·200 세 답을 낸다 |
| A-8 | 롤링 재시작 | 세션은 남고 캐시만 사라진다 |
B층 — 애플리케이션 쪽 저장소
| 가이드 | 무엇을 직접 보게 되나 | |
|---|---|---|
| B-0 | 자동구성 확인 | 아무것도 안 주면 Spring 이 무엇을 고르는가 |
| B-1 | Redis 세션 저장소 | 세션은 옮겨지는데 토큰은 안 따라온다 |
| B-2 | 다중 인스턴스 | 저장소를 옮겨도 안 고쳐지는 것 — 원인은 기본키다 |
| B-3 | refresh 경쟁 | 이긴 요청의 토큰조차 못 쓴다 |
| B-4 | Edge 인가 범위 | 위조 헤더가 그대로 도착한다 |
| B-5 | Redis 상실·영속화 | 볼륨 없는 영속화 설정은 장식이다 |
| B-6 | 키 회전 | JWKS 캐시에 유예 구간이 없다 |
| B-7 | cookie secret 회전 | 겹침 구간을 만들 수 없고 서버 세션이 고아로 남는다 |
| B-7a | 고아 세션 정리 | TTL 로 생성 시각을 역산해 골라낸다 |
C층 — SSO 와 로그아웃
| 가이드 | 무엇을 직접 보게 되나 | |
|---|---|---|
| C-1 | 다중 앱 SSO | SSO 는 되는데 로그아웃이 안 퍼진다 |
| C-2 | 백채널 로그아웃 | 양쪽 다 없었다 — 한쪽만 고치면 여전히 안 된다 |
D층 — 운영
| 가이드 | 무엇을 직접 보게 되나 | |
|---|---|---|
| D-1 | 백업·복구 | 백업이 진짜 백업인지 스키마를 지워서 확인한다 |
| D-2 | 버전 업그레이드 | 롤백이 되는 조건은 스키마가 안 움직였을 때다 |
| D-3 | 비밀 관리 | base64 는 인코딩이지 암호화가 아니다 |
| D-4 | 인증서 갱신 | 갱신은 성공했는데 38분 25초 동안 옛 인증서가 나갔다 |
| D-4a | deploy 훅 | 훅 하나로 그 공백이 1~2초가 된다 |
순서
A-0 을 먼저 한다. 나머지 A층 결론이 전부 거기서 확인한 「세션이 어디 있는가」 위에 서 있다.
A-0 ─┬─ A-1 ─┬─ A-5
│ └─ A-6
├─ A-2 ── A-3 ── D-1 ── D-2
├─ A-4
├─ A-8
└─ A-7 ── A-7a ← A층을 다 한 뒤 설정 하나만 바꿔 재실행한다
B-0 ── B-1 ─┬─ B-2 · B-3 · B-4 · B-5 · B-6
└─ B-7 ── B-7a
C-1 ── C-2 D-3 · D-4 ── D-4a (언제든 독립적으로)
A-7 을 A층 마지막에 두는 이유 — 앞의 실험을 다 마친 뒤 설정 하나만 바꿔 재실행하면 같은 주입에 대한 정반대 결과를 한 벌로 얻는다.
안전
각 편의 2번(주입)부터 상태가 바뀐다. 모든 편이 되돌리는 명령을 주입보다 먼저 보여 주고, 5번에서 원상복구를 확인한다.
호스트(test-server)에서 하는 일은 sudo 비밀번호가 필요해 사람이 직접
쳐야 한다. D-1 과 D-4 가 여기 해당하며, 각 편이 어느 단계가 그런지 적는다.