Hacker News

Making Tailscale Faster

Tailscale를 더 빠르게 만들기

Tailscale가 Linux·Android의 패킷 복사와 메모리 사용을 줄이고, 서브넷 라우터와 앱 커넥터에 멀티큐 처리를 도입합니다. 제어 플레인 연결이 늦을 때 저장된 네트워크 맵으로 먼저 연결하는 기능도 소개합니다.

AI 요약

Tailscale는 NAT Traversal을 넘어 데이터 플레인의 처리량과 지연 시간도 개선하고 있습니다. 이번 글에서는 Linux·Android 클라이언트의 메모리와 패킷 처리 최적화, 서브넷 라우터와 앱 커넥터의 멀티큐 처리, 시작 시간을 줄이는 네트워크 맵 캐싱을 설명합니다. 성능 측정과 진단을 위한 Tailscale 전용 도구도 개발 과제로 제시합니다.

패킷 복사와 대기열 줄이기

Linux의 Generic Receive Offload(GRO) 같은 처리 방식은 한 번에 최대 64KiB 트래픽을 받습니다. 하지만 실제 패킷은 1KiB 안팎인 경우가 많습니다. 기존 wireguard-go 경로에서는 큰 버퍼에 읽어 들인 뒤 패킷마다 별도의 64KiB 버퍼로 복사했습니다. Tailscale는 Linux와 Android에서 패킷을 새 버퍼로 옮기지 않고, 큰 읽기 영역 안에서 패킷의 시작과 끝을 찾아 처리하도록 바꿨습니다. 작은 패킷은 메모리에서도 작은 크기로 유지하고 여러 패킷이 한 번의 메모리 할당을 공유합니다. 회사 측 측정에서는 여러 네트워크 구성에서 이 변경만으로 약 5% 속도가 향상됐습니다.

패킷 처리 단계 사이에 둔 대기열도 줄였습니다. 대기열은 순간적으로 트래픽이 몰릴 때 이를 흡수하지만, 테스트에서는 기존 대기열 깊이 대부분이 사용되지 않았습니다. 짧은 대기열은 패킷이 기다리는 시간을 줄이고 메모리 사용량도 낮춥니다. 또 Linux의 writev 기능을 활용해 패킷 데이터의 여러 조각을 한 번의 작업으로 커널에 전달합니다. 조각을 미리 복사해 합치거나 쓰기 작업을 반복할 필요가 줄어 처리량 개선에 보탬이 됩니다.

서브넷 라우터와 앱 커넥터에 멀티큐 적용

기존에는 서브넷 라우터, 앱 커넥터, 출구 노드가 여러 독립적인 연결의 패킷을 순서가 있는 단일 처리 경로에서 다뤘습니다. 한 연결의 패킷이 순서를 바꿔 도착하지 않도록 여러 연결이 한 줄을 공유하는 구조였습니다. 메모리 사용량을 줄인 뒤에는 여러 처리 경로를 병렬로 운영하는 멀티큐 시스템을 구현할 여지가 생겼습니다. 패킷 흐름마다 처리 경로를 배정하고, 경로 수는 피어 수가 아니라 장비의 자원에 맞춥니다. 각 경로가 CPU 코어에서 병렬로 실행되므로 집계 처리량을 높이고 패킷을 받은 뒤 전달하기까지의 지연을 줄이는 것이 목표입니다. 단시간 연결이 많은 사용자에게 서비스하는 앱 커넥터와 출구 노드에서 효과가 특히 두드러질 것으로 설명합니다.

캐시된 네트워크 맵으로 빠른 시작

Tailscale 클라이언트는 시작할 때 제어 플레인에 연결해 인증하고, 통신 가능한 장치와 연결 방법을 담은 네트워크 맵(netmap)을 받습니다. 일반적인 네트워크에서는 이 과정이 약 100밀리초 걸리지만, 비행기나 호텔의 불안정한 Wi-Fi처럼 제어 플레인에 닿기 어려운 환경에서는 더 오래 걸리거나 연결이 실패할 수 있습니다. 네트워크 맵 캐싱을 켜면 장치가 맵을 디스크에 저장합니다. 다음 시작 때는 캐시로 다른 장치와 연결을 시도하면서 제어 플레인에서 최신 정보를 받을 때까지 기다릴 수 있습니다. 장치끼리 직접 협상하는 연결이며, 기존처럼 Tailscale가 데이터 트래픽을 보지는 않습니다.

이 기능은 해당 tailnet에 한 번 이상 연결해 네트워크 맵을 받은 장치에서만 작동하며, 캐시를 저장할 디스크 공간이 필요합니다. 규모가 매우 큰 tailnet에서는 갱신 때 디스크 쓰기가 많아질 수 있고, SD 카드처럼 느리거나 쓰기 내구성이 민감한 저장 장치에서는 적합하지 않을 수 있습니다. 회사 측은 제어 플레인 연결이 좋지 않은 tailnet에서 캐시가 준비된 시작과 최초 시작을 비교했을 때 데이터 플레인 송신이 10~100배 빨라진 사례를 확인했다고 밝혔습니다.

적용 일정과 성능 도구

버퍼 변경에 따른 메모리 절감은 v1.104 클라이언트에 포함할 예정입니다. 서브넷 라우터와 앱 커넥터용 멀티큐는 v1.104 이후 버전을 계획하고 있습니다. Linux·Android 처리량 개선 일부는 2026년 봄에 구현됐으며, 추가 개선도 v1.104 이후 배포할 예정입니다. 네트워크 맵 캐싱은 현재 기능 플래그로 쓸 수 있고, 추가 테스트를 거쳐 v1.104에서 기본 활성화할 계획입니다. 모바일 클라이언트 적용은 그 이후 버전으로 예정돼 있습니다.

Tailscale는 기존 성능 도구가 각 끝점에 별도 설치를 요구하고, 테스트 절차가 경직돼 있으며, QUIC·HTTP/3 지원과 Tailscale 연결 경로에 대한 이해가 부족하다고 지적합니다. 새 도구는 연결이 DERP를 거치는지 직접 연결인지, 피어 릴레이가 도움이 되는지, 경로가 시간에 따라 어떻게 바뀌는지를 파악하는 방향을 검토하고 있습니다.

Hacker News 반응

  • @CharlesW — 글에서 Linux와 Android에 집중한 이유가 작업을 그곳에서 먼저 시작했기 때문인지, 아니면 그 운영체제에서만 가능한 기술을 쓰기 때문인지 궁금합니다.
    • @chrash — Darwin과 Windows에는 똑같은 방식으로 존재하지 않을 수 있는 Linux 기능을 활용하는 것으로 보입니다.
    • @apenwarr — 대부분 그렇습니다. 패킷 수준 최적화는 플랫폼에 따라 달라질 수밖에 없고, 이 글도 주로 Linux 데이터 플레인을 다룹니다. 다만 멀티큐 아키텍처와 메모리 최적화는 다른 플랫폼에서 발전시키기에도 유용합니다.
  • @ykurtov — 저희 사용 사례에서는 터널을 통해 60Mb/s만 전송하는데도 세션이 250개가 되자 지연 시간이 급격히 치솟았습니다.
  • @aborsy — 출구 노드의 배터리 사용량을 줄였으면 좋겠습니다.
    • @nirav72 — 배터리로 작동하는 장치를 출구 노드로 쓰고 계신가요?
  • @fitblipper — 예전에는 Tailscale를 정말 좋아했습니다. 그러다 집 네트워크에 WireGuard를 설치하고 동적 DNS를 붙여 인터넷에 공개하자 Tailscale가 필요 없어졌습니다. 순수 WireGuard가 더 안정적이고, 휴대전화에서 DNS 문제를 해결하느라 씨름할 필요도 없으며, 더 빠르고 설정도 놀랄 만큼 간단합니다.
    • @PorciiVorbesc — 설정을 공유해 주실 수 있나요? NUC와 Raspberry Pi에서 WireGuard를 직접 운영하는 방법을 알아봤지만, 인증서나 유지보수를 신경 쓰지 않고 장치를 쉽게 추가·삭제할 수 있어 Tailscale를 골랐습니다.
    • @fitblipper — WireGuard 서버를 돌리는 OpenWrt 라우터를 씁니다. 피어 키와 경로를 관리하고, OpenWrt의 Cloudflare DDNS도 설정했습니다. 새 클라이언트는 GUI의 WireGuard 화면에서 피어를 추가하면 됩니다.
    • @tristanj — Tailscale는 2분이면 설정하고 장치를 구성 없이 추가할 수 있습니다. WireGuard는 포트 포워딩과 DDNS를 설정하고 장치마다 키를 만들고 등록해야 하므로 30분에서 한 시간쯤 걸립니다. 대신 완전히 제어할 수 있습니다. 성능 차이는 느끼지 못했고, 제 인터넷 연결이 Tailscale의 성능 한계에 먼저 도달합니다. 편의성에서는 Tailscale가 낫습니다.
    • @kccqzy — 순수 WireGuard 설정이 놀랄 만큼 간단하다고 생각한다면 솔직하지 못한 겁니다. IPsec보다는 간단하지만 Tailscale보다 간단하지는 않습니다. 몇 달 손대지 않으면 설정 세부 사항을 잊어버려 순수 WireGuard에서 Tailscale로 옮겼습니다.
  • @iscoelho — 제 생각에 Tailscale의 가장 큰 문제는 속도입니다. 일반적으로 쓰이는 Windows와 Mac 클라이언트는 1Gbps를 넘기기 어렵고, Linux도 큰 패킷을 쓰는 인공 벤치마크에서 10Gbps를 내기 어렵습니다. IMIX 벤치마크라면 경쟁력이 없을 겁니다. WireGuard 커널 구현이나 DPDK·XDP 기반 IPsec은 더 높은 성능을 냅니다. 이 글을 보면 Tailscale는 그런 개선에 나설 의지가 없어 보입니다.
    • @apenwarr — 커널 WireGuard가 더 빠르게 만든다는 의견이 몇 개 보입니다. 실제로는 그렇게 단순하지 않습니다. 한동안 Tailscale의 최적화 덕분에 wireguard-go가 커널 WireGuard보다 빨랐고, 커널 쪽도 그 개선을 반영했습니다. 아주 높은 대역폭에는 DPDK 같은 기술이 장기적으로 적합하며, 그 방식도 주로 사용자 공간에서 작동합니다. WireGuard의 암호 방식은 하드웨어 가속기가 지원하지 않는 문제가 있습니다. 수백 기가비트급으로 가려면 패킷 형식을 바꿔야 할 수도 있습니다.
    • @lokar — 커널 네트워킹이 자동으로 사용자 공간보다 빠른 것은 아닙니다.
    • @iscoelho — 맞습니다. 다만 커널 WireGuard는 사용자 공간 구현보다 높은 성능을 내고, 사용자 공간 네트워크 스택에는 문맥 전환과 메모리 복사에 따른 성능 한계가 있습니다.
    • @TZubiri — Linux에서 사용자 공간 WireGuard를 그만 쓰라는 조언을 따랐다면 Tailscale 인스턴스가 copy.fail 취약점으로 공격당했을 거라는 점도 기억해야 합니다.
  • @apenwarr — 커널 WireGuard를 쓰면 빨라진다는 말은 단순하지 않습니다. Tailscale의 최적화가 한동안 커널 구현보다 wireguard-go를 빠르게 만들었습니다. 이제 양쪽이 다음 성능 단계로 나아가고 있습니다. 수백 기가비트 처리에는 DPDK 같은 사용자 공간 기술이 장기적으로 적합할 수 있습니다. 또 WireGuard 암호 방식은 하드웨어 가속을 지원하지 않아, 그 수준에 도달하려면 패킷 형식 변경이 필요할 수도 있습니다.
    • @wahern — 양자내성(PQ) 지원을 더하면 WireGuard는 더 이상 WireGuard가 아닐 겁니다. 간단한 핸드셰이크와 적은 상태가 장점이었는데, PQ 알고리즘은 키가 너무 크거나 다루기 복잡합니다. 차라리 IPsec으로 바꾸는 편이 낫습니다.
    • @apenwarr — 조금 더 낙관적입니다. WireGuard도 언젠가는 v2가 필요합니다. 실시간 협상을 피하고 각 노드가 사용할 방식만 미리 정한다면 IPsec보다 계속 단순하게 유지할 수 있습니다. Google의 PSP처럼 하드웨어 가속도 가능한 방식이 있습니다. 양자내성 협상은 까다롭겠지만 다른 장점을 모두 포기할 필요는 없습니다.
    • @Fordec — WireGuard가 Tailscale의 중요한 기반이라면, 오픈소스 쪽 v2 개발에 자금을 지원하고 있나요? 보안 환경이 바뀌는데 아무것도 하지 않는다면 자체 양자내성 프로토콜을 만드는 건가요?
    • @apenwarr — 아직 발표할 내용은 없습니다. WireGuard에 자금과 코드로 지원하고 있습니다.

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