refactor: 문서 개선 중
This commit is contained in:
@@ -1,23 +1,23 @@
|
||||
{
|
||||
"version": "1.1",
|
||||
"id": "b5-b6-storage-and-keys",
|
||||
"title": "볼륨 없는 영속화와 유예 없는 회전",
|
||||
"question": "설정만으로 영속화와 무중단 키 교체가 되는가",
|
||||
"title": "볼륨 없는 영속화와 replica별 키 회전",
|
||||
"question": "설정을 켰다는 사실만으로 영속화와 일관된 키 회전을 기대할 수 있는가",
|
||||
"type": "architecture",
|
||||
"direction": "TB",
|
||||
"direction": "LR",
|
||||
"audience": [
|
||||
"저장소와 키 회전을 운영하는 엔지니어"
|
||||
],
|
||||
"summary": "볼륨이 없으면 appendonly 설정은 장식이고, JWKS 캐시는 모르는 kid 를 만나면 곧바로 다시 가져온다.",
|
||||
"alt": "Redis 의 데이터 디렉터리가 컨테이너 파일시스템일 때 영속화 설정이 무의미해지는 구성과, 새 kid 를 만난 검증기가 JWKS 를 재조회하는 구성.",
|
||||
"long_description": "redis-cli config set appendonly yes 를 켜도 아무것도 달라지지 않았다. /data 가 컨테이너 파일시스템이라 컨테이너와 함께 죽기 때문이다. appendonlydir 이 만들어졌다가 그대로 버려진다. 볼륨 없는 영속화 설정은 장식이다. realm 키를 회전했을 때는 JWKS 캐시의 유예 구간을 기대했는데 없었다. NimbusJwtDecoder 는 모르는 kid 를 만나면 JWKS 를 다시 가져온다.",
|
||||
"summary": "Redis AOF 는 볼륨이 없으면 컨테이너와 함께 사라진다. 키 회전 뒤에는 replica별 JWKS cache 상태가 달라 같은 옛 토큰이 401과 200을 번갈아 받았다.",
|
||||
"alt": "운영 변경에서 Redis AOF는 볼륨 없는 데이터 디렉터리로 이어져 소멸하고, realm 키 회전은 replica별 JWKS cache 차이로 401과 200이 갈리는 두 경로.",
|
||||
"long_description": "B-5에서는 appendonly yes 설정이 적용돼도 /data가 컨테이너 파일시스템이라 재시작 때 사라졌다. B-6에서는 옛 키를 지운 뒤 같은 토큰을 반복 요청하자 401과 200이 교대로 나왔다. echo replica 둘의 JWKS cache가 독립적이라 한쪽은 새 목록을 받아 옛 키를 잃었고 다른 쪽은 아직 들고 있었기 때문이다.",
|
||||
"source_context": {
|
||||
"document": "docs/keycloak-session-store/final/document.md",
|
||||
"document_sha256": "1d44cba1905544d92f1d26ae36a8deb64a3db3914d6b488fd30d6ae7f8cfbabe",
|
||||
"document_sha256": "28aef96a2bbb94fbb10ade26a71238fee62a5a4d9fa6e7749ae98cfd0a65e560",
|
||||
"anchor": {
|
||||
"kind": "heading",
|
||||
"value": "B-5 · B-6 — 저장소 상실과 키 회전",
|
||||
"line": 415
|
||||
"line": 859
|
||||
}
|
||||
},
|
||||
"composition": {
|
||||
@@ -31,71 +31,91 @@
|
||||
"groups": [],
|
||||
"nodes": [
|
||||
{
|
||||
"id": "config",
|
||||
"label": "appendonly yes",
|
||||
"id": "change",
|
||||
"label": "운영 변경",
|
||||
"kind": "process",
|
||||
"role": "source",
|
||||
"emphasis": "warning",
|
||||
"description": "설정은 적용된다.",
|
||||
"emphasis": "normal",
|
||||
"description": "저장 설정과 realm 키 회전을 각각 수행한다.",
|
||||
"details": [
|
||||
"redis-cli config set"
|
||||
"B-5 · B-6"
|
||||
],
|
||||
"evidence": [
|
||||
{
|
||||
"start_line": 406,
|
||||
"end_line": 412
|
||||
"start_line": 861,
|
||||
"end_line": 872
|
||||
}
|
||||
],
|
||||
"assumption": false
|
||||
},
|
||||
{
|
||||
"id": "datadir",
|
||||
"label": "/data",
|
||||
"label": "Redis /data",
|
||||
"kind": "datastore",
|
||||
"role": "control",
|
||||
"emphasis": "warning",
|
||||
"description": "컨테이너 파일시스템이다.",
|
||||
"description": "AOF가 기록되는 컨테이너 파일시스템이다.",
|
||||
"details": [
|
||||
"appendonlydir"
|
||||
"appendonly yes · 볼륨 없음"
|
||||
],
|
||||
"evidence": [
|
||||
{
|
||||
"start_line": 406,
|
||||
"end_line": 412
|
||||
"start_line": 861,
|
||||
"end_line": 863
|
||||
}
|
||||
],
|
||||
"assumption": false
|
||||
},
|
||||
{
|
||||
"id": "container",
|
||||
"label": "컨테이너",
|
||||
"id": "lost",
|
||||
"label": "Redis 재시작",
|
||||
"kind": "component",
|
||||
"role": "target",
|
||||
"emphasis": "warning",
|
||||
"description": "죽으면 /data 도 같이 사라진다.",
|
||||
"description": "볼륨이 없어 데이터가 함께 사라진다.",
|
||||
"details": [
|
||||
"볼륨 없음"
|
||||
"영속화 실패"
|
||||
],
|
||||
"evidence": [
|
||||
{
|
||||
"start_line": 406,
|
||||
"end_line": 412
|
||||
"start_line": 861,
|
||||
"end_line": 863
|
||||
}
|
||||
],
|
||||
"assumption": false
|
||||
},
|
||||
{
|
||||
"id": "volume",
|
||||
"label": "PersistentVolume",
|
||||
"kind": "datastore",
|
||||
"role": "target",
|
||||
"emphasis": "primary",
|
||||
"description": "여기 있어야 설정이 뜻을 갖는다.",
|
||||
"details": [],
|
||||
"id": "replicas",
|
||||
"label": "echo replica 2개",
|
||||
"kind": "service",
|
||||
"role": "control",
|
||||
"emphasis": "warning",
|
||||
"description": "JWKS cache를 인스턴스마다 따로 가진다.",
|
||||
"details": [
|
||||
"replica별 cache"
|
||||
],
|
||||
"evidence": [
|
||||
{
|
||||
"start_line": 406,
|
||||
"end_line": 412
|
||||
"start_line": 868,
|
||||
"end_line": 872
|
||||
}
|
||||
],
|
||||
"assumption": false
|
||||
},
|
||||
{
|
||||
"id": "mixed",
|
||||
"label": "교차 응답",
|
||||
"kind": "component",
|
||||
"role": "target",
|
||||
"emphasis": "primary",
|
||||
"description": "같은 옛 토큰의 검증 결과가 replica에 따라 갈린다.",
|
||||
"details": [
|
||||
"401 · 200 · 반복"
|
||||
],
|
||||
"evidence": [
|
||||
{
|
||||
"start_line": 868,
|
||||
"end_line": 877
|
||||
}
|
||||
],
|
||||
"assumption": false
|
||||
@@ -104,42 +124,56 @@
|
||||
"edges": [
|
||||
{
|
||||
"id": "c-d",
|
||||
"from": "config",
|
||||
"from": "change",
|
||||
"to": "datadir",
|
||||
"label": "AOF 기록",
|
||||
"label": "AOF 설정",
|
||||
"kind": "write",
|
||||
"evidence": [
|
||||
{
|
||||
"start_line": 406,
|
||||
"end_line": 412
|
||||
"start_line": 861,
|
||||
"end_line": 863
|
||||
}
|
||||
],
|
||||
"assumption": false
|
||||
},
|
||||
{
|
||||
"id": "d-c",
|
||||
"id": "d-l",
|
||||
"from": "datadir",
|
||||
"to": "container",
|
||||
"label": "컨테이너와 함께 소멸",
|
||||
"to": "lost",
|
||||
"label": "볼륨 없음",
|
||||
"kind": "blocked",
|
||||
"evidence": [
|
||||
{
|
||||
"start_line": 406,
|
||||
"end_line": 412
|
||||
"start_line": 861,
|
||||
"end_line": 863
|
||||
}
|
||||
],
|
||||
"assumption": false
|
||||
},
|
||||
{
|
||||
"id": "d-v",
|
||||
"from": "datadir",
|
||||
"to": "volume",
|
||||
"label": "볼륨 마운트",
|
||||
"kind": "write",
|
||||
"id": "c-r",
|
||||
"from": "change",
|
||||
"to": "replicas",
|
||||
"label": "키 회전",
|
||||
"kind": "request",
|
||||
"evidence": [
|
||||
{
|
||||
"start_line": 406,
|
||||
"end_line": 412
|
||||
"start_line": 865,
|
||||
"end_line": 872
|
||||
}
|
||||
],
|
||||
"assumption": false
|
||||
},
|
||||
{
|
||||
"id": "r-m",
|
||||
"from": "replicas",
|
||||
"to": "mixed",
|
||||
"label": "cache 상태",
|
||||
"kind": "request",
|
||||
"evidence": [
|
||||
{
|
||||
"start_line": 868,
|
||||
"end_line": 877
|
||||
}
|
||||
],
|
||||
"assumption": false
|
||||
@@ -147,6 +181,6 @@
|
||||
],
|
||||
"legend": [],
|
||||
"metadata": {
|
||||
"rationale": "설정과 매체를 분리해 그렸다. 설정만 보면 두 경우 모두 되어 있는 것으로 읽힌다."
|
||||
"rationale": "B-5와 B-6를 같은 실패로 합치지 않고, 설정이 실제 매체와 인스턴스별 cache에 닿을 때 각각 어떤 결과가 나는지 두 갈래로 연결했다."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user