الملخص

  • containerd برنامج خفي مفتوح المصدر متخرج من CNCF، يدير محتوى الصور واللقطات وبيانات الحاويات الوصفية والمهام العاملة لصالح المنصات الأعلى على Linux وWindows.
  • نشأ المشروع من إعادة هيكلة مكونات التشغيل في Docker، وانتقل إلى Cloud Native Computing Foundation في عام ٢٠١٧، ثم أصبح طبقة بنية تحتية مشتركة بدلاً من منصة حاويات متكاملة.
  • يتصل Kubernetes بـcontainerd عبر Container Runtime Interface، بينما تظل الشبكات والعزل منخفض المستوى والثقة بالصور وجدولة العناقيد مسؤوليات منفصلة تؤثر بدورها في النتيجة.
  • أصبح containerd 2.3 خط الدعم طويل الأجل الحالي في ٣٠ أبريل ٢٠٢٦؛ وتوضح إصلاحات الأمن ودورة الحياة اللاحقة أن التنظيف والمصالحة وتسليم التصحيحات أجزاء من صحة عمل بيئة التشغيل.

تسرّب نقطة تحميل يُعد إخفاقاً في بيئة التشغيل حتى لو بدأت العملية

في ١٠ يوليو ٢٠٢٦، أصدر containerd الإصدار 2.3.3. وشملت الإصلاحات تغييرات في التحقق من حالة بيئة العزل، والتعامل مع خروج NRI، ومساراً لفشل إحدى الخطافات كان يمكن أن يؤدي إلى تسرب نقاط تحميل. لا يبدو أي منها مثيراً بقدر هروب من حاوية. لكن بالنسبة إلى المشغّل، فإن نقطة تحميل كان ينبغي أن تختفي ولم تختف هي إخفاق حقيقي في بيئة التشغيل: فعند تكرار التسربات الصغيرة عبر أسطول من العقد، يمكن أن تستهلك موارد المضيف، وتعقّد التنظيف، وتحول جهازاً سليماً في جوانب أخرى إلى جهاز يجب إخلاؤه أو إعادة بنائه.

يجسد ذلك الإصدار سبب أهمية containerd. فمعظم المستخدمين لا يتعاملون مباشرة مع البرنامج الخفي. إنهم يطلبون من Kubernetes تشغيل وحدة pod، أو من Docker تشغيل حاوية، أو من خدمة سحابية مُدارة توفير عقدة. ويقبع containerd تحت هذه الطلبات، محولاً إياها إلى انتقالات في الحالة تشمل محتوى الصور ولقطات نظام الملفات وسجلات الحاويات ووسائط التشغيل والعمليات الحية. وقد تتعافى المنصة المرئية بإعادة جدولة العمل، لكن على بيئة التشغيل أن تترك العقدة في حالة يمكن فهمها وإعادة استخدامها.

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

هذا هو التوتر الأساسي المحيط بـcontainerd. فقد نجح المشروع بأن أصبح طبقة وسطى مشتركة تحت منتجات كثيرة. ويجعل الانتشار نفسه قراراته العادية المتعلقة بدورة الحياة مؤثرة في أساطيل كبيرة قد لا يظهر اسمه مطلقاً لفرق التطبيقات.

أصبح containerd مفيداً لأنه توقف قبل أن يتحول إلى منصة

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

هذه الحدود مقصودة. يستطيع Docker Engine بناء منتج موجه للمستخدم فوقه. ويستطيع Kubernetes استخدامه كبيئة تشغيل للعقدة عبر Container Runtime Interface. ويمكن لمزودي الخدمات السحابية تضمينه في صور العقد. كما يمكن لتوزيعات Linux شحنه بإعداداتها الافتراضية وتصحيحاتها المنقولة إلى الإصدارات الأقدم. وهكذا يستطيع كل نظام أعلى تقديم نموذج تشغيلي مختلف من دون إعادة تنفيذ الآليات الأساسية نفسها لدورة حياة الصور والعمليات.

يفسر هذا التمييز أيضاً سهولة إساءة استخدامctr، وهو الأمر المرفق مع containerd. إذ يعامله المشروع كواجهة غير مستقرة للتصحيح والتطوير، لا كعقد مدعوم وموجه للمستخدم. وقد يعمل مسار إنتاج يعتمد ضمنياً على تفاصيلctrالداخلية لسنوات، ثم يكتشف أنه بُني على جزء من المشروع تُرك عمداً حراً للتغيير.

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

استخرج Docker نواة تشغيل مشتركة وأنشأ بنية تحتية يمكن لمنتجات أخرى إعادة استخدامها

بدأ containerd داخل Docker. فقد جمع Docker المبكر توزيع الصور والبناء وواجهات برمجة التطبيقات والشبكات ودورة حياة العمليات في منتج واحد. ومع نمو المنصة، فُصل عمل بيئة التشغيل بحيث تتطور الآليات الدائمة لإعداد الحاويات والإشراف عليها بصورة مستقلة عن بقية واجهة منتج Docker.

يبدأ سجل الإصدارات العام بسلسلة 0.0 المؤرخة في ٤ ديسمبر ٢٠١٥. وفي مارس ٢٠١٧، تبرعت Docker بـcontainerd إلى Cloud Native Computing Foundation. ثم صدر الإصدار 1.0 في ٥ ديسمبر ٢٠١٧، مؤسساً واجهات gRPC مستقرة وعقد تضمين موجهاً للإنتاج. وأعلنت CNCF تخرج المشروع في ٢٨ فبراير ٢٠١٩.

كان التحول المؤسسي مهماً لأن Docker كانت الجهة المنشئة وشركة منصة تجارية في الوقت نفسه. ويسهل الاعتماد على بيئة تشغيل تستخدمها شركات سحابية متنافسة وموزعو Linux وموردو Kubernetes عندما لا تكون حوكمتها الأصلية ملكاً حصرياً لمورد منتج واحد. كما يسمح Apache License 2.0 باستخدام تجاري ومفتوح المصدر واسع من دون إلزام كل جهة متبنية باتباع نموذج أعمال واحد.

لم تمحُ استضافة المؤسسة تاريخ Docker أو تأثير الشركات التي توظف القائمين على الصيانة. لكنها غيّرت المسار الرسمي الذي يمكن من خلاله حكم الشفرة المشتركة. وأصبح containerd بنية تحتية واصلت Docker استخدامها، بدلاً من كونه مكوناً داخلياً يتعين على الآخرين قبوله وفق شروط Docker.

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

للصور والحاويات والمهام معانٍ مختلفة عمداً

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

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

لكنه ينشئ أيضاً التزاماً تشغيلياً. فحذف كيان واحد لا يثبت تلقائياً استعادة كل نظام ملفات أو كتلة بيانات أو وسيط تشغيل أو مورد شبكة ذي صلة. وقد تعرض المراقبة التي تحصي الحاويات من دون فهم المهام حالة مضللة. كما قد تترك شفرة التنظيف التي تفترض أن حذفاً واحداً يستتبع البقية موارد وراءها.

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

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

يثبت توجيه المحتوى بالعنوان أي بايتات وصلت، لا ما إذا كان ينبغي الوثوق بها

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

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

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

القاعدة العملية للمشغلين بسيطة: هوية الصورة والثقة بها ضابطان مختلفان. وينبغي لتحليل الحوادث تسجيل كل من الملخص الذي شُغّل والسياسة التي سمحت بتشغيله. فوصف مخزن موجّه بالملخص بأنه نظام أمني يدمج سؤالين منفصلين في سؤال واحد.

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

تحول إضافات اللقطات الصور غير القابلة للتغيير إلى أنظمة ملفات قابلة للعمل

يمكن تخزين الصورة من دون أن تكون جاهزة للتنفيذ. فالحاوية العاملة تحتاج إلى عرض لنظام الملفات يجمع طبقات الصورة مع حالة قابلة للكتابة. ويفوض containerd هذا العمل إلى إضافات اللقطات.

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

تكمن الميزة في الوحداتية. فلا يلزم إعادة كتابة البرنامج الخفي الأساسي لكل استراتيجية لنظام الملفات. ويمكن لمزودي الخدمات السحابية وموردي التخزين ومنصات الحافة تحسين زمن البدء أو استخدام القرص أو الوصول البعيد خلف حدود خدمة مشتركة.

أما التكلفة فهي أن سلوك اللقطات غير موحد. إذ تعتمد عملية جمع المهملات ودلالات التركيب وسلوك الحصص وزمن البدء والتعافي على التطبيق. ومن ثم فإن اختبار أداء ينسب بدءاً بارداً سريعاً إلى «containerd» من دون تحديد مسار الصورة والسجل والقرص وإضافة اللقطات يظل ناقصاً.

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

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

تتيح وسائط Runtime v2 للمهمة النجاة من البرنامج الخفي الذي أنشأها

لا ينفذ containerd عادة عملية حاوية Linux بنفسه. بل يستخدم وسيط تشغيل للتواصل مع بيئة تشغيل منخفضة المستوى مثل runc، التي تنفذ عملية الإنشاء والتشغيل النهائية باستخدام بدائيات نظام تشغيل المضيف.

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

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

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

هذا النموذج متعدد الطبقات هو سبب غموض عبارة «بيئة تشغيل الحاويات». فـcontainerd خدمة طويلة العمر لدورة الحياة والحالة. وتقوم runc وبيئات التشغيل البديلة منخفضة المستوى بإنشاء العمليات. ويمكن لـKata Containers أو gVisor تغيير نموذج العزل الأدنى مع بقاء containerd وسيطاً فوقها. ويبدأ الإسناد الدقيق للحوادث بتسمية الطبقة التي أخفقت فعلياً.

يعتمد Kubernetes على containerd من دون أن يسلمه العنقود

يتصل Kubernetes بـcontainerd عبر Container Runtime Interface. وتطبق إضافة CRI المضمّنة خدمات التشغيل والصور التي يتوقعها kubelet، فتربط بيئات عزل وحدات pod والحاويات بكيانات containerd وتنسق مع مسار التشغيل والشبكة المُعد.

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

تكتسب الحدود أهمية عند الإخفاق. فقد يُمنع بدء وحدة pod بسبب إعداد kubelet، أو توافق CRI، أو صورة مفقودة، أو خطأ في إضافة اللقطات، أو إعداد CNI، أو وسيط تشغيل، أو runc، أو النواة. ووصف الواقعة ببساطة بأنها «إخفاق containerd» قد يخفي نقطة التسليم التي أخفقت فعلياً. كما أن وصف كل مشكلة في بيئة التشغيل بأنها «Kubernetes» غير دقيق بالقدر نفسه.

للتوافق أيضاً بُعد متعلق بالإصدارات. فتوزيعات Kubernetes تعتمد مجموعات محددة من إصدارات containerd وCRI والإعدادات. وقد تحمل الخدمات المُدارة تصحيحات لاحقة أو إصدارات متأخرة. ويمكن أن يكون إصدار المنبع صحيحاً بينما تظل صورة عقدة سحابية على بناء أقدم، كما يمكن لمزود سحابي نقل إصلاح أمني إلى إصدار سابق من دون تغيير رقم الإصدار بالطريقة التي يتوقعها مستخدم المنبع.

لهذا السبب، الكيان التشغيلي هو قائمة مكونات العقدة، لا اسم المشروع وحده: containerd وبيئة التشغيل منخفضة المستوى وملفات CNI التنفيذية وإضافة اللقطات والنواة والإعدادات والتصحيحات اللاحقة. هذه هي الحزمة التي تبدأ وحدة pod وتحذفها فعلياً.

يحافظ CNI وNRI على ضيق نطاق containerd بنقل مزيد من المسؤولية إلى حزمة العقدة

تعتمد بنية containerd بشدة على التركيب. ويمكن لمسار CRI استدعاء إضافات Container Network Interface خارجية لإنشاء شبكة بيئة العزل وإزالتها. كما تستطيع إضافات Node Resource Interface مراقبة أحداث دورة الحياة وضبط إعدادات الموارد أو التشغيل المسموح بها. وتحل إضافات اللقطات والتشغيل محل مكونات التخزين والتنفيذ من دون إعادة كتابة واجهة برمجة التطبيقات الأساسية.

هكذا يظل البرنامج الخفي صغيراً بما يكفي لإعادة الاستخدام. فيستطيع المتخصصون في الشبكات تطوير تطبيقات CNI. ويمكن لموردي الأجهزة استخدام NRI أو آليات ذات صلة بدلاً من صيانة نسخة خاصة. ويستطيع مطورو التخزين إضافة لقطات بعيدة، كما يمكن لمشروعات العزل دمج بيئات تشغيل بديلة.

لكن كل امتداد يضيف أيضاً تبعية للإخفاق والثقة. فقد يترك فشل CNI ADD أو DEL عناوين أو واجهات أو نطاقات أسماء وراءه. وقد تمنع إضافة NRI سيئة دورة الحياة أو تغير التخصيصات على العقدة. ويمكن لإضافة لقطات من طرف ثالث أن تسرب نقاط تحميل أو تسيء التعامل مع جمع المهملات. كما قد تعمل إضافة تشغيل بصورة صحيحة مع نواة وتفشل مع أخرى.

لا ينتقل نضج المشروع الأساسي تلقائياً إلى شبكة الامتدادات. فإصدار containerd مدعوم لا يعتمد كل إضافة أو بيئة تشغيل أو إعداد مقترن به. ويحتاج المشغلون إلى معرفة منشأ كل امتداد مميز الصلاحيات وإصداره وتوقيعه ومسار دعمه وخطة التراجع عنه قبل السماح له بالدخول في دورة حياة العقدة.

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

تنظم نطاقات الأسماء العملاء داخل برنامج خفي واحد، لكنها لا تنشئ حدود مضيف جديدة

تتيح نطاقات أسماء containerd لعملاء مختلفين تجميع الموارد وتوجيهها داخل برنامج خفي واحد. ويمكن لـDocker وCRI وغيرهما من الجهات المضمِّنة إبقاء صورها وحاوياتها ولقطاتها ومهامها منفصلة منطقياً بدلاً من تصادمها في مساحة كيانات مسطحة واحدة.

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

قد يستطيع عميل لديه وصول كافٍ إلى البرنامج الخفي حصر الموارد أو تنفيذ إجراءات عبر نطاقات الأسماء وفقاً لصلاحياته وسلوك الإضافات. ومن ثم فإن الحد آلية لتحديد نطاق واجهة برمجة التطبيقات، وليس بديلاً من صلاحيات Unix أو حماية المقبس أو نطاقات أسماء النواة أو cgroups أو ضوابط الوصول الإلزامية أو العزل المدعوم بالآلات الافتراضية.

يهم هذا التمييز تجارياً وتقنياً. فقد تعلن منصة عن فصل منطقي بينما تضع عدة عملاء على بيئة تشغيل مميزة الصلاحيات ونواة مضيف مشتركتين. ويجب بناء الحجة الأمنية عند طبقتي المضيف والعزل، لا استنتاجها من وجود سلسلة نطاق أسماء في containerd.

يستفيد المشروع عندما تظل هذه الحدود صريحة. فهو يستطيع تقديم نموذج تنظيمي واضح من دون الادعاء بأنه يحل عزل المستأجرين الذي ينتمي إلى طبقة أدنى في الحزمة.

يجب إدراج مقبس البرنامج الخفي في نموذج التهديد نفسه الخاص بإدارة المضيف

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

وهذا يجعل الوصول إلى المقبس والتعرض البعيد والمصادقة والتدقيق وصلاحيات الإضافات ضوابط أمنية أساسية. وقد يؤدي التعامل مع البرنامج الخفي باعتباره تفصيلاً تنفيذياً خفياً إلى حماية الفرق لواجهة Kubernetes مع اهتمام أقل بالواجهة المحلية للعقدة التي تنشئ العمليات المميزة الصلاحيات فعلياً.

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

لذلك يحتاج إسناد الأمن إلى عدة طبقات. فالثغرة في تعامل containerd مع واجهة برمجة التطبيقات تختلف عن هروب عبر runc أو خلل في النواة أو إضافة CNI غير آمنة أو حمل عمل Kubernetes مفرط الصلاحيات. ولا يثبت إصلاح في containerd بالمنبع أن كل عقدة لاحقة محمية، كما لا يجعل إصدار آمن من containerd نواة ضعيفة آمنة.

تضمن الإصدار 2.3.2، الصادر في ١٨ يونيو ٢٠٢٦، تصحيحات لخمس ثغرات CVE مدرجة في containerd إلى جانب إصلاحات أخرى لبيئة التشغيل. والسؤال التشغيلي الصحيح ليس ما إذا كان أحدث إصدار «آمناً»، بل أي تحذير يؤثر في الإعداد المنشور، وأي بناء يحتوي الإصلاح، ومتى وصل ذلك البناء فعلياً إلى العقد العاملة.

تجعل الأحداث وجمع المهملات المصالحة مهمة مستمرة

تحتاج بيئة التشغيل طويلة العمر إلى تذكر قدر كافٍ من الحالة للتعافي من العمليات المنقطعة، مع استعادة الموارد التي لم تعد مطلوبة. وتدعم آليات البيانات الوصفية والأحداث وجمع المهملات في containerd هذا العمل.

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

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

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

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

يحول خط الدعم طويل الأجل 2.3 هندسة الإصدارات إلى عقد تشغيلي

أصبحت سياسة إصدارات containerd أكثر وضوحاً مع انتقال المشروع إلى حقبة 2.x. فقد بدأ خط 1.6 في ١٥ فبراير ٢٠٢٢، وتلاه خط الدعم طويل الأجل 1.7 في ١٠ مارس ٢٠٢٣. ووصل الإصدار 2.0 في ٥ نوفمبر ٢٠٢٤، مع استمرار 2.1 و2.2 في عملية الانتقال خلال ٢٠٢٥.

في ٣٠ أبريل ٢٠٢٦، أصدر المشروع containerd 2.3 وعيّنه خط الدعم طويل الأجل الحالي، مع دعم مخطط حتى ٣٠ أبريل ٢٠٢٨. كما انتقل المشروع إلى دورة إصدار فرعي كل أربعة أشهر، ونشر درجات المنصات وتوقعات استقرار واجهات برمجة التطبيقات ومسارات الترقية المدعومة.

هذه سياسة بنية تحتية، لا مجرد ترتيب لمستودع الشفرة. إذ يحتاج مزودو الخدمات السحابية وتوزيعات Kubernetes إلى معرفة المدة التي سيتلقى خلالها الفرع الإصلاحات، وتسلسلات الترقية المتوقع نجاحها، والمنصات التي يستطيع المشروع اختبارها باستمرار. وتتيح حالة الدعم طويل الأجل للمشغّل تخطيط صيانة صور العقد وفق أفق معلن بدلاً من استنتاج الدعم من نشاط الإيداعات.

العقد محدود عمداً. فالضمانات المستقرة تنطبق على واجهات برمجة التطبيقات الموثقة والمنصات المدعومة. ويقعctrخارج ذلك الوعد. كما لا تُغطى إضافات الأطراف الثالثة تلقائياً. ويمكن للتوزيعات اللاحقة نقل الإصلاحات إلى إصدارات أقدم أو تأخير الإصدارات أو تعديلها. ولا يحدد أفق الدعم على مستوى المشروع متى سيستبدل مزود سحابي مُدار صورة عقدة ضعيفة.

عند نهاية البحث للمقال في ٦ أغسطس ٢٠٢٦، كان 2.3.3 أحدث إصدار مستقر جرى التحقق منه، بعد تصحيح 2.3.2 المتضمن إصلاحات أمنية في يونيو. وكان الإصدار 2.4 مقرراً بصورة أولية في ٢٦ أغسطس ٢٠٢٦. وكان ذلك التاريخ خطة لا إصداراً مكتملاً، وينبغي تحديثه قبل النشر إذا تجاوز المقال تاريخ القطع.

يجعل نموذج الإصدارات تبعية خفية أسهل في الحوكمة. وسيظهر نجاحه في جودة التصحيحات المنقولة إلى الإصدارات السابقة، وسلامة فرع 2.3 حتى ٢٠٢٨، والوقت الذي تستغرقه الأساطيل اللاحقة لاستيعاب الإصلاحات المهمة.

تكشف درجات المنصات مواضع اعتماد قابلية النقل على قدرة اختبار مستدامة

يدعم containerd أكثر من بيئة تشغيل، لكن الدعم ليس ادعاءً مجرداً بأن كل البنى تتصرف بالطريقة نفسها. وعند تاريخ قطع البحث، شملت منصات الدرجة الأولىlinux/amd64وlinux/arm64وwindows/amd64.

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

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

لذلك نتيجتان بالنسبة إلى المشترين. أولاً، ينبغي تقييم ميزة المشروع وفق المجموعة الدقيقة المدعومة من المنصة وبيئة التشغيل. وثانياً، يُعد رفع درجة منصة أو خفضها أمراً جوهرياً لأنه يشير إلى تغير في قدرة المشروع على ضمان الفرع، لا إلى مجرد تعديل في الوثائق.

ينطبق المبدأ نفسه على تكاملات الأجهزة المتخصصة. فقد يعرض البرنامج الخفي نقطة امتداد عامة، بينما تعتمد جودة الإنتاج لمسار معين خاص بوحدة معالجة الرسومات أو التخزين أو الشبكات على شفرة واختبارات تُصان في مكان آخر.

أنشأت CNCF منبعاً محايداً، لكن containerd المنشور لا يزال متعدد المالكين

يُحكم containerd كمشروع تابع لـCNCF من خلال القائمين على الصيانة والمودعين ومسؤولي الإصدارات وسجلات الحوكمة وعملية أمنية. ولا يملك المشروع مجلس إدارة أو مساهمين أو فريقاً تنفيذياً بالمعنى التقليدي. وتأتي السلطة من أدوار المشروع وعمليات المساهمة، لا من ملكية الأسهم.

يجعل هذا النموذج بيئة التشغيل قابلة للاستخدام من شركات متنافسة. فلا يحتاج مزود سحابي إلى شراء containerd من مزود سحابي آخر. ويمكن لتوزيع Linux تضمينه، ولـDocker إدماجه، ولموردي Kubernetes اعتماده، وللقائمين على الصيانة الذين توظفهم مؤسسات مختلفة العمل على شفرة المنبع نفسها.

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

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

هذا التحكم متعدد الطبقات محوري في الإبلاغ عن الحوادث. فتاريخ إصدار المنبع ليس تاريخ اكتمال التصحيح في السوق. وقد يصف تحذير سحابي أسطولاً جرى إصلاحه حتى عندما يختلف رقم الإصدار العام عن المنبع. والإجابة الموثوقة الوحيدة هي تتبع البناء الدقيق ومسار طرحه.

يخلق containerd قيمة اقتصادية من دون بند إيرادات تقليدي

containerd ليس شركة منتج مستقلة لها قائمة دخل منشورة. ولا يوجد في الأدلة المقدمة رقم لإيرادات containerd أو تقييم مؤسسي أو إحصاء نشر مدقق. تستضيف CNCF المشروع، ويمول أصحاب العمل جانباً كبيراً من الهندسة عبر وقت الموظفين، وتكسب الشركات اللاحقة المال من المنتجات والخدمات التي تضمن بيئة التشغيل.

تظهر قيمته الاقتصادية أساساً في تجنب الازدواجية. إذ تستطيع Docker وموردو Kubernetes والخدمات السحابية والتوزيعات مشاركة آليات الصور ودورة الحياة بدلاً من أن يمول كل منها برنامجاً خفياً منفصلاً بالكامل. ويمكن لإصلاح خلل أن ينتقل إلى عدة منتجات، كما يمكن لواجهة مستقرة خفض تكلفة صيانة التكاملات على مدى سنوات.

لكن هيكل المنفعة العامة يثير أيضاً سؤال الاستدامة. تستطيع شركات كثيرة الاعتماد على containerd من دون المساهمة بهندسة تتناسب مع حجم اعتمادها. وتحتاج فروع الدعم طويل الأجل إلى مسؤولي إصدارات وتكامل مستمر ونقل إصلاحات واستجابة أمنية بعد وقت طويل من انتقال الحماس المرتبط بالإصدار الجديد إلى مكان آخر. كما تتطلب الاختبارات الخاصة بالمنصات أجهزة وقائمين على الصيانة. ويجعل التضمين المشروع قيماً، لكنه يصعّب رؤية ميزانيته المباشرة.

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

كما لا يتوافر إحصاء كامل لعمليات النشر. ويتضح الاستخدام الواسع عبر Docker وKubernetes والمنتجات السحابية من دور المشروع، لكن ذلك لا يدعم ادعاء دقيقاً عن حصة السوق. والوصف الأكثر قابلية للدفاع هو أن containerd مضمّن على نطاق واسع وله أثر مهم، لا أنه يشغّل نسبة معلومة من حاويات العالم.

لا تنافس البدائل containerd إلا بعد تحديد الحدود

تخلط مقارنات بيئات تشغيل الحاويات غالباً بين منتجات تعمل في طبقات مختلفة. يُعد CRI-O بديلاً مباشراً في عمليات نشر CRI الموجهة إلى Kubernetes. أما Docker Engine فهو منصة أوسع موجهة للمستخدم تضمن containerd، بدلاً من أن تستبدل كل طبقة بنطاق مماثل. ويستخدم Podman وحزمة libpod نموذجاً مختلفاً للمستخدم والبرنامج الخفي. أما runc فهي بيئة تشغيل OCI منخفضة المستوى توجد عادة تحت containerd بدلاً من منافسته.

تغير Kata Containers وgVisor نموذج العزل أسفل وسيط دورة الحياة. ويمكنهما العمل عبر تكاملات التشغيل بينما يواصل containerd إدارة خدمات الصور والمهام الأعلى. أما Kubernetes نفسه فهو منسق فوق بيئة تشغيل العقدة، وتحدد Open Container Initiative المواصفات التي تستخدمها الحزمة بدلاً من تشغيل الحاويات.

تهم هذه الفروق لأن استبدال مكون واحد لا يزيل كل التبعيات. فالانتقال من containerd إلى بيئة CRI أخرى يؤثر في صور العقد واختبارات التوافق وتخزين اللقطات وإعداد التشغيل والأدوات التشغيلية. والانتقال من runc إلى بيئة عزل مدعومة بآلة افتراضية يغير حدوداً أخرى. كما أن استبدال Docker Engine قد يُبقي containerd في البنية الناتجة.

لذلك تكون المقارنة الوظيفية هي الأكثر فائدة. أي طبقة يجري استبدالها؟ وأي حالة يجب نقلها؟ وأي أدوات تشغيلية تفترض واجهة برمجة التطبيقات أو نموذج الكيانات القديم؟ وأي أنماط إخفاق ستتغير؟ إن وصفاً عاماً لـ«سوق بيئات التشغيل» يخفي أكثر مما يفسر.

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

يبدأ الاختبار الحقيقي لقابلية النقل عندما تتوقف عملية في منتصفها

يقوم تصميم containerd على فصل مفيد للمسؤوليات. يدير البرنامج الخفي حالة التشغيل الدائمة وخدماتها. وتعد إضافات اللقطات أنظمة الملفات. وتتوسط وسائط التشغيل المهام الحية. وتنشئ بيئات التشغيل منخفضة المستوى العمليات. ويعد CNI الشبكات. ويقرر Kubernetes أو نظام أعلى آخر ما ينبغي تشغيله. وتوفر النواة بدائيات العزل الفعلية.

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

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

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