پروتکل XDP: یک قدم قبل از کرنل
تا به حال به این فکر کردهاید که غولهای فناوری مانند کلادفلرCloudflare چگونه حملات گستردهٔ DDoS را در نطفه خفه میکنند یا شرکتهایی مانند گوگل و متا چطور میلیاردها درخواست کاربر را بدون لحظهای وقفه مدیریت میکنند؟ پاسخ، اغلب در اعماق کرنل لینوکس (منظور از کرنل لینوکس، کرنل گنو/لینوکس است) و در دل فناوری قدرتمندی به نام مسیر دادهٔ سریعeXpress Data Path (XDP) نهفته است. XDP یک پروتکل مهم در دنیای شبکههای مدرن است که با عملکرد فوقالعاده بالا، به برنامهها اجازه میدهد بستههای شبکه را در اولین نقطهٔ ممکن، یعنی درست در درایور کارت شبکه، مدیریت کنند. این یعنی دستیابی به سرعتی نزدیک به سختافزار، بدون نیاز به دور زدن کامل کرنل.
XDP با استفاده از eBPF، به توسعهدهندگان این قدرت را میدهد که منطق سفارشی خود را برای مقابله با حملات، متعادلسازی بارLoad Balancing و فایروال، با کمترین سربار ممکن پیادهسازی کنند. در این نوشته ابتدا میبینیم که مشکل استک شبکهٔ سنتی لینوکس چیست، سپس تا حدودی با معماری هوشمندانهٔ XDP آشنا میشویم و در نهایت، نگاهی به کاربرد واقعی آن در پروژهای مانند Cilium میاندازیم که از XDP برای ساخت نسل جدیدی از متعادلکنندههای بار خود استفاده میکند.
مشکل کجاست؟
برای درک ارزش XDP، ابتدا باید با مسیر یک بسته در استک شبکهٔ سنتی لینوکس آشنا شویم. وقتی یک بسته به
اینترفیس کارت شبکهNetwork Interface Card (NIC)
میرسد، کرنل برای مدیریت آن یک دادهساختار به نام sk_buff
(بافر سوکت) ایجاد میکند. این ساختار، مثل یک کولهپشتی، اطلاعات زیادی را در خود جای میدهد و همین اطلاعات زیاد، باعث سنگین و پرهزینه شدن آن شدهاست.
در حجم ترافیک بالا، مثلاً در مقیاس میلیونها بسته در ثانیه، فرآیند تخصیص و مدیریت حافظه برای این «کولهپشتیها» به یک گلوگاهbottleneck جدی تبدیل میشود و عملکرد درست را مختل میکند.
یک راهحل رادیکال
نقطهٔ قوت XDP دقیقاً همینجاست. این پروتکل، یک
قلابHook
استراتژیک در درایور کارت شبکه، یعنی قبل از آنکه کرنل بخواهد ساختار پرهزینهٔ sk_buff
را ایجاد کند، قرار میدهد. عملکرد XDP صرفاً سرعت بالاتر نیست، بلکه برای حذف کارهای غیرضروری است.
برای هر بستهای که یک برنامهٔ XDP تصمیم به رها کردنDrop یا هدایت مجددRedirect آن میگیرد، کرنل از تمام هزینهٔ مربوط به ایجاد و مدیریت یک بافر سوکت خلاص میشود. به همین دلیل است که XDP میتواند دهها میلیون بسته در ثانیه را روی یک کرنل پردازنده مدیریت کند.
این یک جهش عملکردی عظیم در مقایسه با فیلتر کردن بستهها در لایههای بالاتر مانند iptables
است؛ بهویژه در سناریوهایی مانند حملات DDoS که سرنوشت اکثر بستهها، دور ریختهشدن است.
از آزمایش تا نهایت سرعت
یک برنامهٔ XDP میتواند در سه حالت مختلف اجرا شود که هر کدام تعادلی بین عملکرد و سازگاری با سختافزار ارائه میدهند:
- XDP بومیNative XDP: سریعترین حالت که در آن برنامه مستقیماً در درایور کارت شبکه بارگذاری میشود و نیازمند پشتیبانی درایور است.
- XDP عمومیGeneric XDP: یک حالت نرمافزاری جایگزین که روی هر سختافزاری کار میکند. این حالت برای توسعه و آزمایش ایدهآل است، زیرا به توسعهدهندگان اجازه میدهد منطق خود را حتی روی لپتاپشان بنویسند و بعداً روی سرورهای قدرتمند مستقر کنند.
- XDP تخلیهشدهOffloaded XDP: نهایت عملکرد، جایی که برنامهٔ eBPF مستقیماً روی سختافزار کارت شبکه اجرا میشود و بستهها را بدون درگیر کردن پردازندهٔ اصلی پردازش میکند. این حالت نیازمند کارتهای شبکهٔ تخصصی است.
چگونه کار میکند؟
در عمل، برنامههای XDP کدهایی هستند که با زیرمجموعهای از زبان C نوشته شده و به بایتکد eBPF کامپایل میشوند. این کدها در یک محیط ایزوله و امن در کرنل به نام ماشین مجازی eBPF اجرا میشوند.
تا اینجا چندین بار به اینکه XDP از eBPF استفاده میکند اشاره شد و سؤال اینجاست که eBPF چیست؟
eBPF: مغز متفکر عملیات
eBPF یک تکنولوژی قدرتمند در لینوکس است که اجازه میدهد برنامههای کوچکی را داخل کرنل اجرا کنیم، بدون نیاز به اینکه کدهای کرنل را تغییر بدهیم. قبل از بارگذاری هر برنامه، تأییدکنندهVerifier کد را به دقت بررسی و تست میکند تا مطمئن شود که کد نوشتهشده، هیچ کار خطرناکی مانند حلقههای بینهایت یا دسترسی غیرمجاز به حافظه انجام نمیدهد.
این سازوکار ایمنی، انقلابی در برنامهنویسی کرنل است؛ زیرا به ما اجازه میدهد بدون خطر نوشتن ماژولهای پیچیده، کدهای سفارشی را در قلب سیستمعامل و کرنل اجرا کنیم.
دنیای کاربردهای eBPF بسیار گسترده است و هر روز هم وسعت بیشتری پیدا میکند. پس بیایید چند مورد از کاربردهای مهم eBPF بهجز پروتکل XDP را بررسی کنیم:
مشاهده و ردیابی
با eBPF میتوانیم نقاط حساس کرنل و یوزر اسپیس را بیدرنگ اندازهگیری و دنبال کنیم: تأخیر سیستمی، فراخوانی توابع، مقدار I/O، تعداد پردازهها و غیره.
با استفاده از ابزارهایی مثل bpftrace
(ابزاری برای اسکریپتهای tracing با eBPF) دادهها را جمعآوری میکنیم و امکان ساخت
متریکهاmetrics
و پارامترهای دقیق دیگری را میدهد، بدون اینکه برنامه را متوقف کنیم عملکرد را بهطور قابلتوجهی خراب کنیم. همچنین خروجیها را میتوان به ابزارهای مانیتورینگ و tracing مثل Prometheus فرستاد تا تحلیل و ارتباط بین سرویسها امکانپذیر شود.
مدیریت و کنترل منابع
با استفاده از eBPF میتوان مصرف CPU، حافظه، I/O و شبکه را دقیقتر از قبل اندازهگیری و کنترل کرد. مثلاً برای اجرای سیاستهای کیفیت سرویس (QoS)Quality of Service (QoS) یا تضمین اهداف سطح سرویس (SLO)Service Level Objective (SLO) میتوانیم ترافیک یا کارهای یک گروه پردازه را اولویتبندی و محدود کنیم. ترکیب eBPF با cgroups و کنترلرهای دیگر به شما اجازه میدهد رفتار زمانبندی و مصرف منابع را بر اساس قواعد پویا تغییر بدهید.
بالانسرها و مسیریابی هوشمند
با eBPF این امکان را داریم که ترافیک شبکه را بر اساس اطلاعات سطح اپلیکیشن یا متریکهای runtime هدایت کنیم؛ این یعنی لودبالانسرهای هوشمند و مسیریابی آگاه از سرویس که از وضعیت واقعی هر نود آگاه هستند و تصمیمات بهینهتری میگیرند.
پروژهٔ متنباز Cilium، قدرتگرفته از XDP
Cilium یک پروژهٔ شبکهٔ ابری پیشرو برای Kubernetes است که از eBPF برای شبکه، امنیت و مشاهدهپذیری استفاده میکند. Cilium بهطور هوشمندانه از XDP برای شتابدهی ترافیک ورودی و خروجی از کلاستر (ترافیک شمال-جنوب) در متعادلکنندهٔ بارLoad Balancing / Service-aware Routing خود بهره میبرد.
این معماری به Cilium اجازه میدهد تا قابلیتهایی مانند بازگشت مستقیم سرورDynamic Source Routing (DSR) را پیادهسازی کند. در این حالت، سرور پشتیبان پاسخ را مستقیماً برای کاربر ارسال میکند و متعادلکننده، بار را در مسیر بازگشت دور میزند که باعث کاهش تأخیر و حفظ آدرس IP اصلی کاربر میشود.
داستان موفقیت Seznam.cz
شرکت فناوری Seznam، یکی از شرکتهای بزرگ جمهوری چک، متعادلکنندهٔ بار قدیمی خود (مبتنی بر IPVS) را با راهحل L4LB مستقل Cilium که از XDP استفاده میکند، جایگزین کرد.
راهحل قبلی آنها در ترافیک سنگین (تا ۲۰ میلیون اتصال همزمان) هستههای پردازنده را به مرز ظرفیت خود میرساند. در نتیجه تصمیم گرفتند به Cilium مهاجرت کنند.
آنها شاهد کاهش ۷۲ برابری در مصرف پردازنده بودند! مصرف پردازنده از ۳۶ هستهٔ کامل به تنها نصف یک هسته کاهش یافت، در حالیکه همان حجم ترافیک را مدیریت میکردند.
آیندهای که میتواند بسازد
XDP فقط یک ابزار بهینهسازی نیست؛ بلکه یک بلوک ساختمانی بنیادی برای نسل بعدی زیرساختهای شبکه است. با ترکیب عملکرد خام سختافزار و انعطافپذیری نرمافزار، XDP به توسعهدهندگان اجازه میدهد راهحلهای نوآورانهای برای چالشهای بزرگ دنیای شبکه، از امنیت و متعادلسازی بار گرفته تا مشاهدهپذیری، خلق کنند.
این فناوری که در سکوت، در قلب لینوکس کار میکند، بدون شک سنگبنای بسیاری از زیرساختهای نرمافزارمحور در آینده خواهد بود.
باید در نظر داشته باشیم همچنان اکثر شرکتهای بزرگ و کوچک از این تکنولوژی استفاده نمیکنند و در آینده احتمالاً زیاد قرار است اسم XDP را بشنویم!
در واقع XDP هنوز در مراحل پذیرش اولیه قرار دارد و خیلی از شرکتها تازه سراغ آن رفتهاند، ولی روند استفاده از آن رو به رشد است.
با بیشتر شدن پشتیبانی ابزارها و تجربهٔ جامعهٔ کاربری، این پروتکل میتواند به یکی از اجزای عادی و جدی زیرساختهای شبکه در سالهای آینده تبدیل شود.