시작하기
VPP를 처음 돌려보는 분을 위한 단계별 실습 가이드입니다. 설치, 첫 실행, TAP 인터페이스로 그래프 통과 확인, 트레이스 분석, 플러그인 확장까지 한 번의 세션으로 체험합니다.
시작 전 준비물
다음 환경을 권장합니다. VM/컨테이너에서도 대부분 동작하지만 성능 측정은 베어메탈이 필요합니다.
- OS: Ubuntu 22.04 / 24.04 LTS (Debian · RHEL/Rocky · Fedora 도 지원)
- CPU: x86_64 또는 ARM64, 최소 4코어
- RAM: 최소 4 GB (Hugepage 2GB + 운영체제 여유분)
- 권한:
sudo가능한 계정 - 네트워크: 호스트 네트워크와 분리된 실험 인터페이스 1개 권장
1단계 — 설치
가장 빠른 설치 방법은 FD.io 패키지 저장소를 등록하고 apt로 받는 것입니다.
# VPP 26.02 릴리스 저장소 등록
$ curl -s https://packagecloud.io/install/repositories/fdio/release/script.deb.sh | sudo bash
# 핵심 패키지 설치
$ sudo apt-get install -y vpp vpp-plugin-core vpp-plugin-dpdk
# 설치 확인
$ vpp -v
vpp v26.02-release built by root on ...
소스 빌드가 필요한 경우(예: 개발 브랜치 추적)는 운영 페이지의 설치 섹션을 참고하시기 바랍니다.
2단계 — 첫 실행
설치 직후 VPP는 vpp systemd 서비스로 자동 기동됩니다. 상태를 확인하고 CLI에 접속합니다.
$ sudo systemctl status vpp
$ sudo vppctl
vpp# show version
vpp# show interface
vpp# quit
여기서 show interface는 보통 local0만 보일 것입니다. 아직 실제 네트워크 인터페이스를 VPP에 붙이지 않았기 때문입니다.
vppctl은 인자 없이 실행하면 대화형 세션으로 진입하고, 뒤에 명령을 붙이면 한 번만 실행 후 빠져나옵니다. 예: sudo vppctl show version.
3단계 — TAP 인터페이스로 놀이터 만들기
실제 물리 NIC를 붙이면 이후 시스템 네트워크가 끊길 수 있으므로, 첫 실습은 커널 TAP 인터페이스를 사용합니다. VPP가 TAP를 만들면 리눅스 네임스페이스 쪽에서도 같은 이름이 보입니다.
vpp# create tap id 0 host-ip4-addr 10.10.1.2/24
vpp# set interface state tap0 up
vpp# set interface ip address tap0 10.10.1.1/24
# 리눅스 측 TAP에 주소 설정
$ sudo ip addr add 10.10.1.2/24 dev tap0
$ sudo ip link set tap0 up
host-if-name 옵션: TAP 생성 시 리눅스 측 인터페이스 이름을 직접 지정할 수 있습니다. 이름을 지정하지 않으면 VPP가 자동으로 부여합니다.
vpp# create tap id 0 host-if-name vpp-tap0 host-ip4-addr 10.10.1.2/24
tap_create_v2는 VPP 26.02부터 deprecated되었으며, 향후 릴리스에서 제거될 예정입니다. vppctl create tap CLI 명령은 그대로 사용 가능하지만, Python vpp-api·Go·Rust 바인딩 등으로 바이너리 API를 직접 호출하는 코드는 tap_create_v3로 마이그레이션할 것을 권장합니다.
이제 리눅스 → VPP 방향으로 핑을 쏩니다.
$ ping -c 3 10.10.1.1
PING 10.10.1.1 (10.10.1.1) 56(84) bytes of data.
64 bytes from 10.10.1.1: icmp_seq=1 ttl=64 time=0.2 ms
...
패킷이 성공적으로 오갔다면 VPP가 처음으로 사용자 트래픽을 처리한 것입니다.
4단계 — 내부 들여다보기
방금 지나간 패킷이 VPP 그래프를 어떻게 통과했는지 확인합니다.
vpp# show interface
vpp# show ip fib
vpp# show runtime
show runtime은 노드별 처리량·벡터 크기·클럭 사이클을 보여 주는 VPP의 핵심 성능 뷰입니다. ip4-input, ip4-lookup, ip4-rewrite, tap0-output 같은 노드가 등장합니다.
그래프 트레이스로 실제 경로를 확인해 봅니다.
vpp# clear trace
vpp# trace add tap-rx 10
# (리눅스 측에서 다시 ping 실행)
vpp# show trace
출력은 패킷 1건의 노드 경로와 각 노드에서 본 헤더·메타데이터를 순서대로 보여 줍니다. 이 트레이스는 VPP 학습의 가장 강력한 도구입니다. 트레이스 필터링·노드별 출력 해석·운영 환경에서의 사용 패턴은 디버깅 — 패킷 트레이싱에서 자세히 다룹니다.
show trace 출력 단계별 해석
아래는 TAP 인터페이스로 들어온 ICMP (ping) 패킷 한 건에 대한 실제 show trace 출력 예시입니다. 각 줄의 의미를 주석으로 설명합니다.
vpp# show trace
------------------- Start of thread 0 vpp_main -------------------
Packet 1 # 트레이스된 패킷의 순번 (clear trace 이후 첫 번째 패킷)
00:00:00:123456 tap-rx # 시간(Time) 필드: VPP 기동 이후 경과 CPU 클록 기반 타임스탬프
# 노드명: 패킷이 처음 진입한 처리 노드 (여기서는 tap-rx)
buffer 0x00012abc: current data -14, length 98, buffer-pool 0, ref-count 1
# 버퍼 인덱스(buffer index): 이 패킷의 내부 식별자 (0x00012abc)
# current data: 헤더 오프셋, length: 페이로드 길이(바이트)
PKT MBUF: port 0, nb_segs 1, pkt_len 98
tap: hw_if_index 1 # TAP 인터페이스 하드웨어 인덱스
00:00:00:123500 ethernet-input # 노드명: L2 이더넷 헤더를 파싱하는 노드
IP4: 0a:0a:0a:01:02:03 -> 0a:0a:0a:04:05:06
# 이더넷 src MAC → dst MAC
00:00:00:123510 ip4-input # 노드명: IPv4 헤더 파싱 및 기본 유효성 검사
ICMP: 10.10.1.2 -> 10.10.1.1 # src IP (리눅스 측) → dst IP (VPP 측)
tos 0x00, ttl 64, length 84, checksum 0x0000 dscp CS0 ecn NON_ECN
fragment id 0x3e97, flags DONT_FRAGMENT
ICMP echo_request checksum 0xa1b2 id 12345 seq 1
# ICMP 타입, 체크섬, echo id/seq 번호
00:00:00:123520 ip4-lookup # 노드명: FIB 조회 — 다음 홉 결정
fib 0 dpo-idx 3 # fib-index: 사용된 FIB 테이블 번호 (0 = 기본 테이블)
ICMP: 10.10.1.2 -> 10.10.1.1 # adjacency: 다음 처리 경로 (dpo-idx로 식별)
00:00:00:123530 ip4-local # 노드명: 목적지가 VPP 자신인 패킷 처리 (로컬 수신)
ICMP: 10.10.1.2 -> 10.10.1.1
ICMP echo_request checksum 0xa1b2 id 12345 seq 1
00:00:00:123540 ip4-icmp-input # 노드명: ICMP 처리 — echo_request 수신, echo_reply 생성
ICMP: 10.10.1.2 -> 10.10.1.1
ICMP echo_request checksum 0xa1b2 id 12345 seq 1
트레이스 출력에서 자주 하는 실수
| 실수 | 증상 | 올바른 방법 |
|---|---|---|
clear trace 없이 새 테스트 시작 |
이전 테스트의 패킷과 현재 패킷이 섞여 순번을 신뢰할 수 없음 | 테스트 전에 반드시 vpp# clear trace 실행 |
trace add 인터페이스를 잘못 지정 |
패킷이 실제로 들어오지만 트레이스가 비어 있음 | show interface로 올바른 인터페이스 이름 확인 후 지정 |
| 트레이스 갯수 부족 | 일부 패킷만 캡처되고 나머지는 누락 | trace add tap-rx 50처럼 충분히 큰 숫자 지정 |
| 타임스탬프를 절대 시각으로 오해 | 시간을 실시간 시계와 비교해 혼란 | 타임스탬프는 VPP 기동 후 경과 시간(CPU 클록 기반)이며 절대 시각이 아님 |
| 운영 환경에서 트레이스 수를 크게 설정 | 고속 트래픽 환경에서 메모리·CPU 부하 급증 | 운영 환경에서는 소수(5~10)만 짧게 캡처 후 즉시 clear trace |
5단계 — 플러그인으로 NAT 한 줄 추가
VPP의 기능 확장은 플러그인으로 이뤄집니다. NAT 플러그인은 기본 설치에 포함되어 있으므로, CLI만으로 간단한 정적 NAT를 추가할 수 있습니다.
vpp# nat44 plugin enable
vpp# set interface nat44 in tap0 out tap0 output-feature
vpp# nat44 add static mapping tcp local 10.10.1.2 80 external 10.10.1.1 8080
여기서 목표는 정확한 운영 구성이 아니라 플러그인이 얼마나 가볍게 끼워지는지를 체감하는 것입니다. 실전 NAT 구성은 보안과 터널링 — NAT 섹션을 참고하시기 바랍니다.
6단계 — 정리
vpp# delete tap tap0
vpp# quit
$ sudo systemctl stop vpp
다음 단계로
튜토리얼이 끝났습니다. 다음은 카테고리별 추천 경로입니다.
| 관심사 | 다음에 읽을 문서 |
|---|---|
| VPP가 왜 빠른가 | 기초와 아키텍처 · 그래프 노드 내부 구현 |
| L2/L3 실전 구성 | 데이터 경로 (L2~L4) · 오버레이 · 실전 시나리오 |
| 보안 · 방화벽 · VPN | 보안과 터널링 |
| HTTP/TLS/QUIC 서빙 | 호스트 스택 개요 · TLS · QUIC · HTTP/3 |
| 운영 · 성능 튜닝 | 운영 · 플랫폼 · 확장 · 디버깅 · 성능 측정 |
| 문제가 생기면 | 디버깅 · 성능 측정 |
| 용어가 낯설면 | 용어 요약 |
show runtime과 show trace 두 명령에 익숙해지는 것을 목표로 하시는 것을 권합니다. 이 둘만으로 VPP에서 벌어지는 일의 90%를 읽을 수 있습니다.
설치 오류 대처 가이드
VPP를 처음 설치하거나 실행할 때 자주 겪는 오류 유형과 해결 방법을 정리합니다. 로그 메시지로 빠르게 원인을 찾을 수 있도록 에러 문자열 기준으로 구성하였습니다.
1. Hugepage 설정 오류
VPP 기동 시 아래와 같은 메시지가 나타나면 huge page가 커널에 예약되어 있지 않아 DPDK EAL 초기화에 실패한 것입니다.
# /var/log/vpp/vpp.log 또는 journalctl -u vpp 에서 확인
vpp[1234]: dpdk: failed to init EAL
원인: 시스템에 2 MB hugepage가 할당되어 있지 않거나, startup.conf에서 요청한 heap size를 충족할 만큼 충분하지 않습니다.
해결:
# 현재 hugepage 상태 확인
cat /proc/meminfo | grep -i huge
# 런타임에 1024개(= 2 GB) 즉시 할당
sudo sh -c 'echo 1024 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages'
# 재부팅 후에도 유지하려면 /etc/sysctl.conf에 추가
sudo sh -c 'echo "vm.nr_hugepages = 1024" >> /etc/sysctl.conf'
sudo sysctl -p
startup.conf에서 heap size도 맞춰 설정합니다.
# /etc/vpp/startup.conf
memory {
heapsize 2G
}
numastat -m을 사용하세요.
2. DPDK 포트 인식 실패
VPP가 정상 기동되었는데 show interface에 NIC이 나타나지 않거나 아래 메시지가 찍힌다면 NIC이 DPDK 드라이버에 바인딩되지 않은 것입니다.
vpp[1234]: dpdk: no ports found
원인: NIC이 커널 드라이버(e1000, ixgbe 등)에 묶여 있어 DPDK가 접근할 수 없습니다. IOMMU가 비활성화되어 있으면 vfio-pci도 사용할 수 없습니다.
해결:
# 대상 NIC의 PCI 주소 확인
dpdk-devbind.py --status
# vfio-pci 드라이버 로드 (IOMMU 활성화 환경)
sudo modprobe vfio-pci
# NIC을 vfio-pci에 바인딩 (PCI_ID 예: 0000:03:00.0)
sudo dpdk-devbind.py --bind=vfio-pci
# IOMMU 없는 VM/테스트 환경이라면 uio_pci_generic 사용
sudo modprobe uio_pci_generic
sudo dpdk-devbind.py --bind=uio_pci_generic
IOMMU를 활성화하려면 GRUB 커맨드라인에 intel_iommu=on iommu=pt(Intel) 또는 amd_iommu=on(AMD)를 추가하고 재부팅합니다.
uio_pci_generic은 IOMMU 보호가 없으므로 운영 환경에서는 반드시 vfio-pci를 사용하십시오.
3. API 소켓 권한 오류
vppctl 또는 Python/Go API 클라이언트 연결 시 아래 메시지가 나타납니다.
Connection to VPP api failed
원인: /run/vpp/api.sock의 파일 권한이 현재 사용자에게 허용되어 있지 않습니다.
해결:
# 임시 해결 (테스트 용도)
sudo chmod 777 /run/vpp/api.sock
# 권장 방법: vpp 그룹에 사용자 추가 후 재로그인
sudo usermod -aG vpp $USER
newgrp vpp # 현재 셸에서 즉시 적용
# startup.conf에서 소켓 그룹 설정으로 영구 적용
# api-segment { gid vpp }
startup.conf에서의 설정 예시입니다.
# /etc/vpp/startup.conf
api-segment {
gid vpp
}
4. 메모리 할당 실패
VPP 프로세스가 기동 직후 아래 메시지와 함께 종료됩니다.
clib_mem_init_failed
원인: 프로세스의 locked memory(RLIMIT_MEMLOCK) 한도가 hugepage 매핑에 필요한 크기보다 작습니다. 특히 systemd 서비스 단위 파일이나 셸 기본값이 제한적으로 설정된 경우에 발생합니다.
해결:
# 현재 셸에서 즉시 해제 (테스트)
ulimit -l unlimited
# 영구 적용: /etc/security/limits.conf 에 추가
sudo tee -a /etc/security/limits.conf <<'EOF'
vpp soft memlock unlimited
vpp hard memlock unlimited
root soft memlock unlimited
root hard memlock unlimited
EOF
# systemd 서비스 단위에서 LimitMEMLOCK 설정
# /lib/systemd/system/vpp.service 또는 override.conf
# [Service]
# LimitMEMLOCK=infinity
cat /proc/$(pidof vpp)/limits | grep -i locked으로 실행 중인 VPP 프로세스의 실제 한도를 확인할 수 있습니다.
5. TAP 인터페이스가 OS에 없음
VPP 내부에서 create tap으로 tap0을 생성했는데, 호스트 OS의 네트워크 네임스페이스에서 보이지 않는 경우입니다.
확인 절차:
# VPP 내부 확인 — 인터페이스 생성 여부
vpp# show interface
# tap0 항목이 있고 state가 up인지 확인
# 호스트 OS 확인 — 커널 netdev 존재 여부
ip link show
# tap0 또는 vpp0 항목이 없으면 아래 조건 점검
# tun 커널 모듈 로드 확인
lsmod | grep tun
sudo modprobe tun # 없으면 로드
# /dev/net/tun 권한 확인
ls -la /dev/net/tun
일반적인 원인과 체크리스트입니다.
| 원인 | 확인 방법 | 조치 |
|---|---|---|
tun 모듈 미로드 | lsmod | grep tun | sudo modprobe tun |
/dev/net/tun 권한 부족 | ls -la /dev/net/tun | sudo chmod 0666 /dev/net/tun |
| 네임스페이스 불일치 | ip netns list | create tap에 host-ns 옵션 지정 |
| VPP가 non-root로 실행 | ps aux | grep vpp | CAP_NET_ADMIN 부여 또는 root 실행 |