1. 개요
VXLAN(Virtual eXtensible LAN)은 Ethernet 프레임을 UDP 패킷에 통째로 넣어 IP 망 너머로 나르는 터널 기술이다. 원래 프레임은 손대지 않고, 바깥에 노드 사이 배달용 헤더를 덧씌운다. 중간 장비는 바깥 헤더만 보고 배달하므로 안쪽 주소를 몰라도 된다.
라우터에서 끝나야 할 LAN 을 라우터 너머까지 이어 붙이는 셈이다. 그래서 VXLAN 처럼 실제 망 위에 가상의 망을 얹는 방식을 오버레이(overlay) 라고 부른다.
2. 헤더 구조
바깥 헤더는 평범한 Ethernet · IP · UDP 다. 중간 장비 입장에서는 노드 A 가 노드 B 에게 보내는 UDP 패킷 하나일 뿐이다.
3. VTEP
VTEP(VXLAN Tunnel End Point)은 프레임을 감싸고 벗기는 터널의 양 끝이다. 보내는 쪽 VTEP 이 원래 프레임에 바깥 헤더를 씌우고, 받는 쪽 VTEP 이 벗겨서 원래 목적지로 넘긴다. VTEP 은 리눅스 커널의 가상 장치일 수도, 데이터센터 스위치일 수도 있다.
4. UDP 포트
IANA 가 VXLAN 에 배정한 표준 포트는 UDP 4789 다. 리눅스 커널은 표준이 정해지기 전에 쓰던 8472 를 기본값으로 남겨 두었고, flannel 도 리눅스에서는 이 기본값(8472)을 쓴다. 방화벽이나 클라우드 보안 그룹에서 노드 사이 이 포트가 막혀 있으면 다른 노드의 Pod 와 통신이 안 된다.
5. MTU
바깥 헤더가 붙는 만큼 안쪽에 담을 수 있는 크기가 줄어든다. 노드의 MTU 가 1500 이면 Pod 쪽 MTU 는 1450 이어야 봉투째 1500 안에 들어간다. CNI 는 Pod 의 인터페이스 MTU 를 이 값으로 낮춰 둔다.
RFC 7348 은 VTEP 이 VXLAN 패킷을 조각내지 말라고 정한다. MTU 가 어긋나면 큰 패킷이 조용히 버려지고, 작은 요청은 되는데 큰 응답만 멈추는 증상이 나온다.
6. 상대 VTEP 찾기
보내는 VTEP 은 “Pod B 의 MAC 이 어느 노드 뒤에 있는지” 를 알아야 바깥 IP 를 정할 수 있다. 이 표를 채우는 방법은 셋이다.
7. 쿠버네티스의 VXLAN
flannel 의 VXLAN 모드는 노드마다 flannel.1 이라는 VXLAN 장치(VNI 1)를 만든다. 다른 노드의 Pod 서브넷으로 가는 경로가 이 장치를 가리키고, 이 장치로 들어간 프레임이 감싸져 노드의 실제 인터페이스로 나간다.
ip route | grep flannel.1 # 10.244.2.0/24 via 10.244.2.0 dev flannel.1 onlink
ip -d link show flannel.1 # vxlan id 1 local 192.168.10.11 dev eth0 dstport 8472
ip neigh show dev flannel.1 # 다른 노드 VTEP 의 MAC (flannel 이 직접 넣은 줄)
bridge fdb show dev flannel.1 # 그 MAC 이 어느 노드 IP 뒤에 있는지
# 노드 사이 선 위에서 실제 VXLAN 패킷 보기
tcpdump -i eth0 -n -T vxlan udp port 8472 # "VXLAN, flags [I] (0x08), vni 1" 뒤로 안쪽 Pod 주소가 보인다
-T vxlan 을 빼면 tcpdump 는 8472 번 포트를 다른 프로토콜(OTV)로 해석한다. 4789 번이면 지정하지 않아도 VXLAN 으로 읽는다.
Calico 는 기본적으로 라우팅(BGP)으로 노드를 잇고, 필요할 때만 VXLAN 을 켠다. Cilium 도 VXLAN 터널 모드를 지원한다.
8. VLAN 과의 비교
이름이 비슷하지만 하는 일은 반대다. VLAN 은 한 LAN 을 나누고, VXLAN 은 떨어진 LAN 을 잇는다.
9. 관련 문서
- VLAN — 같은 스위치 안에서 LAN 을 나누는 12비트 태그
- LAN — VXLAN 이 라우터 너머로 늘이는 대상
- CNI — VXLAN 장치를 만들고 경로를 넣는 플러그인 규격
- Network & K8s.01-2 Across the Network — Pod 사이 패킷이 봉투에 담기는 과정
10. 출처
VXLAN 은 RFC 7348 이 정의한다. VNI 크기, 표준 포트, 조각내기 금지가 모두 여기 있다.
“Each VXLAN segment is identified through a 24-bit segment ID, termed the “VXLAN Network Identifier (VNI)”. This allows up to 16 M VXLAN segments to coexist within the same administrative domain.”
“IANA has assigned the value 4789 for the VXLAN UDP port, and this value SHOULD be used by default as the destination UDP port.”
“VTEPs MUST NOT fragment VXLAN packets.”
flannel 문서는 리눅스 기본 포트가 커널 기본값 8472 라고 밝힌다.
“On Linux, defaults to kernel default, currently 8472, but on Windows, must be 4789.”