Lobsters

The history of the Hetzner Cloud network stack

Hetzner Cloud 네트워크 스택의 역사

Hetzner가 클라우드 네트워크를 구축해 온 과정을 소개하고, 현재 Open vSwitch 기반 스택의 구성과 패킷 처리 방식을 설명합니다. 100만 대가 넘는 클라우드 서버를 지원하는 구조와 확장성 한계를 짚으며, 다음 편에서 자체 개발한 새 스택을 다루겠다고 예고합니다.

AI 요약

Hetzner는 물리 네트워크를 단순한 호스트 연결에 집중시키고, 방화벽·사설 네트워크 같은 기능은 가상머신 호스트에서 처리하는 방향으로 클라우드 네트워크를 발전시켰습니다. 이 글은 초기 vServer부터 현재 Open vSwitch(OVS) 기반 데이터 플레인까지의 변화를 살펴보고, 호스트에서 패킷을 전달하고 부가 서비스를 제공하는 방식을 설명합니다. 클라우드 서버와 로드 밸런서의 네트워크 구조는 비슷하지만, 여기서는 더 많은 기능을 제공하는 가상머신 호스트를 중심으로 다룹니다.

제품 성장에 맞춘 네트워크 변화

2011년 시작한 Hetzner vServer는 HDD, Linux 브리지, 정적 라우팅을 사용했습니다. 호스트당 최대 1Gb/s를 제공했고, 이 구성으로 약 2만 5,000개 인스턴스를 운영했습니다. 2015년 9월 출시한 후속 제품은 Ceph 기반 하이퍼컨버지드 구성으로 전환했습니다. BGP 동적 라우팅과 Linux 브리지를 적용하고, IPv4에는 1:1 NAT를, IPv6에는 완전한 라우팅 프리픽스를 사용했습니다. 덕분에 IP 이동성이 개선됐고, 고객 영향 없이 호스트를 점검할 수 있었습니다. 2016년에는 호스트 연결 대역폭을 2×10Gb/s로 높였으며, 이 구성은 2018년까지 약 5만 개 인스턴스를 지원했습니다.

2018년 Hetzner Cloud를 출시하면서 NAT를 없애고 IPv4 직접 라우팅으로 바꿨습니다. 2019년 7월 OVS 데이터 플레인을 도입했고, VXLAN 기반 사설 클라우드 네트워크를 추가했습니다. 2020년 11월부터 공용 네트워크도 OVS로 옮겼으며, 2021년 3월 OVS 플로우와 netfilter를 이용한 상태 저장 클라우드 방화벽을 출시했습니다.

호스트에서 제공하는 네트워크 기능

각 서버는 공용 네트워크 인터페이스 하나와 사설 인터페이스 최대 세 개를 사용할 수 있습니다. 사설 네트워크는 VXLAN으로 트래픽을 캡슐화하고, 네트워크마다 고유한 VNI(Virtual Network Identifier)를 부여합니다. 호스트 네트워크 스택은 해당 네트워크에 연결된 서버만 트래픽을 주고받도록 제한합니다.

서버 이미지 대부분은 IPv4 주소와 라우트를 DHCP로 설정합니다. 클라우드 초기 설정에 쓰이는 cloud-init은 IPv6 설정, 사설 인터페이스의 DHCP 요청, 볼륨 연결 등을 처리하며, 로컬 시스템이나 사용자 설정을 메타데이터 서버(169.254.169.254)에서 가져옵니다. CSI 드라이버, hc-utils, Flatcar Linux의 Afterburn과 Ignition, Talos Linux 같은 도구도 메타데이터 서버를 이용합니다. DHCP와 메타데이터 서버는 가용성을 높이기 위해 각 VM 호스트에서 실행합니다.

Hetzner는 방화벽 기능도 서버에 가까운 호스트에서 처리합니다. 중앙 집중식 상태 저장 방화벽을 두면 추가 하드웨어와 네트워크 오버레이가 필요하고, 연결 추적을 고가용성으로 운영하는 복잡성도 커지기 때문입니다.

OVS와 Flusskrebs

OVS는 리눅스 커널에 데이터 경로가 포함된 오픈소스 멀티레이어 가상 스위치입니다. Hetzner는 OpenFlow를 사용해 패킷의 전달 방식을 지정합니다. 통신 방향마다 플로우를 설정하며, ARP·NDP·ICMP 같은 게이트웨이 통신부터 사설 네트워크 구성원 간 트래픽, 인터넷 연결까지 처리합니다.

OVS를 관리하는 일반적인 선택지로는 OVN(Open Virtual Network)이 있지만, Hetzner는 자체 도구 Flusskrebs를 개발했습니다. Python으로 작성한 Flusskrebs는 REST API를 제공하고, 클라우드 제어 평면의 호스트 로컬 구성 요소가 이를 호출합니다. 서버와 로드 밸런서에 필요한 플로우를 설치하고, 사용자가 설정한 방화벽 규칙이나 기본 SMTP 송신 차단 같은 백엔드 규칙도 반영합니다. 사설 인터페이스용 DHCP 서버 역할도 맡습니다.

대부분의 호스트는 두 개의 10Gb/s 업링크를 LACP 링크 집성으로 묶어 두 물리 스위치에 연결합니다. Hetzner는 복원력을 높이기 위해 독립된 스위치 두 대에 BGP로 직접 라우팅하는 업링크로 이전하고 있습니다. 업링크와 OVS 브리지를 직접 연결하지 않고 Linux 시스템이 둘 사이를 라우팅합니다. 따라서 OVS 상태와 호스트 자체의 연결 가능성을 분리하고, 호스트 설치와 유지보수도 쉽게 합니다.

서버에서 나가는 패킷은 먼저 포트와 출발지 MAC 주소가 맞는지 확인합니다. 이어 IPv4·IPv6 주소나 ARP 정보가 서버에 할당된 값인지 검사한 뒤 전달합니다. 외부에서 들어오는 패킷은 목적지 IP에 맞는 서버 포트로 보내며, 서버에는 미리 정한 가상 게이트웨이 MAC 주소를 사용합니다. 공용 DHCP 서비스도 각 서버 전용 Linux 네트워크 네임스페이스 안에서 실행하고, OVS 플로우로 DHCP 요청과 응답을 연결합니다.

상태 저장 방화벽에는 Linux netfilter 연결 추적을 씁니다. 연결 추적 테이블을 여러 서버가 공유하므로, Hetzner는 내부 도구 ctcount로 항목 수를 관리합니다. 서버 한 대당 동시 활성 연결은 최대 8만 개이며, 한도에 도달하면 기존 연결이 닫힐 때까지 새 연결을 열지 못합니다.

현재 구성과 다음 단계

OVS 데이터 플레인은 클라우드 서버가 100만 대를 넘은 뒤에도 운영됐지만, Hetzner는 확장성·복원력·유연성 측면에서 한계에 도달했다고 설명합니다. 이에 맞춰 운영하기 쉽고 자체 요구에 특화된 새 네트워크 스택을 개발해 왔으며, 사설 네트워크에서 IPv6를 지원하는 기능도 다음 단계의 사례로 들었습니다. 새 스택의 설계와 동작은 시리즈 후속 편에서 다룰 예정입니다.

Lobsters 반응

  • @Lt_Riza_Hawkeye — 자바스크립트를 끄면 페이지에 아무것도 표시되지 않습니다 :(
    • @donio — 내용은 HTML에 들어 있습니다. Emacs의 eww처럼 단순한 비자바스크립트 브라우저에서는 표시됩니다. 일반 브라우저에서는 왜 눈에 보이게 렌더링되지 않는지 잘 모르겠습니다.
    • @hwj — uBlock Origin으로 자바스크립트를 끈 상태에서도 같은 현상을 확인했습니다.

원문: Hetzner / 번역·요약: Trawling