حاوياتنا كانت أسطولاً ضائعاً: كيف أنقذنا Kubernetes من جحيم التنسيق اليدوي؟

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

كانت الساعة حوالي 2 بعد منتصف الليل، وأنا قاعد بشتغل على مشروع ذكاء اصطناعي جديد. فجأة، التلفون برنّ، وصوت زميلي محمد على الخط كله توتر: “أبو عمر الحقنا! الموقع واقع!”. الموقع كان عبارة عن منصة تجارة إلكترونية كبيرة، ووقت الذروة تبعها كان بلّش. طيران فتحت اللابتوب، ويا ريتني ما فتحت. السيرفرات عليها عشرات الحاويات (Docker containers)، بعضها شغال، بعضها معلّق، وبعضها “ميت” تمامًا. كنا زي اللي بحاول يطفي حريقة بكاسة مي. أنا بدخل على سيرفر أحاول أعيد تشغيل حاوية يدوياً، ومحمد على سيرفر ثاني، والتطبيق لسا مش راضي يقوم. كل ما نصلح إشي، إشي ثاني يخرب. كانت فوضى عارمة، أو زي ما بنحكي “جحيم التنسيق اليدوي”.

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

ما قبل العاصفة: عالم الحاويات بدون قائد

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

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

  • المراقبة اليدوية: كيف بدك تعرف أي حاوية توقفت عن العمل؟ بدك تضلّك عامل `docker ps` على كل سيرفر؟
  • التحديثات المعقدة: بدك تحدث نسخة التطبيق؟ لازم توقف الحاوية القديمة، تشغل الجديدة، وتدعي ربنا إنه كل شي يشتغل صح، وهذا لكل نسخة من التطبيق على كل سيرفر.
  • التوسّع (Scaling): صار عندك ضغط على الموقع؟ لازم تدخل على السيرفرات وتشغل نسخ جديدة من الحاويات يدويًا. راح الضغط؟ لازم تطفيها يدويًا عشان توفر موارد.
  • الشبكات: كيف الحاويات اللي على سيرفرات مختلفة بدها تحكي مع بعضها؟ بدك إعدادات شبكات معقدة ومؤلمة.
  • الكارثة الكبرى: لو سيرفر كامل “وقع”؟ كل الحاويات اللي عليه راحت. لازم تنقلها وتشغلها على سيرفر ثاني يدويًا، وهذا إذا انتبهت أصلاً!

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

دخول القبطان: تقديم Kubernetes كحل منقذ

هون بيجي دور البطل، Kubernetes (أو اختصارًا K8s). تخيّل Kubernetes وكأنه القبطان الخبير أو قائد الأسطول اللي حكينا عنه. أنت ما بتحكيله “شغّل هاي الحاوية على هداك السيرفر”، لا. أنت بتعطيه “الأوامر العليا” وهو بتكفّل بالباقي.

المبدأ الأساسي في Kubernetes هو “الحالة المطلوبة” (Desired State). أنت بتوصف الحالة اللي بدك نظامك يكون عليها من خلال ملفات إعدادات (عادة بصيغة YAML)، وكوبرنيتز بشتغل ليل نهار عشان يضمن إنه “الحالة الحالية” (Current State) للنظام مطابقة للحالة اللي أنت طلبتها.

نصيحة من أبو عمر: فكّر في Kubernetes كـ “مثبّت سرعة” لتطبيقاتك. أنت بتحدد السرعة (الحالة المطلوبة)، وهو بيضغط بنزين أو بخفف عشان يحافظ عليها، بغض النظر عن الطلعات والنزلات (المشاكل والأعطال).

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

تشريح الوحش: أهم مفاهيم Kubernetes للمبتدئين

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

الـ Pods: أصغر وحدة في أسطولنا

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

الـ Deployments: مهندس التوسّع والتحديثات

هذا هو المكوّن اللي رح تتعامل معه معظم الوقت. الـ Deployment هو المسؤول عن إدارة الـ Pods. أنت بتحكي للـ Deployment: “يا معلم، بدي 3 نسخ (replicas) من تطبيق الويب تبعي شغّالة دائمًا”.

الـ Deployment بيقوم بإنشاء 3 Pods. لو واحد منهم تعطل أو انحذف، الـ Deployment فورًا بينتبه وبعمل واحد جديد بداله عشان يرجع “للحالة المطلوبة” (3 نسخ شغالة). بدك تحدث التطبيق؟ بتعطي للـ Deployment نسخة الكود الجديدة، وهو بقوم بالتحديث بشكل تدريجي (Rolling Update) بدون ما يتوقف الموقع.

مثال عملي: ملف `deployment.yaml` بسيط


apiVersion: apps/v1
kind: Deployment
metadata:
  name: abu-omar-app-deployment
spec:
  replicas: 3 # السر كله هون: بطلب 3 نسخ شغالة على طول
  selector:
    matchLabels:
      app: abu-omar-app
  template:
    metadata:
      labels:
        app: abu-omar-app
    spec:
      containers:
      - name: web-server
        image: nginx:1.21.6 # صورة الحاوية اللي بدنا نشغلها
        ports:
        - containerPort: 80

بمجرد تطبيق هذا الملف، كوبرنيتز رح يضمن وجود 3 Pods من نوع NGINX شغالة دائمًا.

الـ Services: العنوان الثابت في بحر متغير

مشكلة الـ Pods إنها مؤقتة. لما Pod يموت ويجي واحد جديد، بياخد عنوان IP جديد. طيب كيف باقي أجزاء التطبيق أو المستخدمين بدهم يوصلوا له؟

هون بيجي دور الـ Service. الـ Service هو عبارة عن عنوان ثابت (IP واسم DNS ثابت داخل الكلستر) بيوجّه الطلبات للـ Pods الصحيحة. هو زي موظف الاستقبال في فندق كبير، بعرف وين غرف النزلاء (الـ Pods) حتى لو غيروا غرفهم، ويوجه الزوار إلهم.

مثال عملي: ملف `service.yaml`


apiVersion: v1
kind: Service
metadata:
  name: abu-omar-app-service
spec:
  selector:
    app: abu-omar-app # هون بنربط الـ Service مع الـ Pods اللي عليها هذا الـ label
  ports:
    - protocol: TCP
      port: 80       # البورت اللي بيستقبل عليه الـ Service
      targetPort: 80 # البورت اللي بيوجه عليه الطلب داخل الـ Pod
  type: LoadBalancer # هذا النوع بيعطينا IP خارجي يمكن الوصول إليه من الإنترنت

هذا الـ Service رح يوزع الطلبات اللي بتيجي على البورت 80 بين الـ 3 Pods اللي أنشأها الـ Deployment تبعنا.

الـ Nodes والـ Cluster: أرض المعركة

  • الـ Node: هو ببساطة سيرفر (حقيقي أو افتراضي) يعمل كعامل في نظام كوبرنيتز. هو المكان الفعلي اللي بتشتغل عليه الـ Pods.
  • الـ Cluster: هو مجموعة من الـ Nodes (عمال) اللي بيتحكم فيهم “العقل المدبر” أو الـ Control Plane. الأسطول البحري بأكمله.

من النظرية إلى التطبيق: كيف أنقذنا Kubernetes بالفعل؟

بعد ما تبنينا Kubernetes، حياتنا كفريق DevOps تغيرت 180 درجة. المشاكل اللي كانت تسبب لنا أزمات ليلية، صارت كوبرنيتز تتعامل معها بهدوء في الخلفية:

التعافي التلقائي (Self-Healing): لا مزيد من السهر ليلاً

أجمل ميزة في كوبرنيتز. لو حاوية داخل Pod توقفت عن الاستجابة، كوبرنيتز بيعيد تشغيلها. لو Pod كامل فشل، الـ Deployment بينشئ واحد بداله. لو Node (سيرفر) كامل انهار، كوبرنيتز تلقائيًا بنقل كل الـ Pods اللي كانت عليه لـ Nodes أخرى سليمة. صار النظام يصلح نفسه بنفسه!

نصيحة ذهبية من أبو عمر: عشان خاصية التعافي التلقائي تشتغل صح، لازم تستخدم `Liveness and Readiness Probes`. الـ Liveness Probe بيحكي لكوبرنيتز إذا الحاوية “ميتة” وبتحتاج إعادة تشغيل. الـ Readiness Probe بيحكي له إذا الحاوية جاهزة لاستقبال طلبات جديدة. بدونهم، كوبرنيتز ممكن يرسل طلبات لتطبيق معلّق أو يعيد تشغيل تطبيق سليم.

التوسّع الأفقي بضغطة زر (Horizontal Scaling)

تتذكروا كيف كنا بنضيف حاويات يدوياً وقت الضغط؟ الآن، كل اللي بنحتاجه هو أمر واحد بسيط:


# زيادة عدد النسخ من 3 إلى 10
kubectl scale deployment abu-omar-app-deployment --replicas=10

والأفضل من هيك، باستخدام (Horizontal Pod Autoscaler – HPA)، ممكن نخلي كوبرنيتز يعمل هذا الشي تلقائيًا. بنحكيله: “إذا زاد استهلاك المعالج (CPU) عن 70%، زيد عدد الـ Pods تلقائيًا”.

التحديثات بدون توقف (Zero-Downtime Deployments)

عملية تحديث التطبيق صارت سلسة وآمنة. لما نحدّث الـ image في ملف الـ Deployment، كوبرنيتز بستخدم استراتيجية الـ Rolling Update. بيقوم بإنشاء Pod جديد بالنسخة الجديدة، ينتظر حتى يصير جاهز، ثم يوجه الطلبات إليه، وبعدها يحذف Pod قديم. يكرر العملية هاي حتى يتم تحديث كل الـ Pods. النتيجة؟ المستخدم النهائي ما بحس بأي انقطاع في الخدمة أثناء التحديث.

خلاصة الكلام والنصيحة الأخيرة 💡

التحول إلى Kubernetes ما كان مجرد تغيير تقني، بل كان تغيير في طريقة تفكيرنا وعملنا. نقلنا من حالة رد الفعل وإطفاء الحرائق، إلى حالة الفعل والتخطيط الاستباقي. أعطانا الثقة لنبني أنظمة أكبر وأكثر تعقيدًا ونحن نعلم أن لدينا “قبطان” قوي يدير الأسطول بكفاءة.

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

نصيحة أبو عمر النهائية لكم:

لا تحاول تبني كل شي من الصفر في أول يوم. ابدأ صغيرًا. أفضل طريقة للبدء هي استخدام خدمات Kubernetes المُدارة من الشركات الكبرى (مثل Google Kubernetes Engine – GKE، أو Amazon EKS، أو Azure AKS). هاي الخدمات بتريحك من صداع إدارة الـ Control Plane المعقد، وبتخليك تركز على تعلم المفاهيم الأساسية: Pods, Deployments, Services.

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

يلا يا جماعة، شدوا حيلكم. عالم الحاويات والتطبيقات الحديثة بستناكم، ومع قبطان مثل Kubernetes، رحلتكم بتكون آمنة وممتعة. سلام!

أبو عمر

سجل دخولك لعمل نقاش تفاعلي

كافة المحادثات خاصة ولا يتم عرضها على الموقع نهائياً

آراء من النقاشات

لا توجد آراء منشورة بعد. كن أول من يشارك رأيه!

آخر المدونات

أتمتة العمليات

بيئتنا التجريبية كانت شبحاً: كيف أنقذتنا ‘البنية التحتية كشيفرة’ (IaC) من جحيم ‘لكنها تعمل على جهازي’؟

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

11 أبريل، 2026 قراءة المزيد
نصائح برمجية

بياناتي كانت تتغير بشكل غامض: كيف أنقذتنا ‘اللامتغيرية’ (Immutability) من جحيم الآثار الجانبية الخفية؟

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

11 أبريل، 2026 قراءة المزيد
البودكاست