호스트 네트워크 구성
호스트 네트워크 구성 (Host network configuration)
이 문서는 Calico Open Source VPP 데이터플레인이 초기화 과정에서 적용하는 호스트 네트워크 구성을 다뤄요. VPP-Host 연결은 VPP와 Linux가 기본 인터페이스의 주소를 함께 공유한다는 점이 조금 특별해요. VPP가 시작할 때 무슨 일이 일어나는지, 그리고 패킷이 어떤 흐름으로 오가는지 살펴봐요.
출처: 문서
본문
큰 그림 (Big picture)
VPP-Host 연결은 VPP와 Linux가 기본(primary) 인터페이스의 주소를 함께 공유한다는 점에서 조금 특별해요. 기본 인터페이스(아래 다이어그램의 uplink 인터페이스)가 enp216s0f1이라는 이름으로 192.168.0.1/24 주소와 함께 설정되어 있다고 해 봐요.
이 주소는 uplink(호스트의 메인 인터페이스, 즉 a.k.a main interface)의 첫 번째 주소로서 api-server가 리스닝하는 주소이기도 해야 해요.
VPP가 시작할 때 (When VPP starts)
-
VPP는 선택한 드라이버로 기본 인터페이스를 잡아요. 드라이버에 따라 전용 네트워크 네임스페이스로 옮기거나, Linux netdev로서 완전히 제거해요. 어느 쪽이든 인터페이스는 호스트의 루트 네트워크 네임스페이스에서 사라져요.
-
VPP 안에서 Linux에 있던 것과 동일한 구성(주소, 라우트)으로 설정해요. 따라서 VPP에서
show int addr를 실행하면 다음과 같이 나와요.vpp# sh int addr avf-0/d8/a/0 (up): L3 192.168.0.1/24 -
VPP와 호스트 사이에
tap인터페이스를 만들어요. -
이 tap 인터페이스에는 호스트의 루트 네트워크 네임스페이스에 있던 원래 인터페이스와 같은 이름과 MAC 주소가 주어져요.
-
이 인터페이스는 원래 인터페이스에 호스트가 설정해 두었던 모든 주소와 라우트로 다시 설정돼요.
ip addr show enp216s0f1 3: enp216s0f1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000 link/ether 52:54:00:40:46:8e brd ff:ff:ff:ff:ff:ff inet 192.168.0.1/24 brd 192.168.0.255 scope global eth1 valid_lft forever preferred_lft forever ip route default via 192.168.0.254 dev enp216s0f1 proto dhcp src 192.168.0.1 metric 100 ${SERVICE_CIDR} via 192.168.0.254 dev enp216s0f1 proto static mtu 1440 ${POD_CIDR} via 192.168.0.254 dev enp216s0f1 proto static mtu 1440 192.168.0.0/24 dev enp216s0f1 proto kernel scope link src 192.168.0.254새
tap인터페이스(이 예에서는enp216s0f1)에는 쿠버네티스 서비스 CIDR과 파드 CIDR로 가는 라우트도 설정돼요. 그래서 Linux 호스트가 VPP를 통해 워크로드에 도달할 수 있어요. 이 라우트들은 캡슐화를 수용하려고 줄어든 MTU를 사용해요. -
VPP에서는
tap0이라는 이름으로 찾을 수 있어요. 기본 인터페이스avf-0/d8/a/0의 자식으로 unnumbered로 설정돼요.vpp# sh int addr tun0 (up): unnumbered, use avf-0/d8/a/0 L3 192.168.0.1/24 -
기본 punt 경로로도 등록돼요. 이는 VPP가 버리게 될 모든 트래픽(VPP 자신이 처리하지 않는 VPP 주소로 가는 트래픽을 포함하지만, VPP가 캡슐화 해제/복호화하는 터널 트래픽은 제외)이 이 인터페이스로 전달되어 Linux 호스트가 수신하고 처리하게 된다는 뜻이에요.
vpp# sh ip punt redirect rx local0 via: path-list:[31] locks:1 flags:no-uRPF, uPRF-list:24 len:1 itfs:[2, ] path:[41] pl-index:31 ip4 weight=1 pref=0 attached-nexthop: oper-flags:resolved, 169.254.0.1 tap0 [@0]: ipv4 via 169.254.0.1 tap0: mtu:1500 next:6 flags:[features ] 52540040468e02ca11c0fd100800 forwarding [@1]: ipv4 via 169.254.0.1 tap0: mtu:1500 next:6 flags:[features ] 52540040468e02ca11c0fd100800v6 구성은 다음과 같아요:
vpp# sh ip6 punt redirect
패킷 흐름 - uplink로 들어오는 패킷 (Packet flow - incoming packet on the uplink)
호스트로 향하는 패킷이 uplink에 도착한다고 해 봐요. src=192.168.0.2,dst=192.168.0.1이라고 해요.
- VPP가 수신하고, 목적지 주소가 자신의 인터페이스에 설정된 주소임을 알아채요
- 이 패킷에 대해 특별한 처리가 설정되어 있지 않기 때문에 punt 경로를 찾아
tap0으로 보내요 - Linux는
192.168.0.1/32로 설정된 tap 인터페이스에서 이를 수신하고 정상적으로 처리해요
응답은 이제 호스트가 src=192.168.0.1,dst=192.168.0.2로 내보내요.
- Linux는
192.168.0.0/24의 라우트를 찾아 tap 인터페이스로 포워딩해요 - VPP가
tap0인터페이스에서 이를 수신해요 - fib에서
192.168.0.2를 찾아 uplink 인터페이스(192.168.0.1/24로 설정됨)의 라우트를 발견해요 - 패킷은 uplink로 전송돼요
패킷 흐름 - 파드가 api-server와 통신 (Packet flow - pod talking to the api-server)
api server가 Node A에 살고 있다고 해 봐요.
Node B의 파드가 Node A의 api-server와 통신하고 싶다면, 패킷 흐름은 위에서 설명한 것과 같아요.
Node B에서는 표준 라우팅이 일어나요 (sh ip fib <someip>가 이 노드의 상세를 보여줘요)Node A에 도달하면 이전과 같은 상황이 돼요
Node A의 파드가 Node A의 api-server와 통신하고 싶다면, 패킷이 src=10.0.0.1,dst=192.168.0.1이고 10.0.0.1이 파드 주소라고 해 봐요. 그러면:
- uplink에서 온 패킷인 것과 정확히 같은 방식으로 일이 진행돼요
- 이번에는 파드 인터페이스에 해당하는
tunN을 통해 vpp로 패킷이 들어오고, 그 다음tap0으로 punt되어 호스트를 향해요 - 호스트에서 돌아오는 트래픽은 VPP가
tap0에서 수신하고,tunN의 파드로 직접 라우팅돼요
더 알아보기 (Learn more)
- VPP 데이터플레인의 구현 차이와 알려진 이슈는 VPP 구현 상세와 알려진 이슈 문서를 참고하세요.
- VPP 데이터플레인으로 Calico를 시작하는 방법은 시작하기 문서의 VPP 섹션에서 확인할 수 있어요.