시작하기

VPP를 처음 돌려보는 분을 위한 단계별 실습 가이드입니다. 설치, 첫 실행, TAP 인터페이스로 그래프 통과 확인, 트레이스 분석, 플러그인 확장까지 한 번의 세션으로 체험합니다.

이 문서의 대상: VPP를 한 번도 돌려보지 않은 분을 위한 실습 가이드입니다. Ubuntu 기준으로 설치부터 첫 패킷 처리까지 단계별로 안내합니다. 개념적 배경은 기초와 아키텍처를 함께 읽으시면 좋습니다.

시작 전 준비물

다음 환경을 권장합니다. VM/컨테이너에서도 대부분 동작하지만 성능 측정은 베어메탈이 필요합니다.

주의: 본 튜토리얼은 로컬 실험을 전제로 합니다. 프로덕션 환경이나 공유 서버에서는 Hugepage 할당과 DPDK 바인딩이 다른 서비스에 영향을 줄 수 있습니다.

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
VPP 25.10 신기능 — host-if-name 옵션: TAP 생성 시 리눅스 측 인터페이스 이름을 직접 지정할 수 있습니다. 이름을 지정하지 않으면 VPP가 자동으로 부여합니다.
vpp# create tap id 0 host-if-name vpp-tap0 host-ip4-addr 10.10.1.2/24
Deprecated (26.02+): TAP 생성에 사용되는 바이너리 API 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
운영 · 성능 튜닝운영 · 플랫폼 · 확장 · 디버깅 · 성능 측정
문제가 생기면디버깅 · 성능 측정
용어가 낯설면용어 요약
학습 팁: VPP의 강점은 그래프 노드 모델에 있으므로, 처음 한 달은 show runtimeshow 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
}
팁: 할당 가능한 hugepage 수는 물리 RAM과 NUMA 토폴로지에 따라 다릅니다. NUMA 노드별로 확인하려면 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 tunsudo modprobe tun
/dev/net/tun 권한 부족ls -la /dev/net/tunsudo chmod 0666 /dev/net/tun
네임스페이스 불일치ip netns listcreate taphost-ns 옵션 지정
VPP가 non-root로 실행ps aux | grep vppCAP_NET_ADMIN 부여 또는 root 실행