Byeo

Revisiting the Open vSwitch Dataplane Ten Years Later 1 본문

프로그래밍 (Programming)/논문 (Paper)

Revisiting the Open vSwitch Dataplane Ten Years Later 1

BKlee 2024. 4. 24. 22:51
반응형

본 포스트는 sigcomm '21의 Revisiting the Open vSwitch Dataplane Ten Years Later를 요약하였습니다.

 

Abstarct

 해당 논문은 수천 명의 VMware 고객이 사용하는 data center 가상화를 위한 NSX 상품의 일부로서, Open vSwitch를 지원하고 운영해온 경험을 공유한다. 2009년부터 시작된 OVS는 userspace와 kernel의 강한 결합을 분리하였다. 이 분리는 성능을 위해서 반드시 필요했지만, 유지 보수의 어려움이 남아있다. 나아가, in-kernel packet processing은 DPDK와 같은 새로운 option에 비해 상당히 느린 상황이다.

 kernel/user split으로부터 야기하는 이 문제들을 해결하기 위해서 OVS는 새로운 아키텍쳐를 도입해야만 한다. 이 논문에서는 우리가 탐구했으나 적용하지 않은 2가지 기법을 먼저 설명한다. 하나는 data center의 운영자에게 중요한 compatibility를 포기해야 했고, 다른 하나는 성능이 좋지 않았다. 그 대신에, 우리는 AF_XDP 라는 socket type에 기반한 세 번째 접근법을 소개한다. 이는 성능을 유지하면서도 유지 보수의 문제를 해결한다. 새로운 코드는 mainstream OVS에 이미 merge되었으며, 성능 평가와 교훈을 공유한다.

 

1. Introduction

 Computing 가상화는 data center에서 상당히 일반화되었다. 물리 서버보다 VM이 endpoint가 되는 경우가 더 많으며, VMware NSX, Microsoft Hyper-V 등의 가상화 시스템은 software switch (e.g., VFP, Contrail vRouter, Open vSwitch)를 이용해 packet들에게 rule을 적용하고 전송하는 시스템을 포함하고 있다. 

 

 이 논문에서는 Open vSwitch를 지원해온 경험을 공유한다. OVS의 개발을 시작할 때, 첫 번째 목표는 comptability 달성이었다. 예시로, OVS는 이미 지배적이던 Linux Bridge에 견줄 수 있도록 bridge compatibility, daemon, 심지어 migration을 쉽게할 수 있도록 additional kernel module 등을 제공하도록 했었다. OVS는 kernel network device driver (e.g., ip, ping)와 tool들 (e.g., tcpdump)에 호환될 수 있도록 유지중이다. bridge compatibility는 시간이 흐름에 따라 사라졌지만, 여전히 driver와 tool의 compatibility는 중요한 요소로 남아있다.

 

 또 다른 중요한 디자인 목표는 성능이다. OVS가 처음 디자인되었을 때, 오로지 kernel만이 packet을 빠르게 처리할 수 있었다. 하지만 OVS는 kernel에 전부 구현하기에는 너무 복잡했고, 따라서 OVS 초기 architecture는 userspace와 kernel module로 분리되었다. User process는 policy를 설정하고, kernel module은 이 policy를 고성능으로 구현하기 위해서 최소한의 메커니즘만 제공한다. Kernel module은 Linux kernel internal interface들 및 userspace process와 강하게 결합되어 있다. 성능을 위해서 이러한 design choice는 kernel 개발자와 OVS 개발자들로부터 수용되었으나, 다음과 같은 크나큰 문제를 OVS 개발자와 user들에게 남기게 되었다. 

  • Maintainability: Linux와 Open vSwitch의 개발자는 완전 다르다. 하지만 강하게 결합되어 있는 이 구성은 두 개발자가 디자인 및 개발을 수행할 때 합의를 요한다. OVS의 feature는 Linux 개발자의 수용여부에 따라서 제한될 수 밖에 없다.
  • Operability: Kernel module에 영향을 주는 OVS version upgrade나 bug fix는 kernel update 및 production 재시작을 필요로 한다. 이는 구동중인 worklaoid들을 방해하거나 다른 server로 migration을 강제한다.
  • Performance: 전통적인 in-kernel packet processing은 이제 DPDK보다 상당히 느리다.

 이를 해결하기 위해 고안했으나 호환성 문제 등으로 인해 적용하지 못한 두 가지 구조를 2.2.1과 2.2.2에서 설명한다. 

 우리는 최종적으로 세 번째 접근법으로 수렴했다. 메인 아이디어는 packet processing의 대부분을 AF_XDP라는 새로운 Linux socket type을 이용해서 userspace로 가져오는 것이다. 현존하는 software와 어떻게 호환성을 보장하고 고성능을 유지하는지 Section 3에서 후술한다. Section 4에서는 새로운 OVS를 어떻게 NSX network 가상화 solution에 통합했는지 설명하고 section 5에서는 성능을 평가한다. 우리의 새로운 OVS 접근은 OVS-dpdk 성능에 근접한다. container networking에서는 DPDK에 비해 latency가 12배 빠르며, throughput은 4배가 빠르다. 그리고 새로운 OVS는 쉽게 설치 및 업그레이드가 가능하다. 나아가, validation과 troubleshooting도 간단해졌다. 이는 Section 6에서 소개한다.

 

 이 논문의 contribution은 다음과 같다:

  • packet I/O channel로서 AF_XDP를 사용한다. datapath는 userspace에 둔다.
  • OVS에서 사용할 AF_XDP userspace driver의 구현과 성능 최적화를 시연한다.
  • 새로운 OVS가 NSX와 같은 네트워크 가상화 솔루션에서 어떻게 통합되는지 보여준다.
  • OVS의 성능을 상품적 측면에서 평가한다.
  • OVS kernel datapath를 userspace로 옮기려고 노력했던 2년간의 노력에서 얻은 교훈을 공유한다.

 

작성자 요약:
 OVS는 역사적으로 성능과 호환성을 위해서 software switch 기능을 user space 및 kernel space로 분리하였다. 
 User space는 rule을 설정하고 Kernel space에서는 이 rule을 받아 packet processing을 수행할 수 있도록 기능들을 구현하였다.
 하지만 이러한 디자인은 OVS kernel module 개발자와 Linux kernel 개발자로 하여금 괴리를 피할 수 없었고 다음과 같은 과제가 남게되었다.
 (1) 유지 보수: OVS 개발자가 기능을 추가하고 싶어도 Linux Kernel 개발자로부터 수용을 받지 못하면 구현이 제한된다.
 (2) 운영성: OVS Kernel을 수정하려면 kernel update 및 시스템 재시작을 필요로 한다.
 (3) 성능: 새로운 packet processing framework (e.g., DPDK)보다 느려서, 빠른 성능이라는 장점도 없어졌다.

이를 해결하기 위해서 AF_XDP를 사용해 기존의 in-kernel datapath를 userspace로 끌어 올렸으며, 따라서 update나 install도 간단히 userspace에서 할 수 있도록 하였다.

 

 

2. Enterprise Challenges

저자는 주로 VMware NSX를 예시로 드는데, 이 상품은 data center 운영자가 고객이 가져다가 직접 설치하기에 수많은 Linux distribution, kernel versions, hardware 등을 지원할 수 있어야 한다.

2.1 Maintainability

OVS 개발자와 Linux Kernel 개발자는 분리되어있다. 따라서 OVS 개발자는 새로운 코드를 개발하면 그 이유를 Linux Kernel 개발자를 납득해야한다. 또한, Kernel version을 올리더라도 호환성 유지를 위하여 user application의 변경을 요하는 수정은 금지한다. 이는 OVS의 userspace도 포함이며, 결국 kernel version x에서 OVS a를 사용할 수 있다면, kernel version y (>x)도 모두 a를 사용할 수 있어야 한다는 의미이다. 따라서 OVS는 기존의 kernel module을 수정할 수 없기에 주로 기능을 확장하는 방향으로 발전해왔다. (OVS kernel module 개발자와 OVS userspace 개발자는 동일할텐데 말이다!)

 

 이런 높은 장벽은 OVS 개발자에게 좌절을 가져다주었다. 실제로 Stateless Transport Tunneling (STT) encapsulation과 Exact-Match flow cache (EMC)를 거부당했기 때문. (EMC를 거부당했다는 사실은 지금알았다.)

 그러나 수용이 된다 할지라도, user/kernel coupling은 약 몇 년 (1~2년, 심지어는 그 이상)의 지연을 초래한다. Code review 후, next upstream Linux Kernel version에 merge가 되고, 이는 다시 오랜 기간 걸쳐 Linux distribution vendor (e.g., Ubuntu, Red Hat)이 사용하기 시작하기때문. 

 

Takeaway 1
User/Kernel을 분리한 디자인은 software switch의 기능을 확장하는데 제약 / 오랜 시간을 소요한다.

 

2.1.1 Out-of-Tree Kernel Module

완전히 module처럼 OVS를 분리하는 방법이 가능하다. 하지만, 정책상 새로운 feature를 추가할 때 반드시 upstream Linux tree에서 시작해야 한다. 그렇지 않으면 거부당할 수 있기때문. 따라서 (1) out-of-tree module은 upstream을 쫓아가는데 많은 노력을 투자하게 된다.

 Figure 1은 새로운 feature 추가를 위해서 "New Features" label 하위에서 추가/삭제 된 코드 수이다.

 또한, (2) out-of module은 개발자가 꾸준하고 빠르게 코드를 관리해야 한다. Figure 1의 "Backports" 막대는 새로운 kernel release version과 호환되도록 1년마다 수정한 코드의 줄 수를 나타낸다. 예를 들어, OvS에서 ERSPAN을 지원하기위하여 kernel module에는 50줄밖에 추가가 필요하지 않았다. 하지만 오래된 Kernel version에서는 IPv6 GRE를 지원하지 않아서 5,000줄의 코드를 추가로 작성해야했다.

 (3) 누군가가 out-of-tree kernel module을 매 배포 대상마다 검증해야한다. (4) enterprise 버전에서는 third-party kernel module을 (계약상으로) 지원하지 않는 경우가 있다

 

 이러한 이유로 OVS out-of-tree kernel module은 얻는 이익보다 비용이 더 크다고 판단이 되었다. 그래서 OVS2.15 버전은 out-of-tree module이 deprecated 되었으며, 2022년 8월에 배포될 OVS 2.18에서는 이러한 지원을 모두 제거할 예정이다. (사실 github 들어가보면 2.18은 없고 3.0부터 있다. 그리고 2.17과는 다르게 3.0은 datapath directory가 없다!!) [각주:1]

 

Takeaway #2
out-of-tree kernel module은 user/kernel split software switch의 문제점을 해결하지 못했다.

 

 

2.2 Architecture

user/kernel split 문제를 해결하기 위해서 근본적인 architecture부터 재접근하기로 하였다.

 

2.2.1 All-Userspace OVS with DPDK

한 가지 해결책은 전부다 userspace로 올리는 것이다. packet processing을 가속화하는 DPDK를 사용해서 말이다. 이는 Linux Kernel과 더이상 엮이지 않아서 유지보수 문제를 해결할 수 있고, 나아가 OVS with DPDK는 버그 수정도 간단히 process version만 upgrade하면 된다는 장점이 있다. DPDK를 사용하는 것은 Linux internal interface의 급격한 변화에도 자유롭다라는 장점이 있다. 하지만 DPDK 또한 API가 바뀔 수는 있긴 하다는 risk는 있다. 이 때문에 OVS version과 DPDK version이 물리는 문제가 발생할 수 있다. 

 

 OVS-DPDK는 또 다른 다양한 종류의 유지보수 문제를 겪는다. DPDK는 자신만의 network device driver를 사용하고, kernel을 bypass하며 동작한다. 따라서 우리가 잘 알고있는 Table 1에 명시된 도구들 (e.g., NIC을 cofnig하거나 관리하거나 모니터링 하는 등)을 사용할 수 없게된다. User는 차악으로 DPDK가 제공하는 tool들 (e.g., testpmd, dpdk-pdump, dpdk-procinfo)를 사용해야만 한다. 이는 VM, container, physical machine 등을 큰 규모로 운영하고 있는 운영자에게 치명적인 단점이다. 

 

 운영자는 반드시 NIC을 DPDK만을 위해서 dedicate해야 한다. 이 말은 networking configuration을 위해서 별도의 NIC을 추가로 하나 더 설정해야 한다는 의미이다. 이는 결국 관리 부담으로 이어진다. 마지막으로 DPDK 성능은 하나 또는 그 이상의 CPU core를 모두 할당해야 하며, 이는 인프라 운영자로 하여금 거부할 수 밖에 없는 선택지로 남게된다.

 

Takeaway #3
DPDK는 빠르고, userspace라서 upgrade도 쉽고 개발도 쉽다. 하지만 유저들이 일반적으로 원하는 도구와 시스템을 사용할 수 없게된다.

 

2.2.2 Decoupling the Kernel With eBPF

 Kernel module을 eBPF로 대체하여 user/kernel division을 유지하는 방법이 있다. eBPF는 kernel의 source code 수정이나 별다른 kernel module load없이 in-kernel sandbox 내에서 프로그램을 안전하게 돌릴 수 있는 환경을 제공한다. 또한 많은 Linux distribution에서 third-party eBPF program을 지원하려고 노력하고있다. eBPF-based OVS는 유지보수와 운영 문제를 해결할 수 있으리라고 생각했다.

 하지만, eBPF는 한계가 존재한다. sandbox는 제한된 크기의 eBPF program을 돌릴 수 있다. 여러 eBPF program을 chaining하여 접근할 수도 있겠지만 여전히 부족하다. 또한, sandbox는 안전한 eBPF program을 위하여 loop를 금지한다. 이 제약은 eBPF datapath의 몇몇 기능들을 구현할 수 없도록 방해하였다. 예를 들어, megaflow cache는 loop를 돌 수 없어서 구현할 수 없게되었다. (물론 map 자료구조를 사용하면 될 수도 있으나, kernel maintainer들에게 거부당했다.)

 

 성능또한 중요하다. bytecode로 구현된 eBPF code는 C에비해서 느리게 동작했다. Figure 2는 3개의 datapath 구현체를 비교한 것이다. 64-byte single UDP flow를 사용했기때문에 megaflow의 여부는 영향을 주지 않는다. 불행하게도 sandbox overhead는 eBPF packet switching을 기존 (OVS kernel module)대비 10~20% 느린 결과를 초래하게 되었다.

Takeaway #4
eBPF는 유지보수 문제를 해결할 수 있겠으나 packet switching 성능이 매우 느리다.

 

 

2.2.3 Mostly Userspace OVS with AF_XDP

XDP는 "hook point"를 각 NIC의 device driver에 심어놓고 userspace program이 자유롭게 eBPF program을 설치할 수 있도록 제공한다. 이를 기반으로 AF_XDP가 존재하고 있으며, AF_XDP는 Linux 4.18 이상부터 지원한다. NIC driver는 packet을 수신할 때마다 (kernel socket buffer에 위치시키기도 전에!) XDP program을 실행한다. 

 

 

 AF_XDP는 XDP hook program로 하여금 userspace로 packet을 바로 보낼 수 있도록 기능을 제공한다. 이 때 Linux kernel networking stack을 건너뛸 수 있다. OVS가 AF_XDP를 사용하기 위해서는 XDP hook program을 설치하여 모든 packet을 OVS userspace로 보내도록 하면 될 것이다. (Figure 3 참조)

 

 OVS with AF_XDP는 OVS와 kernel을 기존과는 훨씬 적은 eBPF help program 수준의 coupling을 발생시킨다. 이 helper program은 OVS community가 관리하며, 단순히 packet을 userspace로 보내는 역할만을 수행한다. 그리고 XDP와 AF_XDP는 linux kernel community에 의해 accept된 feature이며, 꾸준히 관리될 것이다. 

 

 OVS DPDK를 이용하고 AF_XDP poll mode driver를 사용하는 방법도 가능하다. 사실 이게 첫 구현이었다. 하지만, 성능이 중요하지 않은 사용자에게 높은 CPU 사용량은 부담이 되었고, OVS community 또한 DPDK의 버전 발전에 따라서 계속 유지를 해야하는 데 부담이 있다.

 

 Figure 3은 (OVS with Kernel module, OVS in eBPF), (OVS with DPDK), (OVS with AF_XDP)를 각각 나타낸다. 

반응형
Comments