في عالم تطوير التطبيقات الحديثة الذي يتطور باستمرار، أصبحت الحاجة إلى مستويات أعلى من التجريد واضحة بشكل متزايد. ويشير التحول السائد نحو التطبيقات المعبأة في حاويات والخدمات الصغيرة إلى الابتعاد عن الأساليب التقليدية المتجانسة. ضمن هذا المشهد، برزت Kubernetes باعتبارها المنسق الرئيسي لإدارة التطبيقات السحابية الأصلية، مما يجسد المعيار الفعلي للصناعة. ومع ذلك، مع تزايد تركيز التطوير على سرعة الحركة وقابلية التوسع والكفاءة، ينشأ اعتبار جدير بالملاحظة: التعقيدات المرتبطة بالحلول المعتمدة على kernel تتعارض مع الطبيعة المبسطة للمبادئ الأصلية السحابية المعاصرة. إن التنقل في هذا التقاطع المعقد للتقنيات يحثنا على فهم التحديات التي تقدمها وحدات kernel، واستكشاف طرق بديلة تتناغم بشكل أكثر سلاسة مع روح البنية السحابية الأصلية.

في هذه السلسلة من منشورات المدونة، سنقدم eBPF ومفاهيمه، ثم نتعمق في حالات الاستخدام الواقعية.

وحدة النواة: التحديات الكامنة في أساليب التطوير الجديدة

وحدات Kernel عبارة عن تعليمات برمجية قابلة للتنفيذ يمكن تثبيتها في نواة نظام التشغيل Linux لتحسين وظائفها.

دعونا نلقي نظرة فاحصة على البنية الشاملة. في الأسفل، لدينا أجهزتنا. علاوة على ذلك، هناك نواة Linux، وهي جوهر نظام التشغيل ولها وصول غير مقيد إلى جميع الأجهزة، بما في ذلك وحدة المعالجة المركزية والذاكرة.

توفر النواة واجهة استدعاء النظام، والتي عادة ما تكون مكتوبة بلغة C مع بعض التجميع. تتضمن أمثلة مكالمات النظام com.getpid و إعادة التشغيل. تستدعي التطبيقات والمكتبات واجهة استدعاء النظام للتواصل مع النواة والأجهزة. توجد مساحة النواة في الأسفل، بينما تكون مساحة المستخدم في الأعلى حيث يتم تشغيل التطبيقات. يمكن للتطبيقات الاتصال مباشرة بواجهة استدعاء النظام، أو يمكنها المرور عبر المكتبات (عادةً ما يتم استخدام المكتبات لتجنب إعادة اختراع العجلة). ومع ذلك، من الممكن كتابة تطبيق بسيط يستدعي نظام Linux kernel syscall مباشرة. عند تقديم طلب، تقوم واجهة استدعاء النظام بتمريره إلى النواة ثم إلى الجهاز.

تسمح وحدات Linux Kernel (LKMs) للمطورين بإضافة أجهزة جديدة أو أنظمة ملفات أو بروتوكولات شبكة أو استدعاءات نظام مباشرة إلى kernel. لكن LKMs تشكل أيضًا مخاطر مثل تجاوز الإجراءات الأمنية والتسبب في تعطل النظام في حالة فشل كود kernel، مما يسبب مخاوف تتعلق بالسلامة للمستخدمين. من المهم أن نلاحظ أيضًا أن LKMs تحتاج إلى صيانة منتظمة، نظرًا لأن تحديث إصدار Linux kernel قد يتسبب عن غير قصد في تلف الوحدة.

ما هو eBPF؟

تم إنشاء Berkeley Packet Filter لتصفية حزم الشبكة وفقًا لقواعد محددة. في الأساس، كان يعمل مثل جدار الحماية حيث تتم عملية التصفية داخل جهاز ظاهري قائم على التسجيل. ومع ذلك، بمرور الوقت، أصبح BPF قديمًا لأن محرك الآلة الافتراضية ومجموعات التعليمات الخاصة به لم تكن تستخدم الإمكانات الكاملة لمعالجات 64 بت.

يتغلب eBPF، وهو إصدار أكثر تقدمًا من BPF، على هذا القيد من خلال توافقه مع الأجهزة الحديثة، بما في ذلك شرائح 64 بت. تعمل هذه التحسينات وغيرها على تمكين eBPF من القيام بأكثر من مجرد العمل كجدار حماية افتراضي. الآن، يسمح eBPF بتنفيذ بعض التطبيقات بشكل منفصل بواسطة kernel دون المساس بأمان نظام التشغيل أو المهام الجارية الأخرى.

مهندس البرمجيات بريندان د. جريج، الخبير في هذا المجال، يقارن eBPF بجافا سكريبت في HTML. في حين أن لغة HTML تقيد صفحة الويب بالمحتوى الثابت، فإن JavaScript تسمح للبرامج الصغيرة بالعمل في المتصفح كما لو كان جهازًا افتراضيًا دون المساس بالنظام.

وبالمثل، يسمح eBPF للتطبيقات بالوصول إلى بنية kernel في وضع الحماية المحدود بمجموعة من موارد النظام. يمكن ملاحظة التنفيذ بالكامل في الوقت الفعلي، مما يجعل eBPF يستخدم على نطاق واسع لرصد وتحليل وتصفية المهام المتعلقة بالشبكة أو مجالات الأمان، مثل تخفيف هجمات DDoS.

كيف يمكن حل التحديات التي تفرضها التطبيقات السحابية الأصلية؟

BPF هي أداة قوية تمكن المستخدمين من تعديل الحزم وتغيير وسيطات syscall وحتى تعديل تطبيقات مساحة المستخدم. يعد هذا مفيدًا لأنه يوفر بديلاً آمنًا لتشغيل تعليمات برمجية عشوائية في kernel دون الحاجة إلى تحميله في وحدة kernel. يشبه eBPF وحدة kernel على المنشطات. فهو يسمح لك بإرفاق كود ثانوي مخصص في وضع الحماية لكل وظيفة تقريبًا يتم تصديرها عبر جدول رموز kernel دون القلق بشأن كسر kernel. يعطي eBPF الأولوية للسلامة عند عبور حدود مساحة المستخدم. لن يقوم أداة التحقق داخل kernel بتحميل أي برنامج eBPF إذا اكتشف مرجعيات غير صالحة للمؤشر أو تجاوز الحد الأقصى لحجم المكدس. على الرغم من عدم السماح بالحلقات، باستثناء تلك ذات الحدود العليا الثابتة المعروفة في وقت الترجمة، إلا أنه يمكن استدعاء مجموعة فرعية صغيرة فقط من وظائف مساعد eBPF المحددة في الكود الثانوي الذي تم إنشاؤه. يتم ضمان إنهاء برامج eBPF في مرحلة ما وعدم استنفاد موارد النظام أبدًا، وهذا ليس هو الحال مع وحدات kernel التي يمكن أن تسبب عدم استقرار النظام أو تؤدي إلى ذعر kernel. قد يجد بعض الأشخاص أن eBPF مقيد للغاية مقارنة بـ “الحرية” التي توفرها وحدات kernel. ومع ذلك، من المرجح أن تفضل المفاضلات eBPF على الأجهزة “الموجهة نحو الوحدة”، ويرجع ذلك أساسًا إلى أن برامج eBPF لا يمكنها الإضرار بالنواة. بالإضافة إلى ذلك، يوفر eBPF فوائد أخرى إلى جانب السلامة.

على سبيل المثال، باستخدام eBPF، يمكنك بسهولة تحقيق إمكانية ملاحظة الأمان في kernel دون الحاجة إلى إجراء تغييرات على التطبيقات أو إدارة نظام موزع معقد. إنه حل خفيف الوزن يبسط العملية ويقدم إجابات سريعة على الأسئلة التالية:

  • هل تم تنفيذ العملية باستخدام إدخال مأخذ توصيل غير قياسي، مما يمثل هجومًا لتنفيذ التعليمات البرمجية عن بُعد (RCE)؟

  • هل حاولت إحدى العمليات إنشاء اتصال بمجال معروف لتعدين العملات المشفرة؟

  • هل كانت هناك محاولة للوصول إلى `/etc/passwd`؟

انظر eBPF في العمل

كمسؤولي النظام، نحن على دراية بفوائد استخدام strace كأداة لمراقبة مكالمات النظام. ومع ذلك، من المهم ملاحظة أن هذا الأمر يمكن أن ينشئ قدرًا كبيرًا من الحمل عند إنشاء المخرجات. قد يؤدي استخدامه على خادم إنتاج دون تكرار إلى عواقب وخيمة. باستخدام BPF، نتجنب خطر التأثير على النظام بسبب انخفاض حمله.

لتوفير بعض السياق، من المهم ملاحظة أنه لا يمكن تثبيت eBPF مثل البرامج العادية. وهو ينبع من bpf() syscall. الحد الأدنى المطلوب لإصدار النواة هو 4.4. في حالتي، أقوم بتشغيل الإصدار 5.15 على Ubuntu 22.04:

$ uname -a 

Linux lima-learning-ebpf 5.15.0-72-generic #79-Ubuntu SMP Tue Apr 18 16:53:43 UTC 2023 aarch64 aarch64 aarch64 GNU/Linux 

$ lsb_release -a 

No LSB modules are available. 

Distributor ID:	Ubuntu 

Description:	Ubuntu 22.04.2 LTS 

Release:	22.04 

Codename:	jammy 

للمتابعة، سنحتاج إلى تثبيت نسخة مخفية الوجهة. يمكن العثور على مشروع BCC في مشروع BCC. تتوفر هنا تعليمات تثبيت BCC، وهي توفر واجهة سهلة الاستخدام لتجميع برامج eBPF وتحميلها. إنه أمر بسيط جدًا بحيث يمكنك استخدام برنامج Python النصي لتجميع برنامجك وتحميله والتفاعل معه.

#!/usr/bin/python3   
from bcc import BPF 
program = r""" 

int hello(void *ctx) { 

    bpf_trace_printk("Hello World!"); 

    return 0; 

} 

""" 
b = BPF(text=program) 

syscall = b.get_syscall_fnname("execve") 

b.attach_kprobe(event=syscall, fn_name="hello") 

b.trace_print() 

الكود أعلاه، يقوم برنامج Python بتجميع كود C، بدون حلقات، أو printf، أو متغيرات عامة، ويحمله في النواة، ويرفقه بـ execve syscall kprobe. عندما يقوم أحد التطبيقات على الجهاز الظاهري باستدعاء execve()، فإنه يقوم بتشغيل برنامج eBPF hello(). يكتب هذا البرنامج رسالة تتبع في ملف زائف محدد، ثم تتم قراءة رسالة التتبع بواسطة برنامج بايثون ويتم عرضها للمستخدم.

قم بتشغيل البرنامج باستخدام Sudo:

أنها توفر الكثير من أمثلة مفيدة و برنامج تعليمي لطيف للبدء في كتابة أدوات تتبع eBPF.

eBPF باختصار

قامت نواة Linux بدمج الجهاز الظاهري الموسع Berkeley Packet Filter (eBPF) لبضع سنوات حتى الآن. تتيح هذه الميزة للمستخدمين تطبيق مرشحات eBPF على مآخذ توصيل محددة تتجاوز مجرد تصفية الحزم. يمكن استدعاء البرامج النصية المخصصة بأقل قدر من الحمل في نقاط مختلفة في النواة. على الرغم من أنها ليست تقنية جديدة، إلا أن eBPF أصبحت الآن أكثر نضجًا مع نشر الخدمات الصغيرة بشكل متزايد كحاويات منسقة. قد يكون ربط مشكلات زمن الاستجابة أو الأداء باستدعاء واجهة برمجة التطبيقات (API) أمرًا صعبًا مع الاتصالات المعقدة من خدمة إلى خدمة. في الآونة الأخيرة، ظهرت أدوات تحتوي على نصوص eBPF مكتوبة مسبقًا لجمع وعرض حركة مرور الحزم أو إنشاء تقارير حول استخدام وحدة المعالجة المركزية.

يبدو مستقبل eBPF واعدًا جدًا حيث أنه يكتسب المزيد من الاعتماد عبر الصناعات والمنصات، مثل موفري الخدمات السحابية وأنظمة تنسيق الحاويات مثل Kubernetes. مع التطوير المستمر لنظام eBPF البيئي، بما في ذلك الأدوات والمكتبات والقدرات المحسنة، ستصبح البرمجة باستخدام eBPF أسهل، وسيتم تمكين التطبيقات الأكثر تطورًا. سيتم أيضًا توسيع إمكانية تطبيق eBPF بسبب الدعم عبر الأنظمة الأساسية، مثل مشروع eBPF الخاص بـ Microsoft لنظام التشغيل Windows. ومع اكتساب eBPF زخمًا، فمن المرجح أن يتكامل بشكل أعمق مع أدوات المراقبة والأمن والإدارة الحالية، مما يسمح للمستخدمين بالاستفادة من eBPF دون الحاجة إلى التخلي عن مجموعات أدواتهم الحالية أو إعادة تعلمها.

بشكل عام، تعد eBPF تقنية قوية ومتعددة الاستخدامات داخل Linux kernel. إنها مهيأة للنمو وستستمر في تحسين BPF التقليدي وفتح إمكانيات جديدة في الشبكات والمراقبة والأمن والمزيد. إنها تقنية مهمة يجب تعلمها، لأنها تساعد في إنشاء حلول أفضل وأكثر كفاءة لأنظمة Linux.

شاركها.
اترك تعليقاً