Nov 30, 2025 · 6459 words · 31 min read

2. مبادئ التصميم#

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

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

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

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

2.1 بناء الثقة#

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

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

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

إن فكرة الأتمتة الجديرة بالثقة مستوحاة من عرض Damien Garros بعنوان Building Trustworthy Network Automation في Autocon3.

للتبسيط، إليك الخصائص الأربع الأساسية التي نحتاجها:

  • Predictable: نتائج متسقة وحتمية. يحتاج المهندسون إلى معرفة ما سيحدث قبل الضغط على “تشغيل”، والحصول على نفس السلوك في كل مرة.
  • Reliable: التعامل مع الأخطاء بسلاسة. الانتعاش من الإخفاقات. ضمان اكتمال العمليات بأمان (أو التراجع عنها) حتى في الظروف غير المتوقعة وعلى نطاق واسع.
  • Usable: واجهات تتيح للمهندسين التحقق من السلوك والتفكير فيه والتحكم فيه دون تعقيد مفرط. مع ضوابط حماية.
  • Understandable: لا يمكن أن يكون صندوقاً أسود. يجب أن يعرض النوايا والخطوات والنتائج والقرارات بطريقة تبني الثقة البشرية.
graph BT
  %% ===== Middle Layer =====
  subgraph L2[**الجودة**]
    direction LR
    B1[قابل للتنبؤ]:::layer2
    B2[موثوق]:::layer2
    B3[سهل الاستخدام]:::layer2
    B4[مفهوم]:::layer2
  end

  %% ===== Top Layer =====
  subgraph L1[" "]
    direction TB
    A[الثقة]:::layer1
  end

  %% ===== Connections: Behavior → Outcome =====
  B1 --> A
  B2 --> A
  B3 --> A
  B4 --> A

  %% ===== Styling =====
  classDef layer1 fill:#ffcccc,stroke:#b8860b,stroke-width:2px,color:#000;
  classDef layer2 fill:#ffe6cc,stroke:#4682b4,stroke-width:1.5px,color:#000;

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

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

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

إذن، انطلاقاً من هذه الخصائص، دعونا نستكشف المبادئ التي تدعمها.

2.2 مبادئ التصميم#

مع الثقة كأساس، يمكننا الآن استكشاف مبادئ التصميم التي تدعم الجودة اللازمة للأتمتة الجديرة بالثقة. هذه المبادئ تجعل الأتمتة موثوقة وقابلة للتنبؤ وقابلة للتوسع.

القائمة الكاملة يمكن أن تكون أطول بكثير (سنوسعها لاحقاً عند تقديم مبادئ هندسة البرمجيات الأخرى). لكن ثمة ستة مبادئ أساسية يجب أن يتضمنها كل حل لأتمتة الشبكات:

  • Idempotency: نفس العملية عدة مرات = نفس الحالة النهائية. يقلل الآثار الجانبية ويزيل الغموض ويجعل الأتمتة أكثر وضوحاً وأماناً للتكرار.
  • Transactional: تكتمل التغييرات بالكامل أو تفشل بأمان. لا حالات جزئية أو غير متسقة أو مُطبَّقة بشكل ناقص. أساسي لقابلية التنبؤ ويُتيح التراجع على مستوى الشبكة.
  • Intent-Driven: تحديد الحالة المطلوبة للنظام في ظروف مختلفة. يحسّن قابلية التنبؤ ويقلل العبء المعرفي ويجعل النظام أسهل استخداماً.
  • Dry Run مناسب: أظهر ما ستفعله قبل أن تفعله. يجعل الأتمتة أكثر قابلية للاستخدام وموثوقية بالسماح للبشر بالتحقق من الإجراءات ومشاهدة النتائج واكتشاف المشكلات قبل أن تصل إلى الشبكة.
  • Versioning: دعم تحكم الإصدارات في كل من البيانات والمنطق. التحرك للخلف أو الأمام في الوقت، واستعادة الحالات السابقة، والحفاظ على حالات متعددة بالتوازي. يعزز قابلية التنبؤ ويقوي الموثوقية.
  • قابل للاختبار: بيئة اختبار مناسبة أساسية قبل تنفيذ التغييرات في الإنتاج. تحسّن الموثوقية وتساعد المهندسين على فهم سلوك النظام.

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

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

graph BT
  %% ===== Bottom Layer =====
  subgraph L3[**المبادئ**]
    direction LR
    C1[ثابت النتيجة]:::layer3
    C2[مُعتمَد بإصدارات]:::layer3
    C3[تعاملي]:::layer3
    C4[قابل للاختبار]:::layer3
    C5[تجريبي]:::layer3
    C6[مدفوع بالنوايا]:::layer3
  end

  %% ===== Middle Layer =====
  subgraph L2[**الجودة**]
    direction LR
    B1[قابل للتنبؤ]:::layer2
    B2[موثوق]:::layer2
    B3[سهل الاستخدام]:::layer2
    B4[مفهوم]:::layer2
  end

  %% ===== Top Layer =====
  subgraph L1[" "]
    direction TB
    A[الثقة]:::layer1
  end

  %% ===== Connections: Foundation → Behavior =====
  C1 --> B1
  C1 --> B4

  C2 --> B3
  C2 --> B2

  C3 --> B1
  C3 --> B2

  C4 --> B2
  C4 --> B4

  C5 --> B3
  C5 --> B4

  C6 --> B1
  C6 --> B3

  %% ===== Connections: Behavior → Outcome =====
  B1 --> A
  B2 --> A
  B3 --> A
  B4 --> A

  %% ===== Styling =====
  classDef layer1 fill:#ffcccc,stroke:#b8860b,stroke-width:2px,color:#000;
  classDef layer2 fill:#ffe6cc,stroke:#4682b4,stroke-width:1.5px,color:#000;
  classDef layer3 fill:#ccffcc,stroke:#228b22,stroke-width:1.5px,color:#000;

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

2.2.1. مدفوع بالنوايا#

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

حالة استخدام شائعة للبدء بالأتمتة: سكريبتات أو كتيبات تُنفّذ إجراءات بسيطة. رفع واجهة أو خفضها بتوفير الاسم الكامل للنطاق واسم الواجهة. لكن هذا يخلق مشكلة. الشخص التالي الذي يعمل مع تلك الواجهة لن يعرف ما هي Desired State لها. هل يجب أن تكون مرفوعة أم مخفوضة؟

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

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

قد يجادل أحدهم بأن نواياه هي ببساطة Actual State الشبكة: “افحص الإعداد، هذه نواياي.” وإن كان هذا يُعدّ تقنياً نوايا، إلا أنك لا تستطيع إثبات أنه يطابق نواياك الأصلية أو الفعلية ولم يتغير بفعل الظروف، ما لم يكن لديك مصدر منفصل للمقارنة. إعداد الشبكة هو مخرج نواياك، وليس النوايا نفسها.

لذا فجودة بيانات Intent-Driven لديك تحدد مباشرة جودة أتمتتك. هذا المفهوم وثيق الصلة بـSource of Truth (SoT) (SoT)، الذي سنغطيه بالتفصيل في الفصل الرابع.

البنية التحتية كرمز (Infrastructure as Code - IaC): التصميم المدفوع بالنوايا هو أساس Infrastructure as Code (IaC): معاملة تعريفات البنية التحتية للشبكة معاملة كود البرمجيات. مع IaC، تحصل على تحكم في الإصدارات وعمليات مراجعة الكود والاختبار والقدرة على التعامل مع تغييرات البنية التحتية بنفس الطريقة التي تتعامل بها مع تغييرات البرمجيات. يُجسّر هذا أتمتة الشبكات مع أفضل ممارسات هندسة البرمجيات. يحتفظ IaC بالقوالب والمخزونات والنوايا كملفات تحت تحكم الإصدارات. تُراجَع التغييرات وتُختبَر وتُتتبع، لا تُطبَّق كتعديلات CLI عشوائية.

بالاستناد إلى النوايا، يضمن المبدأ التالي أنه حين نعرف ما نريد، نستطيع تنفيذه بأمان واتساق.

2.2.2. ثبات نتيجة التكرار#

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

Idempotency تعني أن تشغيل نفس العملية عدة مرات يُنتج نفس الحالة النهائية، دون آثار جانبية غير مقصودة.

على سبيل المثال، في توفير ACL الآلي، إن عرّفنا قاعدة، فنتوقع:

  • إن لم توجد القاعدة، تُضاف في موضع محدد.
  • إن كانت القاعدة موجودة بالفعل، لا تُضاف نسخ مكررة.
  • إن أُضيفت قاعدة أخرى لاحقاً، تبقى السابقة دون تغيير ولا تُعاد ترتيبها.

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

  • ما هي الحالة الراهنة لـACL؟
  • هل القاعدة جزء منها بالفعل؟
  • إن لم تكن كذلك، ما الفارق الذي يجب تطبيقه؟

بدون ثبات النتيجة، قد تُطبَّق الإعدادات بترتيب غير متوقع، مما يؤثر على قابلية الاستنساخ.

ينطبق هذا المبدأ على أبعاد مختلفة من أتمتة الشبكات. على سبيل المثال، عند طلب عنوان IP عبر DHCP أو من نظام IPAM يفهم الربط بين طلب المُعرِّف والنتيجة:

الشكل 1: مثال على ثبات نتيجة التكرار (من محادثة Damien Garros في Autocon3)

كما ستقرأ لاحقاً، لتحقيق ثبات نتيجة التكرار، يُفضَّل استخدام النماذج Declarative بدلاً من النماذج Imperative. حدد الحالة النهائية بدلاً من الخطوات. هذا لا يعني أن استخدام النمط الأمري مستحيل، لكنه أكثر تعقيداً.

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

2.2.3. التعاملية#

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

Transactional مفهوم شائع في قواعد البيانات، حيث تُطبَّق تغييرات متعددة بشكل ذري للحفاظ على الاتساق. في الشبكات (نظام موزع)، التعاملية أكثر تعقيداً، لكنها ليست مشكلة جديدة. في عام 2006، قدّم NETCONF (RFC 6241) تثبيتاً على مستوى الشبكة يُطبّق التغييرات عالمياً عبر أجهزة متعددة أو يتراجع كلياً إن فشل التحقق. هذه Atomic Operation تمنع الحالات الجزئية التي يكون فيها بعض الأجهزة مُحدَّثاً والبعض الآخر لا: سيناريو كابوسي لاستكشاف الأخطاء. غير أن ليس جميع المنصات تدعم NETCONF، وتتباين تعقيدات التكامل بشكل كبير. لذا رغم أن المشكلة محلولة نظرياً، يعتمد التطبيق العملي على بنيتك التحتية.

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

إذن، كيف يمكننا تطبيق التعاملية على الشبكات؟ هذا مزيج من التقنيات:

  • NETCONF: قدرات إدارة الشبكة التي تدعم التنسيق الموزع للإدارة. لكن الدعم محدود للغاية.
  • المعاملات المدعومة بقاعدة بيانات: تخزين تغييرات الإعداد في قاعدة بيانات ذات خصائص ACID، ثم تطبيقها في دُفعات منسقة مع إمكانية Rollback.
  • طوابير إشعارات التغيير: التقاط جميع التغييرات المقصودة، والتحقق منها كمجموعة، ثم تنفيذها مع آلية Rollback منسقة إن فشل أي جهاز.
  • أنماط التثبيت على مرحلتين: تحضير التغييرات على جميع الأجهزة أولاً (المرحلة 1)، ثم تثبيتها في آن واحد (المرحلة 2)، مع Rollback إن فشلت المرحلة 2 على أي جهاز.
  • سجلات المعاملات: تسجيل كل محاولة تغيير بتفاصيل كافية للتراجع عن العمليات الجزئية يدوياً أو تلقائياً.

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

يرتبط هذا المبدأ طبيعياً بـVersioning: حين يسوء الأمر، تحتاج إلى معرفة حالتك بالضبط حتى تتمكن من التراجع إلى إصدار معروف بأنه سليم.

2.2.4. تحكم الإصدارات#

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

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

في هندسة البرمجيات، Version Control System (VCS) كـGit ممارسة معيارية (لم أعمل في أي بيئة بدون شكل من أشكال VCS). تُتيح هذه الأنظمة:

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

تطبيق Versioning على أتمتة الشبكات يوفر فوائد جوهرية:

  • إمكانية التدقيق والتتبع: تتبع من غيّر ماذا ومتى بسهولة، مما يجعل النظام شفافاً.
  • التعاون بين الفرق: يُيسّر مراجعة التغييرات ويُتيح تطوير الأتمتة على مستوى الفريق.
  • Atomic Operation: يمكن تطبيق التغييرات ذات الصلة عبر ملفات متعددة معاً، ما يمنع الحالات الجزئية أو غير المكتملة.
  • تكامل CI/CD: يمكن لخطوط الأنابيب الآلية تشغيل الاختبارات والتحقق تلقائياً حين تُكتشف تغييرات في الكود.

قوالب الإعداد مثال بارز على البيانات التي تستفيد من تحكم الإصدارات. تغيير قالب واحد يؤثر على جميع الإعدادات المشتقة عبر الشبكة، لذا يصبح تحكم الإصدارات أمراً لا غنى عنه. بوجه عام، يجب تخزين جميع البيانات بطريقة مُنسَّخة. من الشائع وجود ملفات YAML أو JavaScript Object Notation (JSON) مُنسَّخة تُنمذج بيانات من أي نوع، أو بيانات ذات علاقات أكثر تعقيداً.

GitOps: نمط ناشئ يأخذ تحكم الإصدارات إلى أبعد من ذلك: يصبح مستودع Git هو مصدر الحقيقة الوحيد، ويقارن متحكم باستمرار Desired State في Git مع Actual State في الشبكة، مُصحِّحاً الانجراف تلقائياً. يكتسب انتشاراً في أتمتة الشبكات، لا سيما في البيئات الأصلية للسحابة والمتكاملة مع Kubernetes.

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

2.2.5. قابلية الاختبار#

لماذا تهم قابلية الاختبار: الأتمتة على نطاق واسع تُضخّم الأخطاء. خطأ في كتيب تشغيل يؤثر على جهاز واحد يمكن السيطرة عليه. نفس الخطأ المُطبَّق على 10,000 جهاز كارثة. الاختبار هو شبكتك الأمان قبل النشر في الإنتاج.

الاختبار في الشبكات أمر صعب بشكل خاص. في الغالب لا تملك الشبكة بأكملها (فكر في تبادلات BGP عبر الإنترنت حيث لا تملك الطرف الآخر)، أو أن الحجم حاجز (تخيّل اختبار نسيج مركز بيانات بآلاف المحولات). إعادة إنتاج سيناريوهات اختبار حقيقية قد يكون شبه مستحيل أو مكلفاً للغاية.

هذا لا يعني أنك بلا خيارات. يمكنك تنفيذ الاختبار على مستويات متعددة تتحقق من سلوك الأتمتة وحالة الشبكة في ظروف متنوعة.

تقدم هرمية الاختبار إطاراً مفيداً:

graph BT
  %% Unit tests (base)
  U1["اختبارات الوحدة<br/>(جودة البيانات، المنطق)"]:::unit

  %% Integration tests
  I1["اختبارات التكامل<br/>(بيئة المحاكاة)"]:::integration

  %% End-to-end tests (top)
  E1["اختبارات شاملة<br/>(المختبر، التحقق)"]:::enduser

  %% Links
  U1 --> I1
  I1 --> E1

  %% Styling
  classDef unit fill:#a6e3a1,stroke:#3b7a57,stroke-width:2px,color:#000;
  classDef integration fill:#89b4fa,stroke:#1e3a8a,stroke-width:2px,color:#000;
  classDef enduser fill:#f9e2af,stroke:#b8860b,stroke-width:2px,color:#000;
  • Unit Test تتحقق من جودة البيانات والمنطق الأساسي وسلوكيات محددة في عزل باستخدام محاكيات أو أنظمة وهمية. تعمل بسرعة وتُمسك بالأخطاء الجوهرية مبكراً.
  • Integration Test تُدخل أنظمة طرف ثالث في بيئة محاكاة (ومُبسَّطة). تتفاعل مكونات الأتمتة المختلفة مع بعضها ومع نكهات شبكات محاكاة، مما يُتيح التحقق من نقاط التكامل (على سبيل المثال، تزوير Application Programming Interface (API) أو واجهة Secure Shell (SSH) Command Line Interface (CLI) لجهاز شبكة).
  • End-to-End Test تتحقق من السلوك في سيناريوهات قريبة من الحقيقية باستخدام بيئات شبكية افتراضية أو مختبرات تحاكي جزءاً من شبكتك الإنتاجية (سنتعمق في هذا الموضوع في الفصل التاسع).

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

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

استراتيجيات الاختبار المتقدمة:

  • هندسة الفوضى: حقن إخفاقات متعمدة (انقطاع أجهزة، تأخير شبكة) للتحقق من أن أتمتتك ومراقبتك تتعاملان معها بسلاسة (نتفليكس رائدت هذا النهج بـChaos Monkey).
  • الاختبار القائم على الخصائص: تحديد خصائص يجب أن تظل صحيحة دائماً (مثلاً، “يجب أن يتقارب BGP دائماً خلال 30 ثانية”) والسماح لأطر الاختبار بتوليد سيناريوهات للتحقق منها.

أخيراً، قبل نشر أي تغييرات، يحتاج المشغّلون إلى رؤية ما سيحدث.

2.2.6. التشغيل التجريبي المناسب#

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

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

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

ثمة أدوات توفر إمكانية Dry Run هذه، لكن يمكنك دائماً بناء أدواتك الخاصة إن لزم الأمر:

  • Ansible: تُظهر علامتا --check و--diff ما الذي كان سيتغير.
  • Terraform: يعرض أمر terraform plan الفرق بين الحالة الراهنة وDesired State.
  • واجهات API الشبكية المخصصة: قد يُعرض بعضها وضع “تجريبي” أو معاينة.

إليك مثالاً على ما تبدو عليه هذه الرؤية:

مخرجات Ansible Diff

- description: Uplink to CoreSwitch1
+ description: Uplink to CoreSwitch2
  mtu: 9216

مخرجات Terraform Plan

~ description = "Uplink to CoreSwitch1" -> "Uplink to CoreSwitch2"
  mtu          = 9216

استجابة معاينة API شبكية مخصصة

{
  "operation": "PATCH",
  "path": "/interfaces/Gi0-1",
  "changes": [
    {
      "field": "description",
      "current_value": "Uplink to CoreSwitch1",
      "proposed_value": "Uplink to CoreSwitch2",
    }
  ],
  "mtu": 9216
}

تحوّل التشغيلات التجريبية الأتمتة من نهج “أتمنى أن ينجح الأمر” إلى عملية متعمدة وقابلة للمراجعة.

مفاهيم متقدمة للتشغيل التجريبي:

  • تحليل الأثر: بعيداً عن إظهار التغييرات، قم بتحليل وإيصال الأثر على الأعمال (مثلاً، “سيؤثر هذا مؤقتاً على 10% من الحركة”).
  • النشر التدريجي: تطبيق التشغيل التجريبي على نطاق واسع بطرح التغييرات تدريجياً على مجموعة فرعية من الأجهزة أولاً، والتحقق من الأثر قبل النشر الكامل.
  • محاكاة الشبكة: دمجه مع أدوات اختبار الشبكات لتنفيذ تشغيلات تجريبية على نسخة طبق الأصل من شبكتك الإنتاجية.

2.3. أنماط القرارات المعمارية#

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

2.3.1. التصريحي مقابل الأمري#

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

  • الأتمتة Declarative تُحدد الحالة النهائية المطلوبة؛ النظام يكتشف كيفية تحقيقها. مثال: “أريد أن يكون MTU الواجهة Gi0/1 مساوياً لـ9000.” تُحدد محرك الأتمتة الحالة الراهنة ويُطبّق التغييرات الضرورية فقط. يركز على ما، النتائج المطلوبة.
  • الأتمتة Imperative تُحدد الخطوات الدقيقة للتنفيذ. مثال: “أظهر إعداد الواجهة، وحلّله، واحسب الفارق، وأرسل هذه الأوامر CLI بالضبط بهذا الترتيب.” يركز على كيف، الإجراءات المحددة.

النهج التصريحي يدعم طبيعياً Idempotency وإمكانيات Dry Run والسلوك Transactional، لكنه يتطلب بنية تحتية وأنظمة تدعمه.

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

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

معظم أطر الأتمتة الحديثة (Terraform، Ansible، Kubernetes، أو الأدوات القائمة على Yet Another Next Generation (YANG)) تتجه نحو النماذج Declarative مع إتاحة الوضع Imperative احتياطياً عند الحاجة (مثلاً، وحدات Ansible الخام، CLI مباشر، Netmiko).

بعض الأدوات كـAnsible يمكنها العمل بكلا الطريقتين تبعاً لنوع الوحدة. الوحدات الخاصة بالشبكات (مثل cisco.ios.ios_interfaces) تصريحية، بينما تُنفّذ ansible.netcommon.cli_command أوامر أمرية. في المثال التالي، سترى كلا النهجين:

- name: Imperative vs. Declarative Approaches in Ansible
  hosts: switches
  gather_facts: no
  vars:
    interface_name: GigabitEthernet0/1
    new_description: Uplink to CoreSwitch2
  tasks:
    - name: Imperative - Execute exact commands
      ansible.netcommon.cli_command:
        command: |
          configure terminal
          interface {{ interface_name }}
          description {{ new_description }}
          no shutdown
          end
      # Repeating this task may add duplicates and fails idempotency

    - name: Declarative - Define desired state
      cisco.ios.ios_interfaces:
        config:
          - name: "{{ interface_name }}"
            description: "{{ new_description }}"
            enabled: true
        state: merged
      # Repeating this task is safe, it converges to the desired state

ضع في اعتبارك أنه مع النهج التصريحي، تُفوّض المنطق إلى نظام خارجي، وفي بعض السيناريوهات قد لا يكون ذلك خياراً متاحاً. لاحظ في المثال السابق كيف تستفيد من وحدة Ansible cisco.ios.ios_interfaces التي تُطبّق المنطق اللازم لتوفير النكهة التصريحية.

النهج التصريحي أكثر أماناً وقابلية للتنبؤ، لكنه يتطلب دعم الوحدة لجهازك المحدد.

2.3.2. البنية التحتية المتغيرة مقابل غير المتغيرة#

المفهوم: هل تسمح بإجراء تعديلات في المكان على البنية التحتية (الشبكة)، أم تستبدل البنية التحتية بالكامل حين تكون التغييرات مطلوبة؟

  • البنية التحتية المتغيرة: النهج التقليدي حيث تتصل بالأجهزة عبر Secure Shell (SSH) وتُعدّل الإعدادات مباشرة (أو تُعدّلها عبر NETCONF أو gNMI أو أي Application Programming Interface (API)). التغييرات تُطبَّق في المكان.
    • إيجابي: أقل تعطيلاً، عبء أقل.
    • سلبي: أصعب تتبعاً للحالة، يزيد من مخاطر Configuration Drift.
  • البنية التحتية غير المتغيرة: لا تُعدّل البنية التحتية الجارية أبداً. بدلاً من ذلك، تبني بنية تحتية جديدة بالتغييرات المطلوبة وتُحوّل الحركة/الاتصالات. تُستخدم بشكل مكثف في السحابة (الحاويات، الأجهزة الافتراضية) لكنها أقل شيوعاً في الشبكات.
    • إيجابي: حالة متوقعة، أسهل في التحقق، يُزيل الانجراف.
    • سلبي: يتطلب تنسيقاً، استعادة أكثر تعقيداً، عبء موارد أعلى.

في أتمتة الشبكات، نحن في الغالب في حالة هجينة: الإعدادات متغيرة (نُعدّلها في المكان)، لكن مبدأ عدم التغيير يجب أن يُوجّه تصميمك: قم بإصدار كل شيء، وتتبع التغييرات، وكن قادراً على إعادة البناء من الصفر عند الحاجة.

2.3.3. البيئات المنشأة حديثاً مقابل البيئات القائمة#

ليس مصطلحاً تقنياً، لكنه مفيد لفهم سيناريوهين مختلفين عند تطوير حلول أتمتة الشبكات:

  • بيئات Brownfield قائمة مع أنظمة قديمة وعمليات يدوية وإعدادات غير متسقة ومعرفة ضمنية. أصعب لأنك تُؤتمت تعقيداً لم يُصمَّم للأتمتة أصلاً: تصاميم غير متسقة، وبيانات مفقودة، وتقنيات قديمة، وعادات بشرية، وقيود حركة المرور الحية. لكنها البيئة الأكثر شيوعاً.
  • بيئات Greenfield مبنية من الصفر بتصميم يضع الأتمتة في المقدمة. يمكنك تطبيق جميع المبادئ بشكل نظيف: تحكم في الإصدارات منذ اليوم الأول، ونوايا تصريحية، ونماذج بيانات نظيفة، واختبار شامل. مثالية لكنها نادرة.

دعونا نتعمق قليلاً في أسباب تعقيد البيئات القائمة…

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

غير أن ثمة أملاً في هذه الحالات. الأساليب الثلاثة التالية تُيسّر البدء في هذه السيناريوهات:

  1. نهج البيئة الجديدة الجزئية: أتمتة البنية التحتية الجديدة مع إعادة الهيكلة التدريجية للأنظمة القديمة. يُظهر هذا تقدماً دون البدء بأقصى تعقيد.
  2. الاختيار التدريجي للأهداف: التركيز على أجزاء الشبكة الأسهل في الأتمتة والتي توفر مكاسب سريعة:
    • إضافة رصد انجراف الإعداد ومعالجته لعدد قليل من ميزات الإدارة (AAA، NTP، SNMP).
    • أتمتة توفير الواجهات لنوع جهاز واحد.
    • توحيد نظام فرعي واحد قبل التوسع.
  3. بناء الزخم: كل مكسب صغير يُثبت قيمة الأتمتة ويبني الثقة للتمويل والتوسع.

2.3.4. تنوع الأجهزة وتجريد الخدمات#

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

نهجان رئيسيان:

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

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

مثال من الواقع: بناء بديل DMVPN يقدم موردو الشبكات DMVPN (Dynamic Multipoint VPN) لقابلية التوسع في VPN من النوع محور-تشعب. البديل هو إعداد نفاقات VPN نقطة إلى نقطة بسيطة عديدة. غير أنه بدون أتمتة هذا مرهق (وهو سبب وجود البروتوكول). إدارة آلاف النفاقات بالأتمتة ممكنة (وليست بالغة التعقيد)، وتوفر قابلية توسع مماثلة من خلال التنسيق بدلاً من تعقيد البروتوكول، إذ تدعم فعلياً جميع المنصات نفاقات VPN الأساسية. لقد استبدلت تبعية البروتوكول بتجريد الأتمتة: في الغالب مقايضة أفضل.

المبدأ الرئيسي: فصل تفاصيل التطبيق (كيفية عمل أجهزة محددة) عن الهدف النهائي الذي تريد تحقيقه. هذا يُتيح الاستقلالية عن الموردين ويبسّط التفكير في نظامك.

2.3.5. مغالطة الأدوات على حساب التصميم#

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

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

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

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

2.3.6. الشراء مقابل البناء#

سؤال استراتيجي شائع: هل تشتري حلاً جاهزاً، أم تبني أتمتة مخصصة، أم تتبع نهجاً هجيناً؟

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

عند تقييم القرار:

  • الشراء: استخدمه حين يُطابق منتج احتياجاتك بشكل وثيق ويدعم معمارتيك ويُرجَّح تحليل التكلفة-الفائدة له.
  • البناء: استخدمه حين تكون متطلباتك فريدة، أو لديك الخبرة، أو لا تُلائم الحلول الجاهزة مبادئك.

هذا في جوهره قرار تصميمي، لا قرار شراء. يتعلق الأمر بمقدار التخصيص والسيطرة التي تحتاجها فعلاً.

في الممارسة، تستخدم معظم المؤسسات نهجاً هجيناً: شراء المكونات الاستراتيجية (منصات التنسيق، أنظمة CI/CD، تخزين البيانات) لكن بناء الأتمتة الخاصة بالنطاق (القوالب، سير العمل، منطق التحقق). يجب أن تمتلك طبقة النطاق الخاصة: الوصفات العامة نادراً ما تحقق النتائج التي تحتاجها.

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

2.3.7. حوكمة الأتمتة#

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

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

الحوكمة في هذا السياق تعني تحديد أربعة أشياء:

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

  • عملية الموافقة على المنطق: التغييرات في منطق الأتمتة (كتيبات تشغيل جديدة، قوالب مُعدَّلة، نماذج بيانات مُحدَّثة في SoT) يجب أن تمر بعملية مراجعة مكافئة لمراجعة كود البرمجيات. الانضباط هنا يُطابق هندسة البرمجيات: التغييرات على كود يعمل في الإنتاج تتطلب مراجعة قبل الوصول إلى الإنتاج. كود الأتمتة لا يختلف عن ذلك.

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

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

الحوكمة ليست بيروقراطية لذاتها. هي الآلية التي من خلالها تُوسّع المؤسسات الثقة في الأتمتة تدريجياً. البدء بعمليات منخفضة المخاطر وقابلة للعكس ومفهومة جيداً وتوسيع النطاق مع اكتساب الأتمتة سجل حافل أكثر فاعلية من إما منع الأتمتة كلياً أو نشرها دون ضوابط.

2.3.8. لماذا تهم هذه المبادئ: التعلم من الإخفاقات#

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

دراسة حالة: انقطاع خدمة Meta

في أكتوبر 2021، شهدت Meta (Facebook سابقاً) انقطاعاً عالمياً للخدمة أوقف أنظمتها لساعات. ما الذي تسبب في ذلك؟ الأتمتة ضخّمت إعداداً خاطئاً. خلال تحويل حركة روتيني، أجرت الأنظمة الآلية تغييرات عالمية استناداً إلى تحقق ناقص من السياسة. تسلسل الإعداد عبر شبكتهم مُحدثاً نقطة فشل واحدة انتشرت عالمياً.

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

  • لا ثبات في نتيجة التكرار: تُطبَّق التغييرات دون فحص الحالة الراهنة.
  • لا تعاملية: بعض الأجهزة حصلت على التغيير والأخرى لم تحصل (إخفاق جزئي).
  • اختبار غير كافٍ: لم يُرصد السيناريو في مرحلة ما قبل الإنتاج.
  • لا إمكانية تشغيل تجريبي: طُبِّقت التغييرات دون معاينة أو تحقق.
  • إصدارات ضعيفة: عدم القدرة على تحديد التغيير الإشكالي والتراجع عنه بسرعة.
  • رصد غير كافٍ: عدم اكتشاف الإخفاق بسرعة كافية.
  • لا تدهور تدريجي: انتشرت التغييرات عالمياً دون احتواء نطاق التأثير.
  • مسؤوليات غير واضحة: لا تسلسل قرار واضح للأتمتة.

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

الدرس: لا تُؤتمت الفوضى آملاً في إصلاحها لاحقاً. بدلاً من ذلك:

  1. ابدأ بعمليات تفهمها ويمكنك التحقق منها.
  2. أتمت تدريجياً، متعلماً من كل خطوة.
  3. عامل كل إخفاق في الأتمتة كفرصة للتعلم.
  4. ادمج ضمانات: حدوداً للمعدل، وآليات تراجع، ورصداً، واحتواءً لنطاق التأثير.
  5. افصل المخاوف حتى لا تنتشر الإخفاقات في منطقة ما عالمياً.

لاحظ كيف يرتبط هذا بنهج الأشخاص والعمليات والتكنولوجيا المُقدَّم في الفصل الأول.

المبادئ التي استكشفناها (Intent-Driven، Idempotency، Transactional، Versioning، قابلية الاختبار، وإمكانية Dry Run) تعالج مباشرة أنماط الإخفاق هذه. إنها ليست ميزات اختيارية؛ إنها ضمانات أساسية يجب بناؤها منذ البداية.

2.4. مبادئ هندسة البرمجيات#

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

لا تحمل جميع الاثنتي عشرة نفس الثقل في هذا المجال. أربعة منها تعالج أنماط إخفاق خاصة بأتمتة البنية التحتية الحرجة: مبدأ أقل قدر من المفاجأة (الأتمتة التي تتصرف بشكل غير متوقع تُدمر الثقة التشغيلية المُرسَّخة في القسم 2.1 قبل أن تترسخ)، البرمجة الدفاعية والمتينة (الشبكات تفشل بطرق جزئية وغير حتمية يجب أن تستبق الأتمتة بالتصميم لا أن تعاملها كاستثناءات)، الفشل السريع والمرئي (الاكتشاف المبكر للإخفاقات يحتوي نطاق التأثير قبل أن يتوسع عبر الأجهزة)، وفصل المخاوف (المبدأ الهيكلي الذي يُجسّده إطار NAF في الفصل الثالث مباشرة - فصل النوايا ومنطق التنفيذ والعرض ليس ممارسة جيدة عامة هنا، بل هو الهيكل المحدد الذي يُبقي الكتل مستقلة قابلة للتطور). المبادئ الثمانية المتبقية هي صحة برمجية معيارية: صحيحة ومهمة وتستحق المعرفة، لكنها ليست السبب الذي يجعل أتمتة الشبكات تنجح أو تفشل تحديداً.

نُنظّمها في فئتين استلهاماً من Robert C. Martin في “Clean Code” و"Clean Architecture":

  • مبادئ الكود النظيف: كيفية كتابة منطق أتمتة مقروء وقابل للصيانة وصحيح.
  • مبادئ المعمارية النظيفة: كيفية هيكلة الأنظمة بحيث تبقى المكونات مستقلة وقابلة للاختبار والتطور.

للتركيز على تطبيقها على أتمتة الشبكات، يمكنك العثور على أمثلة جيدة لهذه المبادئ في سلسلة مدونة Network to Code بقلم Ken Celenza.

2.4.1. مبادئ الكود النظيف#

في هذا القسم، يتمحور التركيز على كيفية بناء مكونات البرمجيات.

اكتب الكود للقراء

الكود الذي تكتبه سيُقرأ مرات عديدة في المستقبل: من قِبلك (عند تصحيح الأخطاء) أو من قِبل الآخرين. ومن المرجح ألا يكون لديهم سياقك الأصلي. عبّر عن نيتك بوضوح في الكود من خلال أسماء ذات معنى وتعليقات وهيكل (من فضلك لا تُفرط في التعليقات؛ استخدمها بعناية). كود الأتمتة ليس مجرد تعليمات للآلات؛ إنه شكل من أشكال التوثيق للبشر.

DRY – لا تُكرر نفسك

تجنب تكرار المنطق عبر قاعدة كود الأتمتة. بدلاً من ذلك، استخرج الأنماط الشائعة في قوالب أو دوال أو سير عمل قابلة لإعادة الاستخدام.

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

حين تنتهك DRY، يتطلب الإصلاح في مكان واحد إصلاحات في خمسة أماكن أخرى، وستُغفل واحداً حتماً.

مبدأ المسؤولية الواحدة (SRP)

يجب أن يكون لكل وحدة أو دالة أو سير عمل سبب واحد للتغيير. في أتمتة الشبكات، هذا يعني:

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

حين تكون لكل مكون مسؤولية واحدة، تُعزل الإخفاقات، ويبسط الاختبار، وتصبح التغييرات أقل مخاطرة. من الواضح سيكون ثمة دالة تركيب (أو تنسيق) لربط هذه الدوال معاً.

الفشل السريع والمرئي

اكتشف المشكلات في أقرب وقت ممكن وأظهرها بوضوح. في الأتمتة:

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

رصد المشكلات مبكراً يقلص نطاق التأثير ووقت الاستجابة.

الأمن

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

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

سنتعمق في اعتبارات الأمن والامتثال في الفصل الثاني عشر.

مبدأ أقل قدر من المفاجأة

يجب أن تتصرف الأتمتة بالطريقة التي يتوقعها المستخدمون. السلوك المفاجئ أو المعاكس للحدس يُآكل الثقة.

على سبيل المثال، إن كانت مهمة أتمتة تُسمى “deploy_interface”، يتوقع المشغّلون أنها ستنشئ واجهة، لا تحذفها. السلوك غير المتوقع يُحبط المستخدمين ويتسبب في أخطاء.

البرمجة الدفاعية والمتينة

ادمج إعادة المحاولات وأنماط Circuit Breaker ومنطق Compensation Logic وآليات الاحتياط. الأنظمة الموزعة تفشل. صمّم لذلك بدلاً من مقاومته. إن كان جهاز غير قابل للوصول مؤقتاً، أعد المحاولة مع تراجع أسي بدلاً من الإخفاق الفوري. إن فشل تغيير في منتصف الطريق، امتلك خطة تراجع.

تظهر هذه الأنماط بشكل ملموس في الفصل السابع (التنسيق)، حيث يعالج نمط تعويض Saga إخفاقات سير العمل الجزئية، وتُبنى منطق إعادة المحاولة/التراجع في وظيفة المرونة.
“كن محافظاً فيما تُرسل، وليبِراً فيما تقبل.” قانون Postel (RFC 761)

في أتمتة الشبكات:

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

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

2.4.2. مبادئ المعمارية النظيفة#

بعد ذلك، نستكشف المبادئ التي تحكم كيفية تجميع مكونات حل أتمتة الشبكات.

KISS – ابقِها بسيطة

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

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

في أتمتة الشبكات، هذا يعني تفضيل النهج Declarative الواضح على السكريبتات الأمرية المعقدة (حين يكون ذلك ممكناً)، وإيلاء الأولوية للوضوح، والمكونات الصغيرة القابلة للتركيب، والسلوك المتوقع، والحلول القابلة للفهم بسهولة من قِبل الآخرين (بما فيهم نفسك في المستقبل).

فصل المخاوف

افصل البيانات (الإعداد) والمنطق (سير العمل) والعرض (واجهات API وواجهات المستخدم) بشكل واضح. هذا يمنع الترابط الوثيق ويُتيح التطور المستقل لكل طبقة.

في أتمتة الشبكات:

  • طبقة البيانات: نوايا الشبكة مُخزَّنة كبيانات منظمة.
  • طبقة المنطق: محركات الأتمتة وقواعد التحقق.
  • طبقة العرض: واجهات API وCLI ولوحات التحكم للمشغّلين.

يُتيح هذا الفصل تغيير طريقة تفاعل المشغّلين مع الأتمتة دون التأثير على المنطق الأساسي. يُطابق هذا الفصل مباشرة كتل NAF البنائية: طبقة البيانات هي Source of Truth (الفصل الرابع)، طبقة المنطق تمتد عبر التنفيذ (الفصل الخامس)، والرصد (الفصل السادس)، والتنسيق (الفصل السابع)، وطبقة العرض هي الفصل الثامن. يُقدّم الفصل الثالث إطار NAF الكامل.

الرصد

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

في الفصل السادس، سنغطي أنواعاً مختلفة من بيانات الرصد التي نهتم بها في الشبكات: المقاييس والسجلات والتتبعات وتدفقات الشبكة والتنبيهات (والمزيد!)، وكيفية الاستفادة منها لتوفير معلومات مفيدة على جميع المستويات.

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

قابلية التوسع

صمّم مع وضع المستقبل في الاعتبار. موردون جدد وتقنيات جديدة ومتطلبات جديدة ستصل. يجب أن تسمح المعمارية بذلك دون الحاجة إلى إعادة كتابة كاملة.

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

الترابط الأدنى، والتماسك الأقصى

حدّد عقوداً واضحة لكيفية تواصل الأنظمة: مخططات وقواعد تحقق وسياسات التوافق مع الإصدارات السابقة. تُتيح هذه العقود التطور المستقل للمكونات.

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

تعامل دائماً مع كل نظام بتصميم API أولاً: صمّم الواجهات البرمجية أولاً (لا التطبيقات). هذا يضمن إمكانية تطوير الأنظمة بشكل مستقل واستبدالها دون كسر المكونات الأخرى.


سنُستكشف هذه المبادئ المتقدمة بعمق أكبر في الفصول اللاحقة حين نناقش توسيع الأتمتة عبر المؤسسات الكبيرة (والأصغر). في الوقت الراهن، افهم أن هذه المبادئ تُكمّل مبادئ التصميم التي استكشفناها سابقاً: معاً، يُشكّلان الأساس لأتمتة شبكات جديرة بالثقة وقابلة للصيانة على نطاق واسع.

2.5. الخلاصة#

أرسى هذا الفصل أن الثقة هي أساس نجاح أتمتة الشبكات. تنبثق الثقة من أربع جودات أساسية: Predictable، وReliable، وUsable، وUnderstandable.

تدعم هذه الجودات ستة مبادئ تصميم أساسية:

  1. مدفوع بالنوايا: حدد ما تريد تحقيقه قبل كيفية تحقيقه.
  2. ثابت النتيجة: التنفيذات المتكررة تُنتج نتائج متسقة.
  3. تعاملي: تكتمل التغييرات بالكامل أو تفشل بأمان، لا بصورة جزئية.
  4. مُعتمَد بإصدارات: تتبع جميع التغييرات مع تاريخ كامل وسجلات تدقيق.
  5. قابل للاختبار: التحقق من السلوك قبل النشر في الإنتاج.
  6. مناسب للتشغيل التجريبي: معاينة التغييرات قبل التنفيذ.

بعيداً عن هذه المبادئ الأساسية، استكشفنا أنماط القرارات المعمارية (التصريحي مقابل الأمري، البيئات الجديدة مقابل القائمة، تجريد الأجهزة) ومبادئ هندسة البرمجيات (الكود النظيف والمعمارية النظيفة) التي تُشغّل هذه الأنماط في الأنظمة الحقيقية.

هذه المبادئ ليست نظرية مجردة: لها تطبيقات ملموسة في الأدوات والأطر التي ستستخدمها. طوال باقي هذا الكتاب، سنرى كيف يُطبّق التفكير المعماري (الفصل الثالث) هذه المبادئ على أنظمة أكبر، وكيف تُشغّلها الكتل البنائية (الفصول 4–9).

الوجبات الرئيسية:

  • ابدأ بالمبادئ لا الأدوات.
  • صمّم لنتائج Predictable، لا للتعقيد.
  • قِس وحسّن باستمرار.

حين تفعل ذلك باتساق، تأتي الثقة بشكل طبيعي، ومع الثقة تأتي القدرة على توسيع الأتمتة عبر مؤسستك بأكملها.

أنت الآن تفهم المبادئ التي تجعل الأتمتة جديرة بالثقة. في الفصل الثالث (التفكير المعماري)، سنرى كيف نهيكل هذه المبادئ في أنظمة قابلة للتوسع. ستتعلم كيف تُصمّم أتمتة تنمو مع مؤسستك دون أن تصبح غير قابلة للإدارة: نظرة معمارية عملية حول كيفية تطبيق المبادئ التي تعلمتها هنا بشكل منهجي.

💬 Found something to improve? Send feedback for this chapter