feat: 가상화 문서들 추가

This commit is contained in:
DongHyeonka
2026-09-10 08:54:05 +09:00
parent e9f6a93327
commit 43e1aadef0
695 changed files with 153404 additions and 12754 deletions
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,544 @@
{
"version": "1.1",
"id": "packet-control-and-data-paths",
"title": "control/setup path 는 QEMU 를 지나고 data path 는 backend 에 따라 QEMU 를 지나기도 안 지나기도 한다",
"question": "설정하는 경로와 packet 이 흐르는 경로는 어디에서 갈라지고, 그 두 갈래 가운데 어느 쪽이 QEMU 사용자 공간을 지나는가",
"type": "network",
"direction": "TB",
"audience": [
"가상 머신 안의 요청이 느릴 때 계층을 가르려는 사람",
"vhost-net 이 무엇을 우회하는지 확인하려는 사람"
],
"summary": "virsh 에서 시작한 control/setup path 는 libvirt 와 QEMU 를 지나 virtio-net Device Model 에서 backend 를 설정하고, packet 이 흐르는 data path 는 TAP 에서 그 backend 둘 가운데 하나로 갈라져 vhost-net 쪽은 QEMU 사용자 공간을 지나지 않고 virtqueue 로 모인다.",
"alt": "위쪽 줄은 virsh, libvirt, QEMU, virtio-net Device Model 로 이어지는 control/setup path 이고 아래쪽 줄은 Physical NIC 에서 TAP 까지 이어지는 data path 다. 두 줄이 vhost-net 과 QEMU virtio backend 에서 만나 virtqueue 를 지나 Guest 로 모이는 구성도.",
"long_description": "왼쪽에서 오른쪽으로 읽는다. 위쪽 줄이 control/setup path 다. virsh 에서 libvirt 와 QEMU 를 지나 virtio-net Device Model 에 닿고, 그 device model 이 virtual NIC 생성과 feature negotiation, virtqueue 설정, vhost-net backend 설정을 맡는다. 아래쪽 줄이 data path 다. Physical NIC 에서 Physical NIC Driver 와 Linux Bridge, TAP 까지 온다. 두 줄은 네 번째 열 다음에서 만난다. device model 은 점선으로 backend 둘을 설정하고, TAP 은 실선으로 그 둘 가운데 실제로 쓰는 쪽에 packet 을 넘긴다. vhost-net 을 쓰면 packet 은 Host Kernel 안에서 처리돼 QEMU 사용자 공간을 지나지 않고, QEMU virtio backend 를 쓰면 같은 packet 이 QEMU 사용자 공간을 지난다. 어느 쪽이든 virtqueue 에서 만나 Guest 로 올라간다. 이 Host 가 둘 중 어느 backend 를 쓰고 있는지는 그림이 말하지 않는다.",
"source_context": {
"document": "docs/virtualization/final/document.md",
"document_sha256": "181e2b3cc8a45bae81e7e8193d026937c4d586ae4495d3b2c323eb7e6abcfadd",
"anchor": {
"kind": "heading",
"value": "125. 최종 기준 구조",
"line": 5682
}
},
"composition": {
"profile": "component-flow",
"diagram_only": true,
"reference_ids": [
"payment-event-flow"
],
"rationale": "이 절이 세운 것은 방향이 있는 경로 셋이고 그 셋이 같은 device model 과 같은 virtqueue 를 공유한다. SSOT 는 셋을 각각 따로 선 직선으로 적어 두어서 QEMU 가 control 에는 남고 data 에서는 빠질 수 있다는 사실이 한 장에 보이지 않는다. comparison 은 관계선을 지워도 뜻이 남는 자리에 쓰는 문법이라 여기서는 표가 되고, two-zone-pipeline 은 구역을 둘로 못 나눈다 — 여기 갈래는 경계가 아니라 backend 선택이 만든다. component-flow 는 갈라졌다 모이는 경로를 그대로 옮긴다.",
"focus_node": "virtio-net-device-model"
},
"groups": [],
"nodes": [
{
"id": "virsh",
"label": "virsh",
"kind": "cli",
"role": "actor",
"shape": "box",
"details": [
"User"
],
"description": "VM/network 관리 CLI. packet datapath 에는 직접 참여하지 않는다.",
"evidence": [
{
"start_line": 5662,
"end_line": 5662
},
{
"start_line": 5687,
"end_line": 5689
}
],
"assumption": false
},
{
"id": "libvirt",
"label": "libvirt",
"kind": "service",
"role": "service",
"shape": "box",
"description": "VM lifecycle 과 NIC/network configuration 을 관리한다.",
"evidence": [
{
"start_line": 5663,
"end_line": 5663
},
{
"start_line": 5691,
"end_line": 5691
}
],
"assumption": false
},
{
"id": "qemu",
"label": "QEMU",
"kind": "process",
"role": "service",
"shape": "box",
"details": [
"Host Userspace"
],
"description": "실제로 실행되는 프로세스. 이 안에 virtio-net device model 이 있다.",
"evidence": [
{
"start_line": 5666,
"end_line": 5666
},
{
"start_line": 5693,
"end_line": 5693
}
],
"assumption": false
},
{
"id": "virtio-net-device-model",
"label": "virtio-net Device Model",
"kind": "service",
"role": "service",
"shape": "box",
"emphasis": "primary",
"details": [
"virtual NIC 생성",
"feature negotiation",
"virtqueue 설정",
"vhost-net backend 설정"
],
"description": "control/setup path 가 닿는 자리. 장치를 만들고 backend 를 연결한다.",
"evidence": [
{
"start_line": 5666,
"end_line": 5666
},
{
"start_line": 5695,
"end_line": 5700
}
],
"assumption": false
},
{
"id": "physical-nic",
"label": "Physical NIC",
"kind": "hardware",
"role": "source",
"shape": "box",
"description": "밖에서 온 packet 이 처음 닿는 하드웨어.",
"evidence": [
{
"start_line": 5706,
"end_line": 5708
}
],
"assumption": false
},
{
"id": "physical-nic-driver",
"label": "Physical NIC Driver",
"kind": "driver",
"role": "service",
"shape": "box",
"description": "그 하드웨어를 제어하는 Host kernel driver.",
"evidence": [
{
"start_line": 5674,
"end_line": 5674
},
{
"start_line": 5710,
"end_line": 5710
}
],
"assumption": false
},
{
"id": "linux-bridge",
"label": "Linux Bridge /\nRouting / NAT",
"kind": "network",
"role": "service",
"shape": "box",
"description": "L2 software switch 와 L3 routing, 주소 변환이 놓이는 자리.",
"evidence": [
{
"start_line": 5672,
"end_line": 5673
},
{
"start_line": 5712,
"end_line": 5712
}
],
"assumption": false
},
{
"id": "tap",
"label": "TAP",
"kind": "network",
"role": "service",
"shape": "box",
"details": [
"Host-side interface"
],
"description": "VM 의 Ethernet frame 과 Host Linux networking 을 잇는 접점.",
"evidence": [
{
"start_line": 5671,
"end_line": 5671
},
{
"start_line": 5714,
"end_line": 5714
}
],
"assumption": false
},
{
"id": "vhost-net",
"label": "vhost-net",
"kind": "kernel",
"role": "service",
"shape": "box",
"details": [
"Host Kernel"
],
"description": "반복되는 packet datapath 를 Host kernel 에서 처리하는 backend.",
"evidence": [
{
"start_line": 5669,
"end_line": 5669
},
{
"start_line": 5716,
"end_line": 5716
}
],
"assumption": false
},
{
"id": "qemu-virtio-backend",
"label": "QEMU virtio backend",
"kind": "process",
"role": "service",
"shape": "box",
"details": [
"QEMU Userspace"
],
"description": "vhost-net 을 쓰지 않을 때 datapath backend 를 맡는 쪽.",
"evidence": [
{
"start_line": 5668,
"end_line": 5668
},
{
"start_line": 5742,
"end_line": 5742
}
],
"assumption": false
},
{
"id": "virtqueue",
"label": "virtqueue",
"kind": "queue",
"role": "queue",
"shape": "box",
"details": [
"shared queue"
],
"description": "Guest 와 Host backend 가 I/O buffer 를 주고받는 descriptor 기반 공유 큐.",
"evidence": [
{
"start_line": 5667,
"end_line": 5667
},
{
"start_line": 5718,
"end_line": 5718
}
],
"assumption": false
},
{
"id": "guest",
"label": "Guest",
"kind": "service",
"role": "sink",
"shape": "box",
"details": [
"virtio-net Frontend Driver",
"Guest TCP/IP Stack",
"Socket",
"Keycloak"
],
"description": "packet 이 올라가 애플리케이션 socket 에 닿는 쪽.",
"evidence": [
{
"start_line": 5664,
"end_line": 5665
},
{
"start_line": 5720,
"end_line": 5726
}
],
"assumption": false
}
],
"edges": [
{
"id": "virsh-to-libvirt",
"from": "virsh",
"to": "libvirt",
"label": "Control / Setup",
"kind": "control",
"style": "solid",
"evidence": [
{
"start_line": 5662,
"end_line": 5663
},
{
"start_line": 5684,
"end_line": 5691
}
],
"assumption": false
},
{
"id": "libvirt-to-qemu",
"from": "libvirt",
"to": "qemu",
"label": "NIC/network configuration",
"kind": "control",
"style": "solid",
"evidence": [
{
"start_line": 5663,
"end_line": 5663
},
{
"start_line": 5691,
"end_line": 5693
}
],
"assumption": false
},
{
"id": "qemu-to-device-model",
"from": "qemu",
"to": "virtio-net-device-model",
"label": "QEMU process",
"kind": "control",
"style": "solid",
"evidence": [
{
"start_line": 5666,
"end_line": 5666
},
{
"start_line": 5693,
"end_line": 5695
}
],
"assumption": false
},
{
"id": "nic-to-driver",
"from": "physical-nic",
"to": "physical-nic-driver",
"label": "Ethernet Frame",
"kind": "data",
"style": "solid",
"evidence": [
{
"start_line": 5671,
"end_line": 5671
},
{
"start_line": 5708,
"end_line": 5710
}
],
"assumption": false
},
{
"id": "driver-to-bridge",
"from": "physical-nic-driver",
"to": "linux-bridge",
"label": "L2 forwarding",
"kind": "data",
"style": "solid",
"evidence": [
{
"start_line": 5672,
"end_line": 5672
},
{
"start_line": 5710,
"end_line": 5712
}
],
"assumption": false
},
{
"id": "bridge-to-tap",
"from": "linux-bridge",
"to": "tap",
"label": "Ethernet Frame",
"kind": "data",
"style": "solid",
"evidence": [
{
"start_line": 5671,
"end_line": 5671
},
{
"start_line": 5712,
"end_line": 5714
}
],
"assumption": false
},
{
"id": "setup-vhost-backend",
"from": "virtio-net-device-model",
"to": "vhost-net",
"label": "vhost-net backend 설정",
"kind": "control",
"style": "dashed",
"evidence": [
{
"start_line": 5700,
"end_line": 5700
},
{
"start_line": 5716,
"end_line": 5716
}
],
"assumption": false
},
{
"id": "setup-qemu-backend",
"from": "virtio-net-device-model",
"to": "qemu-virtio-backend",
"label": "",
"kind": "control",
"style": "dashed",
"evidence": [
{
"start_line": 5668,
"end_line": 5668
},
{
"start_line": 5700,
"end_line": 5700
}
],
"assumption": false
},
{
"id": "tap-to-vhost",
"from": "tap",
"to": "vhost-net",
"label": "vhost-net 사용",
"kind": "data",
"style": "solid",
"evidence": [
{
"start_line": 5703,
"end_line": 5703
},
{
"start_line": 5714,
"end_line": 5716
}
],
"assumption": false
},
{
"id": "tap-to-qemu-backend",
"from": "tap",
"to": "qemu-virtio-backend",
"label": "",
"kind": "data",
"style": "solid",
"evidence": [
{
"start_line": 5729,
"end_line": 5729
},
{
"start_line": 5740,
"end_line": 5742
}
],
"assumption": false
},
{
"id": "vhost-to-virtqueue",
"from": "vhost-net",
"to": "virtqueue",
"label": "Data Path",
"kind": "data",
"style": "solid",
"evidence": [
{
"start_line": 5703,
"end_line": 5703
},
{
"start_line": 5716,
"end_line": 5718
}
],
"assumption": false
},
{
"id": "qemu-backend-to-virtqueue",
"from": "qemu-virtio-backend",
"to": "virtqueue",
"label": "Data Path",
"kind": "data",
"style": "solid",
"evidence": [
{
"start_line": 5729,
"end_line": 5729
},
{
"start_line": 5742,
"end_line": 5744
}
],
"assumption": false
},
{
"id": "virtqueue-to-guest",
"from": "virtqueue",
"to": "guest",
"label": "virtio-net Frontend Driver",
"kind": "data",
"style": "solid",
"evidence": [
{
"start_line": 5664,
"end_line": 5664
},
{
"start_line": 5718,
"end_line": 5726
}
],
"assumption": false
}
],
"legend": [],
"metadata": {
"rationale": "network 으로 고른 이유는 이 절이 답하는 물음이 「어느 경로가 어느 계층을 지나는가」이기 때문이다. 점선은 설정이고 실선은 packet 이다 — 색이 아니라 선 모양으로 갈랐다. Internet/Client 와 Socket, Keycloak 은 노드로 세우지 않고 양 끝 노드의 details 로 내렸다. §125 가 적은 세 직선을 그대로 세 장으로 옮기면 SSOT 와 같은 그림이 되고, 이 글이 필요로 하는 것은 그 셋이 어디를 공유하는가다. LR 로 그렸더니 캔버스가 2249px 가 되어 TB 로 바꿨다. 갈래 구간의 엇갈리는 두 이음에 라벨을 다 붙였더니 라벨끼리 겹치고(497px²) 하나가 device model 상자에 먹혀(316px²) check-figure-overlap 이 걸렸다. 그 구간에서는 vhost-net 쪽 두 이음에만 이름을 남기고 QEMU backend 쪽 두 이음은 선 모양(점선=설정·실선=packet)과 도착 상자 이름으로 읽게 두었다."
}
}