콘텐츠로 이동

인프라 · Single Edge

네트워크

VM 연결 방식부터 tenant 격리, 트래픽 정책, 가속과 관측까지 네트워크 서비스를 구성 순서와 실제 확인 지점에 맞춰 설명합니다.

PureCVisor 네트워크 서비스는 한 Single Edge 호스트에서 VM의 연결 방식, 주소 할당, 외부 통신, tenant 격리와 트래픽 정책을 함께 관리하는 로컬 네트워크 제어면입니다.
purecvisorsd가 CLI, Web UI와 REST/RPC 요청을 받아 Linux bridge, dnsmasq, nftables, TC, OVS/OVN과 VM persistent XML에 필요한 상태를 적용합니다.
패킷은 데몬을 경유하지 않고 선택한 Linux/KVM 데이터 경로로 흐르며, 데몬은 구성의 생성·조회·복구와 권한·감사 경계를 담당합니다.

구성 영역네트워크 서비스가 제공하는 기능주요 구현과 확인 지점
기본 VM 연결NAT, 격리, 라우팅, 물리 LAN 연결pcvctl network, Linux bridge, dnsmasq, nftables
tenant 네트워크VPC, IPv4 subnet, 정지 VM attachment, 제한형 Service Publishpcvctl vpc, Linux Local VPC, Web UI 인프라 > Local VPC
트래픽 정책방화벽, Security Group, QoS, IDS/IPSnftables, TC, Suricata
오버레이·가속 경로VLAN, VXLAN, OVN, DPDK, SR-IOV기능별 상태 명령과 이 장의 전용 제약
관측과 복구host 기준선, desired/actual 상태, 네트워크 메트릭/api/v1/networks/host-baseline, network list, vpc status, Prometheus

기본 네트워크와 Local VPC는 목적이 다릅니다.
기본 네트워크는 VM을 하나의 bridge 또는 물리 LAN에 직접 연결하는 단순한 호스트 네트워크이고, Local VPC는 tenant, subnet, attachment와 게시 서비스를 하나의 desired state로 관리하는 격리 경계입니다.
Local VPC를 사용하는 VM NIC는 VPC attachment 절차로 연결해야 하며, VPC가 관리하는 bridge를 일반 network.* 명령이나 vm.create network_bridge로 수정하면 안 됩니다.

요구 사항권장 방식선택 이유
사설 주소를 사용하는 VM의 외부 접속nat내부 DHCP와 outbound NAT를 함께 구성합니다.
외부와 단절된 VM 간 통신isolatedhost 내부 bridge에만 트래픽을 유지합니다.
upstream 장비가 VM subnet을 정적으로 라우팅routed주소 변환 없이 host를 다음 홉으로 사용합니다.
VM 전용 물리 NIC를 upstream LAN에 연결bridge/dedicatedhost L3가 없는 전용 NIC를 bridge port로 편입합니다.
host 관리 연결을 유지하면서 같은 물리 LAN 사용bridge/sharedhost IP·route·DNS를 이동하지 않고 VM L2를 중계합니다.
tenant별 subnet·정책·선택적 inbound 게시Local VPClinux backend현재 공개 지원 경계 안에서 수명주기와 격리를 함께 관리합니다.

구성 전에는 ip -br link, ip -4 route와 Web UI의 호스트 네트워크 기준선을 함께 확인합니다.
새 CIDR은 host connected CIDR과 다른 VPC subnet에 겹치지 않아야 합니다.
물리 NIC를 사용할 때는 관리 경로인지 먼저 판별하고, dedicatedshared 중 하나를 명시적으로 선택해야 합니다.
특히 원격 접속에 사용하는 NIC를 bridge/dedicated 대상으로 선택하면 안 됩니다.

일반 네트워크 변경은 결과를 다시 조회해 bridge, DHCP와 정책 상태를 확인합니다.
Local VPC 변경은 accepted 응답만으로 성공으로 판단하지 않고 CLI의 terminal 결과 또는 jobs.getcompleted를 확인한 뒤 vpc status로 actual state를 검증합니다.
현재 공개 지원 backend는 linux이며, ovn은 이 장에 명시된 추가 검증을 모두 통과하기 전까지 구현 후보로 취급합니다.

Single Edge · 네트워크 서비스와 실제 패킷 경로
Linux/KVM actual state 확대해서 보기
Web UI와 pcvctl 요청이 purecvisorsd의 네트워크 제어면으로 들어와 기본 연결, 가상 네트워크, 정책, 가속과 관측 서비스로 나뉘고 Linux bridge, nftables, OVS, OVN, WireGuard, VFIO, IOMMU와 libvirt VM NIC에 적용되는 Single Edge 네트워크 구성도
위쪽 청록색 화살표는 구성·조회·복구 제어 흐름이고, 아래쪽 회색 화살표는 VM 패킷이 흐르는 Linux/KVM 데이터 경로입니다. 주황색 점선은 DPDK·SR-IOV 가속 우회 경로이며, Local VPC의 OVN backend는 추가 검증 전 후보로 구분했습니다. 마우스 환경에서는 서비스 또는 컴포넌트에 포인터를 올리면 직접 연결된 흐름이 움직이며 강조됩니다.

예제 1 — NAT 네트워크에 VM 연결

섹션 제목: “예제 1 — NAT 네트워크에 VM 연결”

이 예제는 별도의 upstream VLAN이나 물리 NIC 변경 없이 VM에 사설 주소와 외부 방향 통신을 제공하는 가장 단순한 구성입니다.
10.44.0.0/24가 host route와 기존 VM/VPC 대역에 사용되지 않는지 먼저 확인합니다.

Terminal window
# 1. host와 기존 관리형 네트워크의 충돌 여부를 확인한다.
ip -br link
ip -4 route show table main
pcvctl network list
# 2. gateway 10.44.0.1을 사용하는 NAT 네트워크를 만든다.
pcvctl network create app-nat --mode nat --cidr 10.44.0.1/24
# 3. 새 VM NIC를 app-nat에 연결한다.
pcvctl vm create web-demo \
--vcpu 2 \
--memory_mb 2048 \
--disk_size_gb 20 \
--storage_type qcow2 \
--network_bridge app-nat \
--qos_min_mbps 0 \
--qos_max_mbps 1000
# 4. VM을 시작하고 제어면과 host actual state를 확인한다.
pcvctl vm start web-demo
pcvctl network list
pcvctl vm list
ip -br address show app-nat
sudo nft list ruleset

게스트 OS의 NIC가 DHCP를 사용하면 10.44.0.0/24에서 주소를 받고 host의 NAT 경계를 통해 외부로 나갑니다.
NAT 네트워크 생성만으로 외부에서 게스트로 들어오는 포트가 자동 공개되지는 않습니다.
외부 inbound가 필요하고 tenant 단위 수명주기까지 관리하려면 다음 Local VPC 예제처럼 Service Publish를 사용합니다.

예제 2 — Local VPC의 웹 서비스를 허용된 네트워크에 게시

섹션 제목: “예제 2 — Local VPC의 웹 서비스를 허용된 네트워크에 게시”

이 예제는 acme tenant의 웹 subnet을 만들고, 정지 상태의 web-prod VM을 연결한 뒤 host TCP 8443을 게스트 TCP 443으로 제한 게시합니다.
web-prod는 미리 생성되어 정지 상태여야 하고, 연결할 Security Group은 게스트 TCP 443을 허용해야 합니다.
아래 198.51.100.10192.0.2.0/24는 RFC 문서용 주소이므로 실행 전 실제 node IPv4와 허용할 클라이언트 CIDR로 반드시 바꿉니다.

Terminal window
# 1. 공개 지원 backend와 현재 capacity를 확인한다.
pcvctl vpc backends
# 2. Linux NAT VPC와 첫 subnet을 한 Job으로 생성한다.
pcvctl vpc create app-vpc --tenant acme --egress nat \
--backend linux --subnet-name web --cidr 10.60.10.0/24 --mtu 1500
# 3. terminal 완료 뒤 aggregate에서 VPC와 subnet UUID를 확인한다.
pcvctl vpc list --tenant acme
VPC_ID="replace-with-vpc-uuid"
SUBNET_ID="replace-with-subnet-uuid"
pcvctl vpc get "$VPC_ID" --tenant acme
# 4. 정지 VM을 연결하고 완료 응답의 attachment UUID를 확인한다.
pcvctl vpc attachment-create "$SUBNET_ID" web-prod --tenant acme
ATTACHMENT_ID="replace-with-attachment-uuid"
pcvctl vpc get "$VPC_ID" --tenant acme
# 5. 문서용 주소를 실제 운영 값으로 교체한 뒤 서비스 하나만 게시한다.
NODE_IPV4="198.51.100.10"
ALLOWED_CLIENT_CIDR="192.0.2.0/24"
pcvctl vpc service-publish "$ATTACHMENT_ID" --tenant acme \
--protocol tcp --listen-address "$NODE_IPV4" --listen-port 8443 \
--target-port 443 --allowed-source "$ALLOWED_CLIENT_CIDR"
# 6. VM을 시작하고 게시 상태와 전체 수렴 상태를 확인한다.
pcvctl vm start web-prod
pcvctl vpc service-list "$VPC_ID" --tenant acme
pcvctl vpc status

listen_address를 특정 node IPv4로 제한하면 다른 host 주소에는 같은 포트가 열리지 않습니다.
0.0.0.0은 모든 host IPv4에 게시한다는 의미이므로 명확한 운영 사유가 있을 때만 사용합니다.
Service Publish는 게스트 서비스 시작, Security Group 허용 또는 인증서를 대신하지 않으므로 허용된 클라이언트에서 실제 응답까지 별도로 확인합니다.
명령이 실패하면 vpc statusreconcile_required, resource의 last_error와 해당 Job의 terminal 오류를 먼저 확인합니다.

아래 표는 공개 네트워크 서비스 전체를 실제 작업 예제와 연결합니다.
한 예제에서 여러 기능을 함께 쓰더라도 각 서비스의 생성 또는 적용 명령과 actual state 확인 지점을 해당 절에 따로 제시합니다.

서비스활용 시나리오적용 후 확인
기본 브릿지 네트워크NAT, 내부 격리, upstream 정적 route, 전용·공유 물리 LANpcvctl network list, ip -br link, upstream DHCP 또는 route
관리형 방화벽NAT와 isolated 네트워크 경계를 자동 생성sudo nft list table inet purecvisor
VLANVM NIC를 upstream VLAN 100에 연결virsh dumpxml<vlan>과 switch port
QoSVM·tenant별 최소/최대 대역 SLA 적용qos.vm.get, qos.tenant.get, qos.stats
OVS VXLAN·tenant overlay수동 VXLAN peer와 tenant 암호화 격리pcvctl overlay info, tenant_overlay.get, ovs-vsctl show
generic OVN논리 스위치·라우터·DHCP·ACL·SNAT 구성pcvctl ovn status, 리소스별 list, 인증 REST 필터
Security Group웹 VM의 80·443과 관리 CIDR의 22만 허용그룹 목록, VM binding, nft actual rule
DPDK전용 NIC를 vfio-pci에 바인딩해 OVS-DPDK bridge 구성pcvctl dpdk list, ovs-vsctl show
SR-IOVVF에 VLAN·spoof check를 설정하고 VM에 직접 할당pcvctl sriov list, VM hostdev XML
네트워크 디버깅VM 통신 장애를 link→bridge→policy→overlay 순서로 격리계층별 actual 명령의 일치 여부
Prometheus 메트릭NIC error·drop과 conntrack 포화를 관측/api/v1/metrics 필터 결과
Suricata IDS/IPS보안 10.12에서 탐지 상태 확인 후 선택 SID만 인라인 차단IPS status, drop list, 보안 이벤트
Local VPCtenant subnet의 VM 서비스를 허용 CIDR에 제한 게시Job terminal, vpc get, vpc service-list, vpc status

활용 예제 — 연결 목적에 맞는 기본 네트워크 생성

섹션 제목: “활용 예제 — 연결 목적에 맞는 기본 네트워크 생성”

아래 다섯 모드는 같은 기능의 단계가 아니라 서로 다른 연결 목적입니다.
호스트의 connected CIDR과 겹치지 않는 대역을 고르고, 물리 LAN을 사용하는 두 모드는 NIC 역할과 복구 경로를 먼저 확인합니다.
dedicated에는 원격 관리 NIC를 사용하지 않고, shared는 host L3 보존 조건과 upstream의 다중 source MAC 허용 여부를 확인합니다.

연결 mode와 CIDR 또는 uplink 선택이 PureCVisor desired state와 Linux bridge, dnsmasq, nftables 또는 물리 uplink를 거쳐 VM NIC actual state로 이어지는 구성도
입력한 연결 목적이 host 데이터 경로와 VM NIC에 어떻게 반영되는지 먼저 확인합니다.
Terminal window
# NAT 모드: 사설 DHCP 주소와 outbound NAT
pcvctl network create app-nat --mode nat --cidr 10.44.0.1/24
# 전용 업링크: 호스트 IP/기본 경로가 없는 VM 전용 유선 NIC
pcvctl network create prod-net --mode bridge --iface enp5s0 \
--uplink-mode dedicated --confirm-dedicated-uplink
# 공유 업링크: 호스트가 사용 중인 유선 NIC의 IP/route/DNS를 유지
pcvctl network create shared-lan --mode bridge --iface enp4s0 \
--uplink-mode shared --confirm-shared-uplink
# 격리 모드: host 내부 VM 간 통신만 허용
pcvctl network create lab-isolated --mode isolated --cidr 10.45.0.1/24 --mtu 1500
# 라우티드 모드: upstream에 10.46.0.0/24 경로를 별도로 선언
pcvctl network create routed-net --mode routed --cidr 10.46.0.1/24
# desired state와 host actual bridge를 함께 확인
pcvctl network list
ip -br link
모드설명외부 접근DHCP
natiptables/nftables MASQUERADEO (NAT)자동
bridge/dedicated전용 물리 NIC를 Linux bridge port로 편입(호스트 IP 없음)O (upstream 직접)upstream
bridge/shared물리 NIC의 호스트 L3를 유지하고 TC-BPF portal로 VM L2만 중계O (동일 LAN 직접)upstream
isolated외부 격리, VM 간만 통신X자동
routed정적 라우팅O (라우팅)선택

bridge/dedicated는 관리 NIC를 자동 변환하지 않는다.
서버는 IPv4 주소, link-local 외 IPv6 주소, IPv4/IPv6 기본 경로, 기존 master가 있거나 bond/VLAN이거나 상태를 확정할 수 없는 NIC를 거부한다.
호스트 관리 IP·route·DNS를 Linux bridge로 옮기려면 Web UI/RPC가 아니라 사용 중인 Netplan/NetworkManager/systemd-networkd의 선언적 설정과 out-of-band 복구 수단을 사용한다.
network bind는 원자 rollback을 제공할 수 없어 deprecated·차단되며, 물리 NIC 연결은 위 network create --mode bridge 트랜잭션으로만 수행한다.
bridge/shared는 물리 NIC를 bridge port로 만들거나 host IP·route·DNS·renderer profile을 이동하지 않는다.
내부 unnumbered bridge와 veth portal, 물리 NIC의 PureCVisor 소유 TC-BPF filter만 사용한다.
최초 지원 범위는 untagged 유선 Ethernet 한 개이며 Wi-Fi, bond, VLAN, trunk는 거부한다.
상위 스위치 포트가 여러 source MAC을 허용해야 VM이 upstream DHCP에서 호스트와 같은 LAN 대역의 독립 주소를 받을 수 있다.
port-security가 VM MAC을 막아도 호스트 경로는 그대로 유지되며 NAT로 자동 fallback하지 않는다.

shared bridge는 고정 guest MAC이나 IP를 미리 만들지 않는다.
각 KVM VM NIC는 생성·연결 시점의 독립 MAC을 사용하고 upstream DHCP 또는 정적 설정으로 주소를 얻는다.
2026-08-14 검증 예제의 02:16:3e:44:55:66192.0.2.50은 예약값이 아니다.
실제 배포에서는 충돌하지 않는 게스트 MAC과 upstream 네트워크의 주소 정책을 사용한다.

두 physical bridge 모드는 network mode로 live 전환할 수 없다.
먼저 관리형 삭제 경로로 NIC를 분리·원상복구한 뒤 원하는 모드로 다시 생성한다.
일반 삭제 경로도 desired state가 없는 host uplink를 발견하면 네트워크를 건드리지 않고 거부한다.
physical bridge의 DHCP 활성화도 차단되며 게스트 주소 할당은 upstream 네트워크가 담당한다.

Terminal window
# 네트워크 목록
pcvctl network list
# uplink mode·dataplane·host L3 보존 필드를 포함한 상세 목록
sudo pcvctl --format=json network list
# DHCP 토글
pcvctl network dhcp mgmt-net --enable
pcvctl network dhcp mgmt-net --disable
# standalone 물리 NIC 바인딩은 차단됨 — 업링크 방식은 생성 시 함께 지정
pcvctl network create shared-lan --mode bridge --iface enp4s0 \
--uplink-mode shared --confirm-shared-uplink
# 삭제 (멱등: 존재하지 않아도 성공)
pcvctl network delete mgmt-net

RPC 직접 호출:

Terminal window
# 네트워크 생성
echo '{"jsonrpc":"2.0","method":"network.create","params":{
"bridge_name": "mgmt-net",
"mode": "nat",
"cidr": "192.168.100.0/24"
},"id":"1"}' | nc -U /var/run/purecvisor/daemon.sock | python3 -m json.tool
# 네트워크 목록
echo '{"jsonrpc":"2.0","method":"network.list","params":{},"id":"1"}' \
| nc -U /var/run/purecvisor/daemon.sock | python3 -m json.tool

메타데이터와 desired state: /var/run/purecvisor/network/dnsmasq-<bridge>.meta는 현재 부팅의 조회 캐시다.
dedicated/shared physical bridge의 재부팅 복구 정본은 mode 0600/var/lib/purecvisor/networks/<bridge>.json이다.
NAT/isolated/routed의 구성 정본은 기존 설정·운영 계약을 따른다.

멱등 삭제: network.delete는 대상이 없어도 성공을 반환합니다 (재시도 안전).

게스트 MTU 계약(N8): bridge NIC XML(정의 XML·vm.start 라이브 attach·핫플러그, 3경로 모두)은 attach/정의 시점 브리지 실측 MTU(/sys/class/net/<bridge>/mtu 단일 소스)로 <mtu size='N'/>를 1500 포함 항상 명시한다.
유효 대역은 68–9216이며, 읽기 실패나 대역 밖 값은 생략 + 경고로 fail-open 한다(attach 자체는 계속 진행).
dpdk(vhostuser)·SR-IOV(hostdev) 경로는 범위 밖이다.
설계 근거: ADR-0033.

PureCVisor는 nftables를 기본 네트워크, Security Group, Local VPC와 Suricata IPS의 공통 host 정책 경계로 사용합니다.
사용자가 임의 chain에 규칙을 넣는 독립 firewall.rule.* 공개 RPC는 없으며, 서비스의 desired state를 변경하면 데몬이 소유한 규칙을 함께 생성·복구·정리합니다.

활용 예제 — NAT와 내부 격리 경계 비교

섹션 제목: “활용 예제 — NAT와 내부 격리 경계 비교”

아래 예제는 외부 통신이 필요한 workload와 외부에서 분리할 workload를 서로 다른 관리형 네트워크에 둡니다.
NAT 쪽에는 outbound masquerade가 생기고, isolated 쪽은 같은 bridge의 VM 간 통신만 남습니다.

NAT 또는 isolated network mode가 purecvisorsd의 관리형 정책을 거쳐 nftables inet purecvisor 테이블과 VM 허용 범위에 반영되는 구성도
서비스 desired state와 nftables actual state를 함께 비교해야 정책 적용을 확인할 수 있습니다.
Terminal window
# 서로 겹치지 않는 두 네트워크를 생성한다.
pcvctl network create policy-nat --mode nat --cidr 10.47.0.1/24
pcvctl network create policy-isolated --mode isolated --cidr 10.48.0.1/24
# desired state와 데몬 소유 nft actual state를 함께 확인한다.
pcvctl network list
sudo nft list table inet purecvisor

VM 단위 포트 허용은 §6.7 Security Group을 사용하고, tenant subnet과 inbound 게시 수명주기는 §6.12 Local VPC를 사용합니다.
데몬이 소유한 inet purecvisor table을 운영자가 직접 수정하면 desired state와 actual state가 어긋나므로 영구 설정 절차로 사용하지 않습니다.

명령 실행 안전성: 모든 방화벽 조작은 pcv_spawn_sync() argv 배열로 실행됩니다.
system()popen()은 사용하지 않습니다.

VM NIC의 persistent libvirt XML에 802.1Q VLAN tag를 지정할 수 있습니다.
vlan_id는 고급 VM 속성이므로 현재 pcvctl vm create 옵션이 아니라 REST 또는 JSON-RPC body로 전달하며, 공개 network.vlan.add RPC는 없습니다.

활용 예제 — VM을 upstream VLAN 100에 연결

섹션 제목: “활용 예제 — VM을 upstream VLAN 100에 연결”

이 예제의 pcvbr0는 VLAN 100을 전달할 수 있는 Linux bridge 또는 OVS bridge여야 합니다.
upstream switch port도 VLAN 100을 허용해야 하며, native VLAN과 guest tag 정책은 호스트 밖의 switch 설정과 일치해야 합니다.

VLAN 100 입력이 PureCVisor 검증과 libvirt persistent XML의 VM NIC tag를 거쳐 bridge와 upstream trunk로 이어지는 구성도
VM NIC의 VLAN tag와 upstream trunk 허용 목록이 같은 값으로 이어져야 합니다.
Terminal window
# VM 생성 body에 VLAN 100을 지정한다.
echo '{"jsonrpc":"2.0","method":"vm.create","params":{
"name":"web-vlan","vcpu":2,"memory_mb":2048,"disk_size_gb":20,
"storage_type":"qcow2","network_bridge":"pcvbr0","vlan_id":100,
"qos_min_mbps":0,"qos_max_mbps":1000
},"id":"1"}' | nc -U /var/run/purecvisor/daemon.sock | python3 -m json.tool
# persistent XML에 VLAN tag가 남았는지 확인한다.
sudo virsh dumpxml web-vlan
sudo virsh domiflist web-vlan

dumpxml의 VM interface 아래에 <vlan><tag id="100"/></vlan>이 있어야 합니다.
게스트에서 주소를 받지 못하면 VM XML만 반복 수정하지 말고 bridge의 VLAN filtering과 upstream trunk 허용 목록을 함께 확인합니다.

TC 기반 네트워크 QoS를 지원합니다.
인터페이스 단위 network.qos.*는 기존 자동화 호환용 deprecated 표면이며, 새 구성은 VM·tenant SLA를 지속적으로 식별하고 reconcile하는 qos.vm.*qos.tenant.*를 우선합니다.

활용 예제 — 기존 vnet 제한과 VM·tenant SLA 적용

섹션 제목: “활용 예제 — 기존 vnet 제한과 VM·tenant SLA 적용”
VM 또는 tenant의 대역폭 SLA가 PureCVisor QoS handler와 Linux TC qdisc, filter를 거쳐 실제 rate와 drop 통계로 이어지는 구성도
desired SLA와 실제 vnet의 TC 통계를 함께 확인해 대역폭 제한의 수렴 여부를 판단합니다.
Terminal window
# 기존 vnet 자동화와의 호환이 필요할 때만 인터페이스 상한을 설정한다.
pcvctl network qos-set vnet0 --rate-mbps 100 --burst-kb 64
# 실제 tc 적용 상태를 조회한다.
pcvctl network qos-get vnet0
# 호환 규칙이 더 필요하지 않으면 제거한다.
pcvctl network qos-remove vnet0

호환 표면 영속화: network.qos.* 규칙은 /var/run/purecvisor/qos_rules.json에 저장되어 데몬 재시작 시 복원됩니다.
새 workload SLA의 정본으로 사용하지 않습니다.

고급 QoS — per-VM/tenant SLA (2.0, D09)

섹션 제목: “고급 QoS — per-VM/tenant SLA (2.0, D09)”

2.0은 위 인터페이스별 tc 셰이핑(network qos-*) 위에, VM·테넌트 단위 대역폭 SLA를 강제하는 고급 QoS 계층을 추가했습니다.
단일 IFB 디바이스 pcvqos0 위에 단일 HFSC 트리(단일 major 1:, VM·테넌트별 minor 파생)를 세우고, 각 VM leaf는 Cake(besteffort) qdisc로 성형합니다.
class 배정은 이름 기반 결정적 계산이라 데몬을 재시작해도 같은 VM은 같은 class를 다시 씁니다(reconcile).
테넌트 SLA는 /var/lib/purecvisor/qos_tenants.json(재부팅 생존)에, tc id 매핑은 /var/run/purecvisor/qos_ids.json(tmpfs, 커널 tc 트리와 동일 수명)에 영속화됩니다.

RPC 전용(2.0): qos.* 네임스페이스는 전용 REST 경로·CLI 서브커맨드·UI 페이지가 없습니다.
POST /api/v1/rpc JSON-RPC 패스스루(또는 UDS 직접 nc -U)로만 호출합니다.

메서드RBAC파라미터용도
qos.vm.setADMIN{vm, qos_min_mbps, qos_max_mbps, [qos_burst_kb]}per-VM 대역폭 SLA 설정
qos.vm.getVIEWER{vm}per-VM SLA 조회
qos.tenant.setADMIN{tenant, min_mbps, max_mbps}per-tenant 대역폭 SLA 설정
qos.tenant.getVIEWER{tenant}per-tenant SLA 조회
qos.statsVIEWER{[tenant]}QoS 강제 통계(테넌트 필터 선택)
Terminal window
# per-VM SLA 설정 (POST /api/v1/rpc 패스스루)
curl -s -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
http://127.0.0.1:8080/api/v1/rpc \
-d '{"jsonrpc":"2.0","method":"qos.vm.set","params":{
"vm":"web-prod","qos_min_mbps":100,"qos_max_mbps":500},"id":"1"}'
# per-tenant SLA 설정
curl -s -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
http://127.0.0.1:8080/api/v1/rpc \
-d '{"jsonrpc":"2.0","method":"qos.tenant.set","params":{
"tenant":"acme","min_mbps":200,"max_mbps":1000},"id":"1"}'
# VM 설정과 tenant별 강제 통계를 다시 조회한다.
curl -s -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
http://127.0.0.1:8080/api/v1/rpc \
-d '{"jsonrpc":"2.0","method":"qos.vm.get","params":{"vm":"web-prod"},"id":"1"}'
curl -s -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
http://127.0.0.1:8080/api/v1/rpc \
-d '{"jsonrpc":"2.0","method":"qos.stats","params":{"tenant":"acme"},"id":"1"}'

VM 생성 시 SLA 필수(D09): 커널 netdev(tc 셰이핑 가능) NIC — network_bridge 미지정/bridge 또는 tenant-overlay — 을 쓰는 VM은 vm.create--qos_min_mbps/--qos_max_mbps가 필수입니다(§3.1 「기본 생성」의 D09 안내와 상호 참조).
dpdk/sriov NIC만 면제되며, 생략 시 서버가 vm.create-32602로 거부합니다.

QoS 카오스 주입 (netem, 테스트용)

섹션 제목: “QoS 카오스 주입 (netem, 테스트용)”

VM leaf class에 netem을 삽입해 지연·손실을 인위적으로 주입하는 카오스 하네스를 제공합니다(장애 주입 테스트 용도).
타임박스·dry_run·감사·부팅 시 자동 정리(잔여 netem을 Cake besteffort로 복원) 가드가 걸려 있으며, 타임박스 만료 시 자동으로 정상 성형으로 되돌립니다.

메서드RBAC파라미터용도
qos.chaos.startADMIN{vm, profile, timebox_sec, [dry_run]}netem 카오스(지연/손실) 시작
qos.chaos.stopADMIN{vm}카오스 중지 + Cake besteffort 복원
qos.chaos.statusADMIN{}카오스 상태 조회

에디션 경계: 오버레이 코어(create/delete/list/info/add_peer/remove_peer)는 Single Edge 공개 범위에 포함됩니다.
자동 풀메시와 peer discovery는 공개 출시 표면에 포함되지 않습니다.

Open vSwitch 기반 VXLAN 오버레이 네트워크를 구성합니다.

활용 예제 — 외부 VXLAN endpoint와 수동 peer 구성

섹션 제목: “활용 예제 — 외부 VXLAN endpoint와 수동 peer 구성”

이 예제는 PureCVisor 노드가 192.0.2.19를 tunnel source로 사용하고, 운영자가 관리하는 VXLAN 호환 endpoint 192.0.2.20과 VNI 100을 연결하는 구성입니다.
두 주소는 RFC 문서용 주소이므로 실제 tunnel endpoint로 바꾸고, underlay에서 UDP 4789와 MTU를 먼저 확인합니다.

tunnel source와 remote endpoint 및 VNI 100이 PureCVisor peer desired state, OVS VXLAN port와 UDP 4789 underlay를 거쳐 원격 endpoint로 이어지는 구성도
수동 peer 구성은 OVS actual port와 두 endpoint 사이의 underlay 도달성을 모두 확인합니다.
Terminal window
# 오버레이 생성
pcvctl overlay create --name pcvoverlay0 --vni 100 --cidr 10.100.0.1/24
# 명시적으로 관리하는 endpoint만 peer로 추가
pcvctl overlay add-peer pcvoverlay0 192.0.2.20
# desired state와 OVS actual port 확인
pcvctl overlay list
pcvctl overlay info pcvoverlay0
sudo ovs-vsctl show
# 사용을 마치면 peer와 overlay를 역순으로 정리
pcvctl overlay remove-peer pcvoverlay0 192.0.2.20
pcvctl overlay delete pcvoverlay0

RPC 직접 호출:

Terminal window
# 오버레이 목록
echo '{"jsonrpc":"2.0","method":"overlay.list","params":{},"id":"1"}' \
| nc -U /var/run/purecvisor/daemon.sock | python3 -m json.tool
# 오버레이 상세
echo '{"jsonrpc":"2.0","method":"overlay.info","params":{
"name": "pcvoverlay0"
},"id":"1"}' | nc -U /var/run/purecvisor/daemon.sock | python3 -m json.tool

daemon.conf [overlay] 섹션을 설정하면 부팅 시 기본 브리지가 자동 생성됩니다.
Single Edge에서는 로컬 브리지 생성과 명시한 peer 적용까지만 사용하며, 자동 peer discovery나 자동 풀메시는 제공하지 않습니다.

Single Edge는 overlay 코어 기능을 지원하지만, tunnel_ip는 자동 추론하지 않습니다.
따라서 Single Edge에서 overlay를 활성화하려면 운영자가 [overlay] 섹션에 tunnel_ip를 명시해야 합니다.
이 값은 로컬 호스트가 VXLAN 터널 소스로 사용할 IP이며, Single Edge에서는 운영 가이드에 따라 명시적으로 관리합니다.

[overlay]
name = pcvoverlay0
vni = 100
cidr = 10.100.0.1/24
tunnel_ip = 192.0.2.19
peers = 192.0.2.20,192.0.2.21

OVS 상태 확인:

Terminal window
sudo ovs-vsctl show

테넌트 암호화 오버레이 (tenant_overlay, 2.0)

섹션 제목: “테넌트 암호화 오버레이 (tenant_overlay, 2.0)”

에디션 경계: 테넌트 오버레이 코어(create/delete/get/list/attach_vm/detach_vm)는 Single Edge 공개 범위에 포함됩니다.
자동 peer 구성과 키 교환 자동화는 공개 출시 표면에 포함되지 않습니다.

2.0은 멀티테넌트 VM 트래픽을 per-VM 암호화 오버레이로 격리하는 tenant_overlay.* 제어평면을 추가했습니다.
각 VM은 자체 network namespace 안의 per-VM WireGuard 엔드포인트로 배선되며, 공유 브리지 위를 지나는 오버레이 트래픽은 암호문입니다.
오버레이 레지스트리는 영속화되어 데몬 재시작 시 재수화되고, vm.create/vm.start 오케스트레이션은 fail-closed로 동작합니다(암호 오버레이 준비 실패 시 VM 기동을 막음).

VM을 테넌트 오버레이에 붙이려면 vm.createnic_typetenant-overlay로 지정하며, 이 조합은 커널 netdev 셰이핑 대상이라 §3.1의 D09 QoS SLA(--qos_min_mbps/--qos_max_mbps)가 필수입니다.
서브넷은 오버레이 생성 시 자동 배정되어 응답으로 반환되고, VM attach 시 내부 오버레이 IP가 배정됩니다.

RPC 전용(2.0): tenant_overlay.* 네임스페이스는 전용 REST 경로·CLI 서브커맨드·UI 페이지가 없습니다.
POST /api/v1/rpc JSON-RPC 패스스루(또는 UDS 직접 nc -U)로만 호출하며, 모든 메서드는 ADMIN 권한이 필요합니다.

메서드파라미터용도
tenant_overlay.create{tenant}테넌트 암호화 오버레이 생성(서브넷 자동 배정 → 응답 subnet)
tenant_overlay.delete{tenant}테넌트 오버레이 삭제
tenant_overlay.list{}테넌트 오버레이 목록([{tenant, subnet}, …])
tenant_overlay.get{tenant}단일 테넌트 오버레이 상세({tenant, subnet})
tenant_overlay.attach_vm{tenant, vm}VM을 오버레이에 참여(내부 IP 배정 → 응답 overlay_ip)
tenant_overlay.detach_vm{tenant, vm}VM을 오버레이에서 분리
Terminal window
# 테넌트 오버레이 생성 (POST /api/v1/rpc 패스스루)
curl -s -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
http://127.0.0.1:8080/api/v1/rpc \
-d '{"jsonrpc":"2.0","method":"tenant_overlay.create","params":{
"tenant":"acme"},"id":"1"}'
# VM을 오버레이에 참여
curl -s -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
http://127.0.0.1:8080/api/v1/rpc \
-d '{"jsonrpc":"2.0","method":"tenant_overlay.attach_vm","params":{
"tenant":"acme","vm":"web-prod"},"id":"1"}'
# tenant subnet과 VM overlay IP가 등록됐는지 다시 조회
curl -s -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
http://127.0.0.1:8080/api/v1/rpc \
-d '{"jsonrpc":"2.0","method":"tenant_overlay.get","params":{
"tenant":"acme"},"id":"1"}'

에디션 경계: generic OVN 코어(status, switch/port/ACL/router/DHCP/NAT/tenant)는 Single Edge 공개 범위에 포함됩니다.
등록된 RPC inventory는 정확히 18개이며 완전한 CRUD를 뜻하지 않습니다.
완결되지 않은 OVN/NFV Load Balancer와 production caller가 없는 VM 자동 포트 내부 helper는 공개 기능이 아닙니다.
encap 설정과 auto-provision 자동화는 공개 범위 밖 멀티 제어면 참고 기능으로 남겨 둡니다.

OVN (Open Virtual Network) 기반 소프트웨어 정의 네트워크를 지원합니다.

활용 예제 — 웹 논리 네트워크에 DHCP·ACL·SNAT 적용

섹션 제목: “활용 예제 — 웹 논리 네트워크에 DHCP·ACL·SNAT 적용”

아래 절을 순서대로 실행하면 ls-web 논리 스위치와 lr-main 논리 라우터를 만들고, 10.0.1.0/24 DHCP와 웹 ACL, SNAT를 연결합니다.
203.0.113.1은 RFC 문서용 주소이므로 실제 external IP로 교체하고, 실행 전 host 기준선과 ovn status가 모두 준비 상태인지 확인합니다.

웹 논리 네트워크 모델이 PureCVisor generic OVN RPC를 거쳐 logical switch, router, DHCP, ACL, SNAT과 OVS br-int actual state로 이어지는 구성도
논리 객체의 REST 조회와 OVN·OVS actual state를 함께 비교해 단계별 수렴을 확인합니다.

작업 전 호스트 네트워크 기준선

섹션 제목: “작업 전 호스트 네트워크 기준선”

Web UI의 인프라 > 네트워크에서 호스트 네트워크 기준선을 먼저 확인합니다.
관리 interface/IP, IPv4 main route와 connected CIDR, Linux bridge/port, OVS bridge/port, 현재 tenant의 Local VPC CIDR과 OVN readiness를 한 화면에서 비교할 수 있습니다.

Terminal window
curl -ksS -H "Authorization: Bearer $TOKEN" \
"https://${NODE_IPV4}/api/v1/networks/host-baseline" | python3 -m json.tool

이 endpoint는 host interface·route·OVS actual을 변경하지 않는 읽기 전용 조회입니다.
응답 일부가 partial 또는 unavailable이면 빈 상태로 해석하지 말고 해당 수집 실패를 해결한 뒤 OVN이나 Local VPC 리소스를 생성합니다.

등록된 generic OVN RPC — 정확히 18개

섹션 제목: “등록된 generic OVN RPC — 정확히 18개”
영역개수등록 RPC
상태1ovn.status
스위치4ovn.switch.create, ovn.switch.delete, ovn.switch.list, ovn.switch.detail
포트2ovn.port.add, ovn.port.remove
ACL2ovn.acl.add, ovn.acl.list
라우터5ovn.router.create, ovn.router.delete, ovn.router.list, ovn.router.detail, ovn.router.add_port
DHCP1ovn.dhcp.enable
NAT2ovn.nat.add, ovn.nat.list
테넌트1ovn.tenant.create
총계18dispatcher에 등록된 generic ovn.* 공개 inventory

등록되지 않은 역동작과 공개 제외 기능

섹션 제목: “등록되지 않은 역동작과 공개 제외 기능”

현재 ACL 삭제, NAT 삭제, DHCP 목록·삭제, tenant 삭제, router port 제거 RPC는 등록돼 있지 않습니다.
manager 내부에 일부 역동작 함수가 있더라도 사용자 RPC로 간주하지 않습니다.
cleanup은 등록된 port/switch/router 삭제와 부모 리소스의 안전한 cascade를 기준으로 합니다.
OVN/NFV Load Balancer를 생성·연결·조회·삭제하는 사용자 절차도 제공하지 않습니다.
Local VPC의 제한형 Service Publish는 이 제외 기능과 별개입니다.

Terminal window
pcvctl ovn status
Terminal window
# 스위치 생성
pcvctl ovn switch create ls-web
# 스위치 목록
pcvctl ovn switch list
# 스위치 삭제
pcvctl ovn switch delete ls-web

논리 스위치 생성은 L2 switch만 만들며 subnet 입력을 받지 않습니다.
주소 대역과 DHCP는 아래 ovn dhcp enable 단계에서 별도로 구성합니다.

Terminal window
# 라우터 생성
pcvctl ovn router create lr-main
# 라우터 목록
pcvctl ovn router list
# 라우터 삭제
pcvctl ovn router delete lr-main
Terminal window
# 인그레스 규칙 추가
pcvctl ovn acl add ls-web to-lport 100 'tcp.dst == 80' allow
# 이그레스 규칙 추가
pcvctl ovn acl add ls-web from-lport 50 'tcp.dst == 443' allow
# ACL 목록
pcvctl ovn acl list ls-web
Terminal window
# NAT 목록
pcvctl ovn nat list lr-main

NAT 추가와 router↔switch 포트 연결은 현재 JSON-RPC 표면을 사용한다.

Terminal window
echo '{"jsonrpc":"2.0","method":"ovn.router.add_port","params":{
"router":"lr-main","switch":"ls-web","mac":"02:00:00:00:01:01",
"cidr":"10.0.1.1/24"},"id":"1"}' \
| socat - UNIX-CONNECT:/var/run/purecvisor/daemon.sock
echo '{"jsonrpc":"2.0","method":"ovn.nat.add","params":{
"router":"lr-main","type":"snat","external_ip":"203.0.113.1",
"logical_ip":"10.0.1.0/24"},"id":"1"}' \
| socat - UNIX-CONNECT:/var/run/purecvisor/daemon.sock
Terminal window
# OVN DHCP 옵션 설정
pcvctl ovn dhcp enable 10.0.1.0/24 10.0.1.1 --switch ls-web

--switch를 주면 DHCP option record를 스위치에 귀속시키고, 이미 있는 일반 logical switch port와 이후 추가할 포트 모두에 같은 옵션을 연결한다.
OVN 포트, DHCP, router link 생성은 하나의 ovn-nbctl transaction으로 실패하며 부분 구성을 성공으로 보고하지 않는다.

스위치를 삭제하면 같은 ownership marker를 가진 DHCP option record도 동일 transaction에서 자동 정리합니다.
다른 스위치가 소유한 행과 foreign OVN 행은 보존하며, 소유권 조회가 모호하거나 UUID가 비정상이거나 안전 상한을 넘으면 실제 변경 전에 실패합니다.

ACL과 NAT 목록 REST는 대상 식별자를 query parameter로 받아 canonical RPC parameter로 전달합니다.

Terminal window
curl -ksS -H "Authorization: Bearer $TOKEN" \
"https://${NODE_IPV4}/api/v1/ovn/acl?switch=ls-web"
curl -ksS -H "Authorization: Bearer $TOKEN" \
"https://${NODE_IPV4}/api/v1/ovn/nat?router=lr-main"

switch 또는 router가 없거나 비어 있으면 필터 없는 전체 목록으로 넓히지 않고 canonical JSON-RPC -32602(Invalid params)로 거부합니다.
대상이 지정된 성공 응답에는 다른 switch/router의 표식이 섞이면 안 됩니다.

generic OVN 18개 RPC의 NET-OVN-01~07 검증과 Local VPC OVN backend의 공개 지원 판정은 서로 다른 gate입니다.
generic OVN 검증이 통과해도 Local VPC OVN의 부팅 KVM, Linux/OVN 공존, controller/host reboot와 전 단계 fault injection을 대신하지 않습니다.

Security Group으로 VM의 ingress와 egress 허용 범위를 선언하고, nftables actual rule로 적용합니다.
CLI는 기본 생성·단일 포트 규칙·VM 연결을 제공하고, source CIDR이나 rule 제거처럼 세부 속성이 필요한 작업은 JSON-RPC를 사용합니다.

활용 예제 — 웹 포트와 관리 CIDR의 SSH만 허용

섹션 제목: “활용 예제 — 웹 포트와 관리 CIDR의 SSH만 허용”

아래 예제는 web-prod VM에 HTTP·HTTPS를 허용하고, SSH는 RFC 문서용 관리 대역 192.0.2.0/24에서만 허용합니다.
실행 전 해당 대역을 실제 관리 CIDR로 바꾸며, VM에 기존 그룹이 있다면 교체 영향을 먼저 확인합니다.

HTTP, HTTPS와 관리 CIDR SSH 규칙이 PureCVisor 보안 그룹 desired state와 nftables VM NIC 경계를 거쳐 web-prod의 허용 및 차단 결과로 이어지는 구성도
허용 규칙뿐 아니라 default-deny가 유지되는 차단 경로까지 함께 시험합니다.
Terminal window
# 보안 그룹 생성
pcvctl security-group create web-sg
# 공개 웹 포트는 CLI로 각각 추가
pcvctl security-group rule add web-sg --direction ingress --proto tcp --port 80
pcvctl security-group rule add web-sg --direction ingress --proto tcp --port 443
# SSH 규칙의 source CIDR은 JSON-RPC로 제한
echo '{"jsonrpc":"2.0","method":"security_group.rule.add","params":{
"name":"web-sg","direction":"ingress","protocol":"tcp",
"port":22,"source":"192.0.2.0/24"
},"id":"1"}' | nc -U /var/run/purecvisor/daemon.sock | python3 -m json.tool
# 애플리케이션의 HTTPS egress 허용
pcvctl security-group rule add web-sg --direction egress --proto tcp --port 443
# VM에 보안 그룹 적용
pcvctl vm security-group web-prod web-sg
# desired state와 nft actual state 확인
pcvctl security-group list
sudo nft list table inet purecvisor

이 예제는 DNS, NTP, package mirror 등 운영체제에 필요한 다른 egress를 자동으로 허용하지 않습니다.
실제 workload 의존성을 확인한 뒤 최소 규칙을 추가하고, 잘못 연결했으면 pcvctl security-group detach web-prod web-sg로 분리합니다.

영속화: 보안 그룹은 SQLite에 저장되며, 데몬 재시작 시 nftables 규칙이 자동 복원됩니다.
default-deny 정책이 기본 적용됩니다.

고성능 데이터 플레인을 위한 DPDK (Data Plane Development Kit) 통합을 지원합니다.
이 경로는 NIC를 host kernel network stack에서 분리하므로 out-of-band 복구 수단과 전용 NIC가 준비된 경우에만 사용합니다.

활용 예제 — 전용 PCI NIC로 OVS-DPDK bridge 구성

섹션 제목: “활용 예제 — 전용 PCI NIC로 OVS-DPDK bridge 구성”

0000:03:00.0은 예시 PCI 주소입니다.
dpdk statusavailable과 hugepage 준비 상태를 먼저 확인하고, host 관리 경로 또는 기본 route가 연결된 NIC는 대상으로 선택하지 않습니다.

전용 PCI NIC와 hugepage 사전 조건이 PureCVisor vfio-pci bind와 OVS-DPDK bridge를 거쳐 VM vhost-user 가속 경로로 이어지는 구성도
주황색 점선은 host kernel network stack을 우회하는 가속 경로와 별도 복구 책임을 나타냅니다.
Terminal window
# 사전 조건 확인
pcvctl dpdk status
pcvctl dpdk hugepage
# 전용 NIC를 vfio-pci에 바인딩하고 같은 PCI 장치를 bridge port로 구성
pcvctl dpdk bind 0000:03:00.0 vfio-pci
pcvctl dpdk bridge create dpdk-br0 0000:03:00.0
# desired state와 OVS actual state 확인
pcvctl dpdk list
sudo ovs-vsctl show
# 사용 종료 시 bridge를 먼저 삭제한 뒤 kernel driver를 복원
pcvctl dpdk bridge delete dpdk-br0
pcvctl dpdk unbind 0000:03:00.0

언바인딩 완료 판정: dpdk unbind는 복원 명령의 종료코드만 믿지 않습니다.
driver_override를 해제하고 커널 probe를 요청한 뒤 실제 non-DPDK 드라이버가 다시 보일 때만 성공합니다.
장치가 이미 사라졌거나 커널 드라이버로 복원된 상태는 멱등 성공이며, 도구 부재·권한 오류·상태 미변경은 실패로 보고됩니다.

SR-IOV를 사용하여 물리 NIC의 가상 기능(VF)을 VM에 직접 할당합니다.
VF 트래픽은 일반 Linux bridge와 host TC QoS를 우회하므로 switch 정책, IOMMU 격리와 guest driver를 함께 검증해야 합니다.

활용 예제 — VLAN 100 VF를 웹 VM에 직접 할당

섹션 제목: “활용 예제 — VLAN 100 VF를 웹 VM에 직접 할당”

eno2는 예시 PF이며 host 관리 경로에 사용되지 않는 SR-IOV 지원 NIC여야 합니다.
아래 MAC은 문서용 locally administered 주소이므로 실제 배포에서는 중복되지 않는 값으로 바꿉니다.

PF eno2의 VF 0과 VLAN 100, spoof check 설정이 PureCVisor 검증과 IOMMU hostdev 직접 할당을 거쳐 web-prod guest VF로 이어지는 구성도
직접 할당은 Linux bridge와 host TC를 우회하므로 switch와 guest까지 검증 범위를 확장합니다.
Terminal window
# SR-IOV 지원 NIC 상태
pcvctl sriov status
# VF 활성화 (4개)
pcvctl sriov enable eno2 4
# VF 목록
pcvctl sriov list eno2
# VF 0에 MAC, VLAN과 spoof check를 적용
pcvctl sriov set eno2 0 --mac 02:00:00:00:01:10 --vlan 100 --spoofchk on
# VM에 VF 할당
pcvctl sriov attach web-prod eno2 0
# VM persistent XML과 VF actual state 확인
sudo virsh dumpxml web-prod
pcvctl sriov list eno2
# VM에서 VF 분리
pcvctl sriov detach web-prod 0000:03:10.0

detach의 PCI 주소는 pcvctl sriov list eno2가 VF 0에 반환한 실제 값을 사용합니다.
사용을 모두 마친 뒤에만 pcvctl sriov disable eno2로 VF 수를 0으로 되돌립니다.

직접 할당 안전 경계: sriov attach는 PF와 VF의 IOMMU group을 서버에서 모두 확인한 뒤에만 첫 드라이버 변경을 시작합니다.
sriov detach는 libvirt의 정확한 “이미 연결되지 않음” 응답만 멱등 성공으로 처리하며, VM 부재·권한·libvirt 장애는 실패로 전파합니다.

활용 예제 — link에서 VM NIC까지 계층별 장애 격리

섹션 제목: “활용 예제 — link에서 VM NIC까지 계층별 장애 격리”

한 번에 설정을 바꾸기보다 desired state, host link, bridge·OVS, 정책, VM NIC 순서로 실제 상태를 좁힙니다.
VLAN 또는 VXLAN을 쓰지 않는 구성이라면 해당 단계의 빈 결과는 정상입니다.

PureCVisor desired state에서 host link와 route, bridge와 OVS, nftables와 Security Group, libvirt VM NIC 순서로 실제 상태를 좁히는 구성도
기대 상태와 실제 상태가 처음 달라지는 계층을 장애 경계로 좁힙니다.
Terminal window
# 1. PureCVisor desired state와 host 주소·route
pcvctl network list
ip -br address
ip -4 route show table main
# 2. Linux bridge와 연결된 port
ip -d link show type bridge
bridge link
# 3. OVS와 VXLAN actual state
sudo ovs-vsctl show
ip -d link show type vxlan
# 4. 데몬이 소유한 정책
sudo nft list table inet purecvisor
# 5. 대상 VM NIC와 persistent XML
sudo virsh domiflist web-prod
sudo virsh dumpxml web-prod

기본 네트워크가 목록에 있지만 bridge가 없으면 생성 또는 재수화 오류를 확인합니다.
bridge와 VM NIC가 정상인데 통신이 실패하면 nftables·Security Group을 보고, VXLAN 구성에서만 실패하면 underlay endpoint, UDP 4789와 MTU를 확인합니다.

활용 예제 — NIC drop과 conntrack 포화 징후 확인

섹션 제목: “활용 예제 — NIC drop과 conntrack 포화 징후 확인”

먼저 ip -br link로 실제 interface 이름을 확인한 뒤 내장 /api/v1/metrics에서 같은 device label을 조회합니다.
counter는 누적값이므로 한 번의 숫자보다 일정 구간의 증가율을 기준으로 판단합니다.

Linux NIC, socket과 conntrack 통계가 purecvisorsd collector와 metrics API를 거쳐 Prometheus의 증가율 및 포화 신호로 이어지는 구성도
device label을 실제 interface와 맞춘 뒤 counter 증가율과 conntrack 사용 비율을 판정합니다.
Terminal window
# eno1을 실제 uplink 이름으로 교체한다.
curl -s http://127.0.0.1:8080/api/v1/metrics | \
grep -E '^(node_network_(receive|transmit)_(bytes|errors|drop)_total\{device="eno1"\}|node_nf_conntrack_(entries|entries_limit))'
# 네트워크 인터페이스 메트릭
node_network_receive_bytes_total{device="eno1"}
node_network_transmit_bytes_total{device="eno1"}
node_network_receive_errors_total{device="eno1"}
node_network_transmit_errors_total{device="eno1"}
node_network_receive_drop_total{device="eno1"}
node_network_transmit_drop_total{device="eno1"}
# 소켓 통계
node_sockstat_TCP_inuse
node_sockstat_TCP_tw
node_sockstat_UDP_inuse
# conntrack
node_nf_conntrack_entries
node_nf_conntrack_entries_limit

error 또는 drop counter가 지속적으로 증가하면 NIC·switch·qdisc를 함께 확인합니다.
node_nf_conntrack_entries가 limit에 가까우면 NAT·Security Group workload의 연결 수와 timeout 정책을 점검합니다.

Local VPC는 한 Single Edge 호스트에서 tenant별 VPC, 여러 IPv4 subnet과 정지 VM attachment를 하나의 desired state로 관리합니다.
생성할 때 linux 또는 ovn backend를 고정하며, 생략하면 기존 호환값인 linux입니다.
Linux는 subnet별 bridge/dnsmasq, OVN은 공유 OVS br-int 위의 LS/LR/DHCP/LSP/Port Group/ACL을 사용합니다.
두 backend 모두 공통 nft 경계에서 natisolated egress를 제공하고, 서로 다른 VPC와 VM에서 host 관리 서비스로 향하는 트래픽을 기본 차단합니다.

외부 inbound에는 Floating IP pool이나 범용 port forwarding 대신 제한형 Service Publish를 사용합니다.
운영자는 host의 listen_address:listen_portACTIVE attachment의 target_port에 연결하고, 허용 source CIDR을 반드시 명시합니다.
대상 VM에는 Security Group이 연결돼 있어야 합니다.
즉 VM에 직접 공인 IP를 주지 않아도 host IP와 게시 포트를 통해 선택한 서비스만 외부에 노출할 수 있습니다.

Web UI + REST + CLI + RPC: Web UI의 인프라 > Local VPC, 전용 /api/v1/vpcs REST resource, pcvctl vpc CLI와 POST /api/v1/rpc JSON-RPC 패스스루/UDS를 사용할 수 있습니다.
Web UI와 CLI 변경 명령은 accepted의 Job ID를 jobs.get terminal까지 조회해 completed만 성공으로 확정합니다.
--no-wait를 지정하면 접수와 Job ID만 즉시 반환하므로 별도 결과 확인이 필요합니다.

Local VPC 작업 전에는 Web UI의 인프라 > 네트워크에서 호스트 네트워크 기준선을 먼저 확인합니다.
GET /api/v1/networks/host-baseline은 읽기 전용 RPC network.host.info에 매핑되어 host interface·route·OVS actual을, GET /api/v1/vpcs/statussubnet_cidrs는 현재 tenant 범위의 VPC 주소 대역을 반환합니다.
어느 영역이 partial 또는 unavailable이면 빈 상태로 간주하지 말고 원인을 해결한 뒤 생성합니다.

Web UI의 Local VPC 생성은 VPC 이름·tenant·backend·egress와 첫 subnet 이름·IPv4 CIDR·MTU를 한 모달에서 받아 하나의 Job으로 생성합니다.
CIDR 입력 중 gateway와 VM 할당 범위를 미리 표시하며, 첫 subnet 적용 실패 시 이번 요청에서 만든 VPC도 역순 rollback합니다.
backend 준비 상태, 현재 VPC 수와 실제 주소 pool 잔량을 제출 전에 표시하며, 생성 실패는 모달 내부의 읽을 수 있는 오류로 남겨 입력을 보존합니다.
목록에서 VPC를 선택하면 같은 화면 아래에 subnet, VM attachment와 Service Publish를 순서대로 표시합니다.
egress와 두 번째 이후 subnet 변경은 상세에서 읽은 현재 revision을 자동 전달하며, 삭제·연결 해제·게시 해제는 영향 확인을 거칩니다.
VIEWER는 조회, OPERATOR는 일반 변경, ADMIN은 VPC 삭제와 전체 reconcile을 수행할 수 있으며 실제 인가는 서버가 판정합니다.

전용 REST 경로:

HTTP경로기능
GET/api/v1/networks/host-baseline읽기 전용 host interface·route·Linux bridge·OVS·VPC 기준선
GET, POST/api/v1/vpcs목록, 생성
GET/api/v1/vpcs/backendsbackend readiness, 현재 수와 주소 기반 capacity
GET/api/v1/vpcs/statuscontroller/reconcile 상태
POST/api/v1/vpcs/reconcile전체 desired state 수렴
GET, DELETE/api/v1/vpcs/{vpc_id}aggregate 상세, 삭제
POST/api/v1/vpcs/{vpc_id}/egressegress 변경
GET, POST/api/v1/vpcs/{vpc_id}/subnetssubnet 목록, 생성
DELETE/api/v1/vpc-subnets/{subnet_id}subnet 삭제
GET/api/v1/vpcs/{vpc_id}/attachmentsVM 연결 목록
POST, DELETE/api/v1/vpc-attachments[/{attachment_id}]VM 연결, 해제
GET/api/v1/vpcs/{vpc_id}/services게시 서비스 목록
POST, DELETE/api/v1/vpc-services[/{publish_id}]서비스 게시, 해제

활용 예제 — Linux Local VPC의 VM 서비스를 제한 게시

섹션 제목: “활용 예제 — Linux Local VPC의 VM 서비스를 제한 게시”

이 절의 전체 예제는 공개 지원 backend인 linux를 사용합니다.
198.51.100.10192.0.2.0/24는 RFC 문서용 주소이므로 실행 전 실제 node IPv4와 허용할 client CIDR로 교체합니다.

REST로 VPC와 첫 subnet을 한 Job에 생성합니다.

허용된 client CIDR이 Single Edge host의 8443 listener와 Local VPC Service Publish, Linux bridge attachment를 거쳐 web-prod VM의 443 포트로 이어지는 구성도
허용 source CIDR과 host listener를 단일 VPC attachment의 target port에 제한적으로 연결합니다.
Terminal window
curl -sS -X POST https://127.0.0.1:8443/api/v1/vpcs \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{"tenant":"acme","name":"prod","backend":"linux","egress_mode":"nat","subnet_name":"web","subnet_cidr":"10.60.10.0/24","subnet_mtu":1500}'
# 응답의 job_id를 terminal까지 확인한다.
curl -sS https://127.0.0.1:8443/api/v1/jobs/<job-id> \
-H "Authorization: Bearer $TOKEN"
메서드최소 역할주요 파라미터
vpc.list, vpc.status, vpc.backend.listVIEWERadmin은 선택적 tenant
vpc.get, vpc.subnet.list, vpc.attachment.list, vpc.service.listVIEWERvpc_id
vpc.createOPERATORname, egress_mode; 선택적 backend=linux|ovn과 all-or-none subnet_name, subnet_cidr, subnet_mtu; admin UDS 호출은 tenant 명시
vpc.egress.setOPERATORvpc_id, egress_mode, expected_revision
vpc.subnet.createOPERATORvpc_id, name, cidr, expected_revision, 선택적 mtu
vpc.subnet.deleteOPERATORsubnet_id
vpc.attachment.createOPERATORsubnet_id, vm, 선택적 ip_address
vpc.attachment.deleteOPERATORattachment_id
vpc.service.publishOPERATORattachment_id, protocol, listen_address, listen_port, target_port, allowed_sources
vpc.service.unpublishOPERATORpublish_id
vpc.delete, vpc.reconcileADMINvpc_id 또는 전체 수렴

CLI로 같은 수명주기를 실행할 수 있습니다.

Terminal window
# backend 준비 상태와 주소 기반 capacity를 먼저 확인한다.
pcvctl vpc backends
# Linux NAT VPC와 첫 subnet 일괄 생성 — 기본값은 worker terminal 완료까지 기다린다.
pcvctl vpc create prod --tenant acme --egress nat \
--backend linux --subnet-name web --cidr 10.60.10.0/24 --mtu 1500
# 목록과 상세 조회
pcvctl vpc list --tenant acme
pcvctl vpc get <vpc-uuid> --tenant acme
# 두 번째 이후 subnet 생성: vpc.get에서 확인한 현재 revision을 사용한다.
pcvctl vpc subnet-create <vpc-uuid> db --tenant acme \
--cidr 10.60.20.0/24 --mtu 1500 --revision 2
# 정지 VM 연결과 제한형 Service Publish
pcvctl vpc attachment-create <subnet-uuid> web-prod --tenant acme
pcvctl vpc service-publish <attachment-uuid> --tenant acme \
--protocol tcp --listen-address 198.51.100.10 --listen-port 8443 \
--target-port 443 --allowed-source 192.0.2.0/24
# attachment, publish와 controller 수렴 상태 확인
pcvctl vpc get <vpc-uuid> --tenant acme
pcvctl vpc service-list <vpc-uuid> --tenant acme
pcvctl vpc status

같은 기능의 raw UDS RPC 예시:

Terminal window
# NAT VPC와 첫 subnet 일괄 생성 — 응답 Job 완료 뒤 aggregate를 확인한다.
echo '{"jsonrpc":"2.0","method":"vpc.create","params":{
"tenant":"acme","name":"prod","egress_mode":"nat",
"backend":"linux",
"subnet_name":"web","subnet_cidr":"10.60.10.0/24","subnet_mtu":1500
},"id":"1"}' | nc -U /var/run/purecvisor/daemon.sock | python3 -m json.tool
# 두 번째 이후 subnet 생성
echo '{"jsonrpc":"2.0","method":"vpc.subnet.create","params":{
"tenant":"acme","vpc_id":"<vpc-uuid>","name":"db",
"cidr":"10.60.20.0/24","mtu":1500,"expected_revision":2
},"id":"2"}' | nc -U /var/run/purecvisor/daemon.sock | python3 -m json.tool
# 정지 VM 연결
echo '{"jsonrpc":"2.0","method":"vpc.attachment.create","params":{
"tenant":"acme","subnet_id":"<subnet-uuid>","vm":"web-prod"
},"id":"3"}' | nc -U /var/run/purecvisor/daemon.sock | python3 -m json.tool
# 지정한 host IPv4의 TCP 8443을 VM TCP 443으로 제한 게시
echo '{"jsonrpc":"2.0","method":"vpc.service.publish","params":{
"tenant":"acme","attachment_id":"<attachment-uuid>","protocol":"tcp",
"listen_address":"198.51.100.10","listen_port":8443,"target_port":443,
"allowed_sources":["192.0.2.0/24"]
},"id":"4"}' | nc -U /var/run/purecvisor/daemon.sock | python3 -m json.tool

제약과 안전 경계:

  • VPC subnet은 다른 VPC와 기존 host connected CIDR을 포함해 호스트 전체에서 겹칠 수 없습니다.
  • backend는 VPC 생성 뒤 바꿀 수 없고 한 VPC 안에서 혼합할 수 없습니다.
    OVN 장애 시 Linux로 자동 fallback하지 않으며 generic ovn.*는 Local VPC 소유 row 변경을 거부합니다.
  • OVN readiness는 NB/SB/northd/controller/chassis/br-int, 기능 parity와 [ovn] edge_transit_pool 충돌을 함께 검사합니다.
    기본 100.64.0.0/16을 VPC당 /30으로 나누면 이론상 16,384개지만, allocatable_count는 이미 예약한 주소를 뺀 현재값이고 product_limit=null은 무제한 보증이 아닙니다.
  • attachment는 정지 VM persistent XML만 변경합니다.
    실행 중 VM live attach는 아직 지원하지 않습니다.
  • 한 VM의 cross-VPC multi-homing과 tenant-overlay 동시 연결은 거부합니다.
  • VPC managed bridge는 network.*, raw NIC attach와 vm.create network_bridge로 수정할 수 없습니다.
  • isolated VPC에는 Service Publish를 만들 수 없고, non-admin은 0.0.0.0/0 또는 동등한 분할 CIDR 합집합으로 전체 공개할 수 없습니다.
  • 0.0.0.0 listen은 모든 host IPv4 주소를 의미합니다.
    특정 NIC만 공개하려면 해당 host local IPv4를 명시합니다.
  • 데이터면 actual state가 불일치하면 데몬은 listener를 열기 전에 quarantine을 적용하며, vpc.statusreconcile_required와 각 resource의 last_error를 확인해야 합니다.

Linux Local VPC backend와 데이터면은 실제 VM·패킷 효과 검증을 완료했습니다.
전용 CLI는 17개 action과 create/list/get/delete terminal 왕복을 검증했습니다.
선택형 OVN backend 후보는 제품 API 생성, inactive VM XML, LSP/chassis packet, NAT/isolated, SG, Service Publish, 관리면 차단, daemon restart, schema migration과 cleanup을 검증했습니다.
다만 부팅 KVM·Linux/OVN 공존·host/controller reboot· 전 단계 fault injection 전에는 Implemented 후보이며 공개 지원은 Linux backend만입니다.
Network Flow/IPFIX collector, VPC peering, Floating IP pool, live attachment와 다중 노드 router는 이번 Local VPC 범위에 포함되지 않습니다.