Lambda ثبت flow را با eBPF و Rust بازنویسی کرد؛ iptables در تراکم microVM کم آورد

/images/aws-lambda-ebpf-rust-flow-logging.png

یک worker لامبدا یک EC2 برهنه است پر از هزاران microVM فایرکرکر. هر کدام چند صد میلی‌ثانیه زنده می‌مانند، با S3 و VPC و اینترنت حرف می‌زنند، و تنها شاهد ترافیک همان چند میلی‌ثانیه لاگ است. ۱۱ سپتامبر ۲۰۲۶ پراشانت کومار سینگ، کشیتج گوپتا و شیوندرا سریواستاوا در The New Stack نوشتند چرا سیستم قدیمی ثبت flow در این تراکم شکست خورد و چه چیزی جایش نشست.

طرح قرضی از دوران EC2 تک‌مستأجر دو تکه بود: افزونه کرنل که بسته را می‌شمرد و به tenant وصل می‌کرد، و daemon فضای کاربر که شمارنده‌ها را به رکورد Amazon Ion تبدیل می‌کرد. روی چند VM کار می‌کرد. روی چند هزار microVM دو جور تمام شد.

اول، انفجار قانون. iptables تقریباً خطی روی زنجیره راه می‌رود. یک host با حدود دو هزار microVM بیش از صد هزار قانون لازم داشت فقط برای دفترداری. هر بسته مالیاتی متناسب با شلوغی host می‌پرداخت — درست خلاف هدف تراکم. دوم، ماژول قرضی IPv6 نمی‌فهمید. وقتی dual-stack برای Lambda مطرح شد، همان معماری تمام شده بود؛ دفتری که نصف فضای آدرس را نمی‌بیند قابل‌اعتماد نیست.

سه قطعه، یک قرارداد با گذشته

جایگزین را طوری ساختند که مصرف‌کننده‌های billing و flow-log هیچ فرقی نبینند: خروجی باید byte-compatible با Ion قدیمی باشد. معماری جدید سه نقش دارد.

پایین: برنامه‌های کوچک eBPF روی هوک TC (clsact) در ingress و egress هر دستگاه مجازی شبکه. هر شبکه دو دستگاه دارد؛ یعنی چهار نقطه اتصال. برنامه‌ها فقط نگاه می‌کنند. مسیر کپی، drop یا بازنویسی بسته در کار نیست. برای هر بسته یک event فشرده (حدود ۲۴ بایت برای IPv4) در ring buffer همان شبکه می‌نویسند؛ aggregation کار کرنل نیست.

وسط: tagger، یک پروسه Rust بدون امتیاز per-network. ring خودش را خالی می‌کند، eventها را به flow جمع می‌کند، Ion می‌نویسد. هر tagger چند صد کیلوبایت RAM می‌گیرد، بودجه حدود یک مگابایت؛ همین هزاران پروسه روی host را ممکن می‌کند. GC نمی‌خواستند: pause یعنی حفره در دفتر.

بالا: orchestrator، یک پروسه با امتیاز per-host. eBPF را load می‌کند، TC را سیم می‌کشد، taggerها را می‌سازد. API چرخه عمر روی Unix socket با gRPC است. Create سنگین است (قفل کرنل روی attach). Activate سبک است: متادیتای مشتری را می‌دهد و ضبط را روشن می‌کند. بودجه تأخیر Activate: p90 زیر ۲ms و p99.9 زیر ۱۰ms — هم‌تراز سیستم قبلی.

امتیاز را با یک حقه قدیمی یونیکس جدا کردند. tagger حق باز کردن map را ندارد. orchestrator descriptor را با SCM_RIGHTS روی سوکت می‌فرستد. سطح privileged کل سیستم یک پروسه کوچک per-host است.

کف اندازه ring از نرخ بسته guest ضرب‌در فاصله drain حدود ۱۰۰ms به‌دست آمده؛ API توان دو می‌خواهد، پس پیش‌فرض طراحی ۵۱۲ KiB. در production فعلاً سخاوتمندانه‌تر، حدود چند مگابایت، تا tuning تمام شود. برنامه‌های eBPF علاوه بر verifier، هر بیلد از CBMC رد می‌شوند.

چیزی که از این کار ماند: هزینه per-packet دیگر با شلوغی host بالا نمی‌رود، IPv6 مثل IPv4 ثبت می‌شود، و downstream بدون تغییر ماند. برای هر پلتفرم متراکم multi-tenant — حتی خارج از Lambda — درس همان است: ضبط را از مسیر داغ جدا کنید، بافر را از حد واقعی سیستم بسازید، و tenant را از لحظه capture از هم جدا نگه دارید.

آخرین مطالب