{ "version": "1.1", "id": "lab-topology", "title": "실험대의 구성", "question": "이 실험들은 어떤 기계 위에서 돌았는가", "type": "architecture", "direction": "LR", "audience": [ "같은 실험을 재현하려는 백엔드 엔지니어" ], "summary": "베어메탈 한 대 위의 VM 두 대에 k3s 를 올리고, 호스트 nginx 가 TLS 를 끝낸 뒤 traefik 으로 넘긴다.", "alt": "test-server 호스트의 nginx 가 kc-lab-1 의 traefik 으로 프록시하고, 그 아래 두 VM 에 Keycloak 과 데이터 저장소가 나뉘어 있는 구성.", "long_description": "베어메탈 test-server 위에 VM 두 대를 올렸다. kc-lab-1 이 k3s server 이자 컨트롤 플레인이고 keycloak-1 이 여기 있다. kc-lab-2 는 agent 이며 keycloak-0 과 PostgreSQL, Redis 가 함께 있다. 저장소가 한 노드에 몰려 있어 그 노드를 잃으면 DB 도 같이 잃는다. 호스트 nginx 가 Let's Encrypt 인증서로 TLS 를 끝내고 traefik 으로 넘기며, 인증서 하나에 auth·app1·app2 세 이름이 SAN 으로 들어 있다.", "source_context": { "document": "docs/keycloak-session-store/final/document.md", "document_sha256": "28aef96a2bbb94fbb10ade26a71238fee62a5a4d9fa6e7749ae98cfd0a65e560", "anchor": { "kind": "heading", "value": "실험대", "line": 120 } }, "composition": { "profile": "component-flow", "diagram_only": true, "reference_ids": [ "payment-event-flow" ], "rationale": "호스트 nginx에서 traefik과 Keycloak, 저장소로 이어지는 실제 배치 경로가 지배적 질문이다. current context가 선택한 component-flow 문법을 사용한다." }, "groups": [], "nodes": [ { "id": "nginx", "label": "호스트 nginx", "kind": "gateway", "role": "source", "emphasis": "primary", "description": "Let's Encrypt 인증서로 TLS 를 끝내고 traefik 으로 넘긴다.", "details": [ "SAN: auth · app1 · app2" ], "evidence": [ { "start_line": 123, "end_line": 127 } ], "assumption": false }, { "id": "traefik", "label": "traefik (kc-lab-1)", "kind": "gateway", "role": "control", "emphasis": "normal", "description": "k3s 의 인그레스. 호스트 이름으로 서비스를 고른다.", "details": [ "k3s server 노드" ], "evidence": [ { "start_line": 120, "end_line": 122 } ], "assumption": false }, { "id": "keycloak-1", "label": "keycloak-1", "kind": "service", "role": "shard", "emphasis": "primary", "description": "컨트롤 플레인 노드에 있다.", "details": [ "kc-lab-1" ], "evidence": [ { "start_line": 120, "end_line": 120 } ], "assumption": false }, { "id": "keycloak-0", "label": "keycloak-0", "kind": "service", "role": "shard", "emphasis": "primary", "description": "저장소와 같은 노드에 있다.", "details": [ "kc-lab-2" ], "evidence": [ { "start_line": 122, "end_line": 122 } ], "assumption": false }, { "id": "stores", "label": "PostgreSQL · Redis", "kind": "datastore", "role": "store", "emphasis": "warning", "description": "둘 다 kc-lab-2 에 있다. 이 노드를 잃으면 저장소도 같이 잃는다.", "details": [ "kc-lab-2" ], "evidence": [ { "start_line": 122, "end_line": 122 } ], "assumption": false } ], "edges": [ { "id": "tls", "from": "nginx", "to": "traefik", "label": "TLS 종단", "kind": "request", "evidence": [ { "start_line": 123, "end_line": 127 } ], "assumption": false }, { "id": "to-k1", "from": "traefik", "to": "keycloak-1", "label": "라우팅", "kind": "request", "evidence": [ { "start_line": 120, "end_line": 122 } ], "assumption": false }, { "id": "to-k0", "from": "traefik", "to": "keycloak-0", "label": "라우팅", "kind": "request", "evidence": [ { "start_line": 120, "end_line": 122 } ], "assumption": false }, { "id": "k0-store", "from": "keycloak-0", "to": "stores", "label": "같은 노드", "kind": "read", "evidence": [ { "start_line": 122, "end_line": 122 } ], "assumption": false } ], "legend": [], "metadata": { "rationale": "저장소가 kc-lab-2 한 곳에 몰린 것을 그림에서 읽히게 배치했다. A-4 의 두 결과가 이 배치에서 갈린다." } }