Files
project-infra/presentation/diagrams/registry-pull-flow.drawio
T

90 lines
9.9 KiB
Plaintext

<mxfile host="app.diagrams.net">
<diagram name="Registry Pull" id="pull-flow">
<mxGraphModel dx="1422" dy="800" grid="0" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1600" pageHeight="1000" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="title" value="Registry Pull 흐름 — K3s 노드 containerd 에서 image 를 받기까지" style="text;html=1;align=center;verticalAlign=middle;fontSize=22;fontStyle=1;fontColor=#1f1f1f" vertex="1" parent="1">
<mxGeometry x="100" y="20" width="1400" height="40" as="geometry" />
</mxCell>
<mxCell id="flow-bg" value="" style="rounded=0;fillColor=#f5f9ff;strokeColor=#005599;strokeWidth=2;dashed=1;opacity=70" vertex="1" parent="1">
<mxGeometry x="40" y="80" width="900" height="880" as="geometry" />
</mxCell>
<mxCell id="flow-header" value="정상 Pull 경로 (Pod 가 새 이미지 필요 → 노드 캐시까지)" style="text;align=center;fontSize=18;fontStyle=1;fontColor=#005599;verticalAlign=middle" vertex="1" parent="1">
<mxGeometry x="60" y="95" width="860" height="36" as="geometry" />
</mxCell>
<mxCell id="p1" value="① K8s API server&#10;&#10;Pod 생성/재시작 → scheduler 가 node X 에 배정&#10;(spec.image = registry.project.com/.../auth-server:tag)" style="rounded=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=13;fontStyle=1;verticalAlign=middle;align=center;whiteSpace=wrap;html=1" vertex="1" parent="1">
<mxGeometry x="240" y="150" width="500" height="80" as="geometry" />
</mxCell>
<mxCell id="p2" value="② kubelet (node X)&#10;&#10;CRI 호출: containerd 에게 &#34;이 이미지 pull 해줘&#34;&#10;imagePullSecrets 의 dockerconfigjson 도 같이 전달" style="rounded=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=13;verticalAlign=middle;align=center;whiteSpace=wrap;html=1" vertex="1" parent="1">
<mxGeometry x="240" y="260" width="500" height="80" as="geometry" />
</mxCell>
<mxCell id="p3" value="③ containerd 의 image resolver&#10;&#10;/var/lib/rancher/k3s/agent/etc/containerd/certs.d/&#10;&lt;hostname&gt;/hosts.toml 을 보고 endpoint 결정" style="rounded=1;fillColor=#fff2cc;strokeColor=#d6b656;fontSize=13;verticalAlign=middle;align=center;whiteSpace=wrap;html=1" vertex="1" parent="1">
<mxGeometry x="240" y="370" width="500" height="80" as="geometry" />
</mxCell>
<mxCell id="p4" value="④ HTTP GET /v2/&lt;name&gt;/manifests/&lt;tag&gt;&#10;&#10;Authorization: Basic ... (hosts.toml 의 auth 또는 imagePullSecret)" style="rounded=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=13;verticalAlign=middle;align=center;whiteSpace=wrap;html=1" vertex="1" parent="1">
<mxGeometry x="240" y="480" width="500" height="80" as="geometry" />
</mxCell>
<mxCell id="p5" value="⑤ Traefik Ingress&#10;&#10;BasicAuth middleware 통과 → Registry Pod 로 routing" style="rounded=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=13;verticalAlign=middle;align=center;whiteSpace=wrap;html=1" vertex="1" parent="1">
<mxGeometry x="240" y="590" width="500" height="70" as="geometry" />
</mxCell>
<mxCell id="p6" value="⑥ Registry Pod&#10;&#10;REGISTRY_STORAGE_REDIRECT_DISABLE=true&#10;Registry 가 MinIO 와 직접 통신 → blob 데이터 응답에 그대로 흘림" style="rounded=1;fillColor=#d5e8d4;strokeColor=#82b366;fontSize=13;verticalAlign=middle;align=center;whiteSpace=wrap;html=1" vertex="1" parent="1">
<mxGeometry x="240" y="690" width="500" height="100" as="geometry" />
</mxCell>
<mxCell id="p7" value="⑦ node X 의 containerd image store 에 캐시 → 컨테이너 시작" style="rounded=1;fillColor=#d5e8d4;strokeColor=#006600;strokeWidth=3;fontSize=13;fontStyle=1;verticalAlign=middle;align=center;whiteSpace=wrap;html=1" vertex="1" parent="1">
<mxGeometry x="240" y="820" width="500" height="60" as="geometry" />
</mxCell>
<mxCell id="p-arrow-1" style="endArrow=classic;html=1;strokeWidth=2;strokeColor=#666666" edge="1" parent="1" source="p1" target="p2"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="p-arrow-2" style="endArrow=classic;html=1;strokeWidth=2;strokeColor=#666666" edge="1" parent="1" source="p2" target="p3"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="p-arrow-3" style="endArrow=classic;html=1;strokeWidth=2;strokeColor=#666666" edge="1" parent="1" source="p3" target="p4"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="p-arrow-4" style="endArrow=classic;html=1;strokeWidth=2;strokeColor=#666666" edge="1" parent="1" source="p4" target="p5"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="p-arrow-5" style="endArrow=classic;html=1;strokeWidth=2;strokeColor=#666666" edge="1" parent="1" source="p5" target="p6"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="p-arrow-6" style="endArrow=classic;html=1;strokeWidth=2;strokeColor=#006600" edge="1" parent="1" source="p6" target="p7"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="trap-bg" value="" style="rounded=0;fillColor=#fff5f5;strokeColor=#cc0000;strokeWidth=2;dashed=1;opacity=70" vertex="1" parent="1">
<mxGeometry x="970" y="80" width="600" height="880" as="geometry" />
</mxCell>
<mxCell id="trap-header" value="이 경로의 함정 3가지" style="text;align=center;fontSize=18;fontStyle=1;fontColor=#cc0000;verticalAlign=middle" vertex="1" parent="1">
<mxGeometry x="990" y="95" width="560" height="36" as="geometry" />
</mxCell>
<mxCell id="trap1" value="⚠ 함정 1 — K3s 자동 hosts.toml 생성 (③ 단계)&#10;&#10;registries.yaml 이 존재하면 K3s 가 hosts.toml 을&#10;매번 재생성 (사용자 작성을 덮어씀)" style="rounded=1;fillColor=#fbe5d6;strokeColor=#d79b00;fontSize=12;fontStyle=1;verticalAlign=middle;align=left;spacingLeft=10;spacingTop=8;whiteSpace=wrap;html=1" vertex="1" parent="1">
<mxGeometry x="990" y="150" width="560" height="90" as="geometry" />
</mxCell>
<mxCell id="trap1-code" value="server = &#34;https://registry.project.com/v2&#34; ← HTTPS 강제&#10;[host.&#34;http://registry.project.com/v2&#34;] ← /v2 path 박힘" style="rounded=0;fillColor=#1f1f1f;strokeColor=#000000;fontSize=11;fontColor=#ffffff;fontStyle=0;fontFamily=Courier New;verticalAlign=middle;align=left;spacingLeft=10;whiteSpace=wrap;html=1" vertex="1" parent="1">
<mxGeometry x="1010" y="250" width="520" height="50" as="geometry" />
</mxCell>
<mxCell id="trap1-effect" value="origin (server) 이 HTTP registry 와 mismatch&#10;→ containerd 가 호출 자체 안 함 → &#34;not found&#34;&#10;&#10;해결: registries.yaml 제거 + hosts.toml 직접 작성&#10;(server = http://... 명시)" style="rounded=1;fillColor=#fbe5d6;strokeColor=#d79b00;fontSize=12;verticalAlign=middle;align=left;spacingLeft=10;spacingTop=8;whiteSpace=wrap;html=1" vertex="1" parent="1">
<mxGeometry x="990" y="310" width="560" height="100" as="geometry" />
</mxCell>
<mxCell id="trap2" value="⚠ 함정 2 — BasicAuth 자격증명 전달 경로 (④ 단계)&#10;&#10;registry 자체엔 auth 없음. Traefik middleware 가 강제.&#10;&#10;containerd 에 자격증명 도달 경로 두 가지:&#10; (a) imagePullSecrets → kubelet → containerd CRI&#10; (b) hosts.toml 의 [host.*.auth] (노드 단에서 자동)&#10;&#10;둘 중 하나라도 안 박히면 401 → &#34;not found&#34; 표시&#10;실전: (b) 가 더 안정적 — imagePullSecrets 누락 면역" style="rounded=1;fillColor=#fbe5d6;strokeColor=#d79b00;fontSize=12;verticalAlign=middle;align=left;spacingLeft=10;spacingTop=8;whiteSpace=wrap;html=1" vertex="1" parent="1">
<mxGeometry x="990" y="430" width="560" height="220" as="geometry" />
</mxCell>
<mxCell id="trap3" value="⚠ 함정 3 — hosts.toml 은 노드별 (③ 단계)&#10;&#10;Pod 가 어느 node 에 scheduling 될지 모름&#10;&#10;node X 에만 설정하고 node Y 는 default 라면&#10;Pod 가 node Y 에 떠서 fail&#10;&#10;K3s 의 server node 도 default schedulable 이므로&#10;control-plane 까지 모든 노드에 동일하게 적용 필요&#10;&#10;dev: 노드 3대 모두 hosts.toml 일치&#10;운영: Ansible / cloud-init 으로 source-of-truth 관리" style="rounded=1;fillColor=#fbe5d6;strokeColor=#d79b00;fontSize=12;verticalAlign=middle;align=left;spacingLeft=10;spacingTop=8;whiteSpace=wrap;html=1" vertex="1" parent="1">
<mxGeometry x="990" y="670" width="560" height="220" as="geometry" />
</mxCell>
<mxCell id="trap1-link" style="endArrow=classic;html=1;strokeWidth=2;strokeColor=#d79b00;dashed=1;exitX=0;exitY=0.5;entryX=1;entryY=0.5" edge="1" parent="1" source="trap1" target="p3"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="trap2-link" style="endArrow=classic;html=1;strokeWidth=2;strokeColor=#d79b00;dashed=1;exitX=0;exitY=0.5;entryX=1;entryY=0.5" edge="1" parent="1" source="trap2" target="p4"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="trap3-link" style="endArrow=classic;html=1;strokeWidth=2;strokeColor=#d79b00;dashed=1;exitX=0;exitY=0.5;entryX=1;entryY=0.5" edge="1" parent="1" source="trap3" target="p3"><mxGeometry relative="1" as="geometry"/></mxCell>
<mxCell id="legend" value="🟦 정상 컴포넌트 🟨 주의 지점 (설정 의존) 🟩 해결 / 결과 🟧 함정 — 점선이 가리키는 단계에서 발생" style="rounded=1;fillColor=#fafafa;strokeColor=#999999;fontSize=13;verticalAlign=middle;align=center;whiteSpace=wrap;html=1" vertex="1" parent="1">
<mxGeometry x="160" y="970" width="1280" height="24" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>