The keycloak project ended with four open questions that design could not
settle. A two-VM lab was built to answer them by measurement, and this is
that material: 26 experiments, 125 raw command outputs, 22 browser captures.
Follows the import procedure in README.md.
source/ the originating repository verbatim — 78 documents, 28 SVGs,
8 manifests, plus .source-revision recording the commit
final/ the SSOT
document.md 729 lines written from the 29 experiment documents, not
concatenated: what was predicted, what was measured, and
where the measurement itself was wrong
evidence/raw 125 outputs, flattened to <experiment>__<file> because
the originals collided (01-baseline.txt appeared three
times) and the audit only globs the top level
evidence/meta one per raw file; command and exitCode are null and the
README says why rather than inventing them
evidence/browser 22 captures
assets/ three diagrams through techviz
.techviz/ their VizSpecs
A separate project rather than an addition to keycloak: the B-layer answers
that project's four questions, but the A, C and D layers are about cluster
failure, SSO and operations, and one document.md should hold one subject.
The four question records there can point here through 관계.
Recorded rather than papered over: only three of the 28 diagrams were
remade. The repository forbids hand-drawn SVG and forbids titles inside the
canvas; all 28 originals carry both, so converting them is redrawing, not
reformatting. They stay in source/ and the gap is written into the document.
verify-pipeline.py passes. audit-records.py reports no issues.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
89 lines
4.1 KiB
Plaintext
89 lines
4.1 KiB
Plaintext
browser — 브라우저 캡처 (Playwright MCP)
|
|
==================================
|
|
|
|
운영 콘솔(Grafana·Keycloak 관리 콘솔·앱 화면)의 화면 증거다.
|
|
|
|
★ 스크린샷이 없는 실험이 14개다. 안 찍은 것이 아니라 관측 대상에 그 지표가
|
|
없어서다 — Prometheus 는 keycloak·kubelet·node-exporter·prometheus 만 긁고
|
|
Redis·BFF·PostgreSQL 은 긁지 않는다. 근거는
|
|
raw/followup__04-observability-gap.txt 에 있다. 터미널·DB·로그로 측정한
|
|
실험은 브라우저에 띄울 화면 자체가 없다.
|
|
|
|
★ 6개 PNG 는 md5 가 같은 3쌍이다. 화면이 실제로 같았기 때문이며 각 실험의
|
|
원본 README 에 그 사실을 적어 두었다.
|
|
|
|
|
|
[a1-jgroups-transport-block]
|
|
a1-jgroups-transport-block__a1-cluster-size-partition-recovery.png
|
|
Grafana — vendor_cluster_size 가 2 → 1 → 2 로 움직이는 전 구간
|
|
|
|
[a2-database-loss]
|
|
a2-database-loss__a2-up-stayed-1-during-outage.png
|
|
Grafana — up{job="keycloak"} 이 전면 장애 내내 1에 평평
|
|
|
|
[a4-node-loss]
|
|
a4-node-loss__a4-up-dropped-per-node.png
|
|
Grafana — up 이 노드별로 0 으로 떨어지는 구간. 12:18–12:23 은 0 이 아니라 데이터 없음(관측자가 같이 죽음)
|
|
|
|
[a5-asymmetric-partition]
|
|
a5-asymmetric-partition__a5-cluster-size-bidirectional-block.png
|
|
Grafana — vendor_cluster_size 가 갈라졌다 합쳐지는 구간
|
|
|
|
[a6-latency-injection]
|
|
a6-latency-injection__a6-connection-pool-blocking.png
|
|
Grafana — agroal_blocking_time_max_milliseconds
|
|
|
|
[a8-rolling-restart]
|
|
a8-rolling-restart__a8-cache-reset-cluster-reformed.png
|
|
Grafana — 세션 캐시가 0 으로 떨어지고 cluster_size 가 다시 2 가 되는 구간
|
|
|
|
[b0-bff-redis-deploy]
|
|
b0-bff-redis-deploy__b0-bff-login-success-single-replica.png
|
|
replica 1 에서 로그인 성공한 BFF 화면
|
|
b0-bff-redis-deploy__b0-bff-token-boundary.png
|
|
/bff/token-boundary — principal: labuser, accessTokenStoredOnServer: true, browserTokenCount: 0
|
|
|
|
[b1-redis-session-store]
|
|
b1-redis-session-store__b1-login-works-two-replicas.png
|
|
전환 직후 accessTokenStoredOnServer: false
|
|
b1-redis-session-store__b1-token-boundary-after-redis.png
|
|
파드 전면 교체 후 — principal: labuser 는 살아남고 토큰만 사라진 상태
|
|
|
|
[b2-multi-instance-session]
|
|
b2-multi-instance-session__b2-before-relogin.png
|
|
JDBC 전환 직후, 옛 세션은 여전히 false
|
|
b2-multi-instance-session__b2-tokens-shared-across-instances.png
|
|
재로그인 후 accessTokenStoredOnServer: true — 두 replica 에서 동작
|
|
|
|
[b7-cookie-secret]
|
|
b7-cookie-secret__b7-oauth2proxy-login-success.png
|
|
Redis 세션 전환 후 성공한 Forward-Auth — x-forwarded-user/email/preferred-username 과 티켓 형태 쿠키
|
|
|
|
[b7a-orphan-session]
|
|
b7a-orphan-session__b7a-live-session-after-orphan-delete.png
|
|
고아를 지운 직후 살아있는 세션이 /oauth2/userinfo 를 정상 응답하는 브라우저 화면
|
|
|
|
[c1-multi-app-sso]
|
|
c1-multi-app-sso__c1-apps-alive-after-idp-logout.png
|
|
IdP 세션을 죽인 뒤에도 그대로 열리는 화면
|
|
c1-multi-app-sso__c1-sso-app2-no-login-screen.png
|
|
app2 가 로그인 화면 없이 열린 화면
|
|
|
|
[d2-version-upgrade]
|
|
d2-version-upgrade__d2-upgrade-window.png
|
|
Grafana — 26.7.3 업그레이드 구간의 cluster_size 2→1→2 두 번과 파드별 up 시계열 교체 (후속 작업에서 촬영)
|
|
|
|
[session-replication]
|
|
session-replication__keycloak-admin-sessions.png
|
|
관리 콘솔의 Sessions 화면. 브라우저는 nginx→Traefik 을 거쳐 두 파드 중 하나에 닿지만 어느 파드가 만든 세션이든 전부 보인다
|
|
session-replication__session-cache-entries-per-pod.png
|
|
위 사실의 시계열. 파란 선(keycloak-1)이 0에 붙어 있는 동안 초록 선(keycloak-0)만 14까지 오른다
|
|
|
|
[two-hop-proxy-headers]
|
|
two-hop-proxy-headers__stage-a-nginx-fixed.png
|
|
A — nginx 만 고침
|
|
two-hop-proxy-headers__stage-b-traefik-trusts.png
|
|
B — Traefik trustedIPs 추가
|
|
two-hop-proxy-headers__stage-c-resolved.png
|
|
C — 앱 strategy=native
|