{ "version": "1.1", "id": "two-l7-hops-entry-recursion", "title": "L7 두 홉과 진입점 이중화 재귀", "question": "요청은 왜 nginx와 Traefik이라는 두 L7 홉을 지나며, nginx를 두 대로 늘리면 왜 다시 selector가 필요한가", "type": "architecture", "direction": "LR", "audience": [ "실험대의 nginx와 Traefik 역할을 구분하려는 개발자", "진입점 이중화가 왜 새 SPOF를 만드는지 이해하려는 운영자" ], "summary": "정상 요청은 브라우저에서 edge nginx, Traefik, Pod 순으로 흐르고 두 L7 홉은 서로 다른 라우팅 범위를 맡는다. edge nginx를 두 대로 늘리면 어느 nginx를 고를 selector가 필요해지고 그 selector가 다시 단일 장애점이 된다.", "alt": "브라우저에서 edge nginx와 Traefik을 거쳐 Pod로 가는 두 L7 홉과, edge nginx를 두 대로 늘릴 때 앞단 selector가 새 단일 장애점이 되는 재귀를 함께 보여 주는 흐름도.", "long_description": "왼쪽의 정상 경로는 브라우저가 TLS를 edge nginx에서 종료하고 고정 노드 IP로 전달한 뒤, Traefik이 동적으로 Pod를 고르는 흐름이다. 아래쪽 이중화 경로는 nginx-1과 nginx-2 앞에 selector를 두면 어느 nginx로 갈지 정할 수 있지만 selector 자체가 새 SPOF가 되어 같은 질문이 반복된다는 점을 보여 준다. VRRP·DNS·BGP·클라우드 LB 같은 재귀 종료 방식의 상세 비교는 본문 표에 남기고 그림에는 넣지 않는다.", "source_context": { "document": "docs/virtualization/final/document.md", "document_sha256": "8c4ecc64c8cea9a4450ed7131fdd9cb2048dc092b66cd969f6346ed77887c210", "anchor": { "kind": "heading", "value": "261. 진입점 자체가 죽으면 — 로드밸런서의 재귀 문제", "line": 15796 } }, "composition": { "profile": "component-flow", "diagram_only": true, "reference_ids": [ "payment-event-flow" ], "rationale": "핵심은 요청과 선택 경로의 방향성이다. 비교표보다 엣지를 지웠을 때 의미가 더 크게 사라지므로 component-flow로 그린다.", "focus_node": "edge-nginx" }, "groups": [], "nodes": [ { "id": "browser", "label": "Browser", "kind": "actor", "role": "source", "shape": "actor", "description": "외부 요청의 시작점.", "evidence": [ { "start_line": 15860, "end_line": 15864 } ], "assumption": false }, { "id": "edge-nginx", "label": "edge nginx", "kind": "service", "role": "service", "emphasis": "primary", "details": [ "L7", "TLS 종료", "고정 노드 선택" ], "description": "클러스터 밖 진입점. TLS와 인증서, forwarded header, 어느 노드로 보낼지를 맡는다.", "evidence": [ { "start_line": 15860, "end_line": 15882 } ], "assumption": false }, { "id": "traefik", "label": "Traefik", "kind": "service", "role": "service", "details": [ "L7", "Ingress", "동적 Pod 선택" ], "description": "클러스터 안에서 Service/Ingress 상태를 따라 어느 Pod로 보낼지 정한다.", "evidence": [ { "start_line": 15872, "end_line": 15882 } ], "assumption": false }, { "id": "pod", "label": "Pod", "kind": "runtime", "role": "sink", "description": "Traefik이 선택한 실제 워크로드.", "evidence": [ { "start_line": 15860, "end_line": 15864 } ], "assumption": false }, { "id": "selector", "label": "앞단 selector", "kind": "service", "role": "service", "details": [ "edge redundancy" ], "description": "nginx를 여러 머신으로 이중화했을 때 어느 nginx로 갈지 정하는 새 앞단.", "evidence": [ { "start_line": 15941, "end_line": 15945 } ], "assumption": false }, { "id": "nginx-pair", "label": "nginx-1 · nginx-2", "kind": "service", "role": "service", "details": [ "서로 다른 머신" ], "description": "진짜 이중화를 위해 머신을 늘린 edge nginx 쌍.", "evidence": [ { "start_line": 15934, "end_line": 15944 } ], "assumption": false }, { "id": "new-spof", "label": "selector가 새 SPOF", "kind": "result", "role": "sink", "description": "selector를 하나 더 두면 같은 단일 장애점 질문이 한 단계 앞으로 이동한다.", "evidence": [ { "start_line": 15941, "end_line": 15952 } ], "assumption": false } ], "edges": [ { "id": "browser-edge", "from": "browser", "to": "edge-nginx", "label": "HTTPS", "kind": "request", "evidence": [ { "start_line": 15860, "end_line": 15864 } ], "assumption": false }, { "id": "edge-traefik", "from": "edge-nginx", "to": "traefik", "label": "노드 선택 · HTTP", "kind": "request", "evidence": [ { "start_line": 15872, "end_line": 15882 } ], "assumption": false }, { "id": "traefik-pod", "from": "traefik", "to": "pod", "label": "Ingress routing", "kind": "request", "evidence": [ { "start_line": 15860, "end_line": 15882 } ], "assumption": false }, { "id": "selector-pair", "from": "selector", "to": "nginx-pair", "label": "nginx 선택", "kind": "request", "style": "dashed", "evidence": [ { "start_line": 15941, "end_line": 15945 } ], "assumption": false }, { "id": "selector-spof", "from": "selector", "to": "new-spof", "label": "단일 selector", "kind": "result", "style": "dashed", "evidence": [ { "start_line": 15941, "end_line": 15952 } ], "assumption": false } ], "legend": [], "metadata": { "rationale": "두 L7 홉의 역할 차이와 진입점 이중화 재귀만 남겼다. VRRP의 상세 동작은 별도 본문 설명이므로 그림에서 제외한다." } }