Skip to content

Latest commit

 

History

History
135 lines (90 loc) · 9.56 KB

File metadata and controls

135 lines (90 loc) · 9.56 KB

v26.03.0 — OVN Flow-Based Tunnel: 섀시마다 만들던 터널 포트를 타입별 공유 포트로 접기

메타데이터

항목 내용
프로젝트 OVN (Open Virtual Network)
관련 릴리스 v26.03.0 (2026-03-20)
구현 커밋 79302556 — controller: Add experimental flow-based tunnel support (2025-08-25)
설정 external_ids:ovn-enable-flow-based-tunnels=true (실험적 기능, 기본값 false)
발견 출처 OVN v26.03.0 Release Notes의 experimental flow-based tunnel 항목
검증 근거 커밋 79302556의 실제 diff(controller/encaps.c, local_data.c, physical.c, ovn-controller.c, ovn-controller.8.xml)
소스 라이선스 Apache License 2.0

개요

OVN v26.03은 각 원격 chassis와의 연결마다 전용 OVS tunnel port를 만드는 기존 방식을 대신해, tunnel type별 Geneve/VXLAN 포트 하나를 여러 원격 chassis가 공유하는 flow-based tunnel을 실험적으로 추가했다. 공유 포트에는 local_ip=flow, remote_ip=flow, key=flow를 설정하고, ovn-controller가 생성하는 OpenFlow action이 패킷마다 tunnel source/destination과 metadata를 채운다. 한 로컬 chassis의 tunnel port 수는 원격 chassis 수에 비례하던 구조에서 지원 tunnel type 수에 가까운 구조로 줄어든다.

사전 지식

OVN의 논리 포트는 결국 OVS의 물리 출력 포트로 번역된다

OVN northbound의 logical switch/router는 중앙의 ovn-northd를 거쳐 southbound DB의 logical flow와 Port_Binding으로 변환된다. 각 hypervisor에서 실행되는 ovn-controller는 이 정보를 읽어 로컬 OVS bridge(br-int)에 OpenFlow flow를 설치한다.

목적 logical port가 다른 chassis에 있으면 패킷을 overlay tunnel로 보내야 한다. 기존 구조에서는 로컬 chassis가 원격 chassis별로 Geneve 또는 VXLAN interface를 만들고, 각 interface가 고정된 remote_ip를 가졌다. ovn-controller는 목적 Port_Binding의 chassis를 찾은 뒤 그 chassis에 대응하는 tunnel port의 ofport로 출력했다.

고정 endpoint tunnel port는 이해하기 쉽지만 객체 수가 커진다

고정 tunnel port는 "이 OVS port는 저 chassis로 간다"는 대응 관계가 명확하다. BFD를 port endpoint에 붙이거나, IPsec의 원격 이름을 정하거나, chassis별 상태를 추적하기도 쉽다. 반면 chassis가 N개인 대규모 클러스터에서는 각 chassis가 나머지 chassis를 향한 port를 가져야 하므로 전체 port 수가 대략 N² 방향으로 증가한다. 한 chassis에 여러 encap IP 조합까지 있으면 로컬 port 수도 더 늘어난다.

OVS tunnel interface는 endpoint를 반드시 고정값으로만 받을 필요가 없다. remote_ip=flow를 사용하면 OpenFlow가 packet processing 시점에 tun_dst를 채울 수 있다. 이 기능을 쓰면 tunnel port는 전송 장치 역할만 하고, 실제 원격 endpoint 선택은 flow action으로 옮길 수 있다.

변경 분석

변경 전: topology의 각 edge가 OVSDB tunnel port였다

encaps_run()의 기존 경로는 southbound Chassis table을 순회하고, transport zone이 겹치는 각 원격 chassis에 대해 chassis_tunnel_add()를 호출했다. 생성된 port는 external_ids:ovn-chassis-id로 원격 chassis와 연결됐고, 물리 flow 생성 코드는 chassis_tunnels map에서 대상 chassis의 ofport를 찾아 출력했다.

[변경 전 — port-based tunnel]

Chassis A / br-int
  ├─ ovn-B-geneve (remote_ip=B) ─────────▶ Chassis B
  ├─ ovn-C-geneve (remote_ip=C) ─────────▶ Chassis C
  ├─ ovn-D-geneve (remote_ip=D) ─────────▶ Chassis D
  └─ ovn-E-geneve (remote_ip=E) ─────────▶ Chassis E

출력 flow:
  logical outport가 C에 있음 → C용 tunnel ofport로 OUTPUT

chassis가 늘 때마다 각 기존 chassis에도 새 tunnel port가 추가된다.

shared port는 tunnel type별로 한 번만 만든다

create_flow_based_tunnels()는 로컬 chassis가 지원하는 encap type을 중복 제거한 뒤, type마다 한 port만 보장한다. interface option은 다음 세 필드를 모두 flow로 둔다.

options:local_ip=flow
options:remote_ip=flow
options:key=flow

port의 external_ids:ovn-chassis-id는 특정 chassis 이름 대신 flow이고, 별도 ovn-tunnel-type에 Geneve/VXLAN 종류를 기록한다. local_nonvif_data_run()은 이 표식을 읽어 flow_tunnels[TUNNEL_TYPE_MAX] 배열에 type별 ofport를 보관한다. 기존의 chassis→tunnel hash map과 별개의 빠른 조회 경로를 만든 것이다.

원격 endpoint 선택을 OVSDB 객체에서 OpenFlow action으로 이동했다

목적 Port_Binding이 원격 chassis에 연결되어 있으면 put_flow_based_remote_port_redirect_overlay()가 다음 순서로 action을 만든다.

  1. 로컬과 원격 chassis가 함께 지원하는 tunnel type을 선택한다. 현재 우선순위는 Geneve, 그다음 VXLAN이다.
  2. Port_Binding.encap에 지정된 endpoint가 있으면 그 IP를 쓰고, 없으면 원격 chassis의 기본 encap IP를 고른다.
  3. 기존 put_encapsulation()으로 datapath key와 logical outport 같은 tunnel metadata를 넣는다.
  4. put_set_tunnel_ip()이 IPv4이면 MFF_TUN_SRC/MFF_TUN_DST, IPv6이면 MFF_TUN_IPV6_SRC/MFF_TUN_IPV6_DST에 endpoint를 load한다.
  5. type에 대응하는 shared tunnel ofport로 출력한다.

unicast뿐 아니라 multicast/broadcast fan-out도 원격 chassis를 순회하면서 endpoint IP를 바꿔 같은 shared port로 여러 번 출력하도록 별도 경로가 추가됐다. 수신 방향은 기존 tunnel ingress flow 생성 함수를 재사용한다. shared port의 ofport와 type으로 임시 chassis_tunnel 구조체를 만들어 decapsulation·MTU 관련 ICMP 처리 flow를 동일하게 설치한다.

설계 결정 및 트레이드오프

tunnel port의 개수를 줄이는 대신 flow의 책임을 키웠다

기존 설계는 topology 정보를 OVSDB의 port 객체 수로 표현했다. 새 설계는 type별 port만 남기고 "이 패킷의 원격 chassis는 어디인가"를 OpenFlow action에 인코딩한다. 따라서 chassis 추가가 모든 노드의 port 생성으로 번지지 않고, 로컬 chassis 기준 port 수는 지원 type 수 O(T)에 가까워진다. 대신 physical flow 생성 코드가 remote chassis, port별 encap 선택, IPv4/IPv6 tunnel field를 모두 정확히 계산해야 한다.

기존 모드를 없애지 않고 명시적 opt-in으로 두었다

flow-based 경로는 ovn-enable-flow-based-tunnels가 참일 때만 활성화되고 기본값은 거짓이다. encaps_run()과 physical flow 생성은 port-based/flow-based 분기를 모두 유지한다. 대규모 환경에는 객체 수 감소라는 이득이 크지만, 기존 port 기반 운영 도구와 장애 진단 방식은 "remote chassis마다 port가 있다"는 전제에 의존할 수 있다. 실험적 opt-in은 이 운영 모델 변화까지 함께 검증할 시간을 준다.

port endpoint에 결합된 기능은 아직 공유할 수 없다

커밋과 man page는 알려진 제한을 명시한다.

  • IPsec은 지원하지 않는다. 공유 port는 패킷마다 remote chassis가 달라져 기존처럼 port에 고정 remote_name을 둘 수 없다.
  • tunnel endpoint 간 BFD를 지원하지 않는다. 따라서 BFD에 의존하는 HA chassis, 예를 들어 Distributed Gateway Port redundancy를 사용할 수 없다.
  • 코드에는 multi-chassis port의 강제 tunneling 경로가 flow-based tunnel을 추가 지원해야 한다는 XXX도 남아 있다.

즉 port 수를 줄인 대가는 endpoint별 port에 붙던 보안·liveness 의미를 별도의 flow-aware 모델로 다시 설계해야 한다는 것이다.

[변경 후 — flow-based tunnel]

Chassis A / br-int
  ├─ ovn0-geneve (local_ip=flow, remote_ip=flow, key=flow)
  └─ ovn0-vxlan  (local_ip=flow, remote_ip=flow, key=flow)

원격 logical port가 Chassis C에 있을 때:
  Port_Binding → C의 선호 encap IP 선택
       │
       ▼
  OpenFlow actions
    set tunnel metadata
    load A encap IP → tun_src
    load C encap IP → tun_dst
    output shared Geneve ofport
       │
       └──────────────────────────────▶ Chassis C

원격 chassis 수가 늘어도 type이 같으면 tunnel port는 추가되지 않는다.

더 살펴볼 점

  • endpoint별 BFD 상태를 shared port 위에서 표현하려면 어떤 key와 state model이 필요할까?
  • IPsec의 peer identity를 packet별 tunnel destination과 안전하게 결합할 OVS/OVN 인터페이스가 추가될 수 있을까?
  • port 수 감소가 큰 환경에서 OVSDB transaction·reconcile 시간과 OpenFlow entry 수는 각각 얼마나 달라질까?

참고 자료

참고 외 별도 확인 링크

본문 참고 자료로 충분했다.