منصة Kubernetes
منصة Kubernetes
بعد الانتهاء من إعداد الحسابات والشبكة، تُشكّل طبقة Kubernetes المجال الذي تستثمر فيه فرق المنصة أكبر قدر من رأس المال الهندسي. في Google وNetflix وAirbnb وShopify، قرارات بنية الكلاستر التي اتُّخذت في الشهر الأول لا تزال تشتغل—ويُحيَّل إليها مراراً—بعد ثلاث سنوات. يتناول هذا الدرس ثلاثة قرارات بالغة الأهمية على مستوى المؤسسات الكبرى: كيفية هندسة Control Plane، وكيفية تصميم أسطول الـ Nodes، وكيفية رسم خريطة طوبولوجية لبيئات متعددة عبر الكلاسترات.
بنية Control Plane
في الخدمات المُدارة—EKS وGKE وAKS—يكون الـ Control Plane مُدار من قِبل مزود السحابة، لكنه لا يعني انعدام الإعدادات. القرارات التي تبقى بيدك ذات أثر بالغ:
- Endpoint خاص فقط. تستخدم شركات التقنية الكبرى نقاط نهاية API خاصة حصراً للكلاسترات الإنتاجية. لا يمكن الوصول إلى API Server إلا من داخل الـ VPC. يتصل مهندسو CI/CD عبر Bastion أو AWS Systems Manager Session Manager. أي Endpoint عام هو سطح هجوم لا فائدة منه متى توفّر لديك VPN أو سياسة SSM صحيحة.
- دورة إصدارات الكلاستر. يدعم EKS إصدارين فرعيين سابقين؛ تحتاج إلى مسار ترقية مُختبَر كل 14 أسبوعاً. استخدم ترقية Blue/Green للكلاستر—تهيئة نسخة جديدة، نقل الحركة عبر DNS موزون، ثم تصفية النسخة القديمة—بدلاً من الترقية في الموضع. الترقيات في الموضع على الكلاسترات الكبيرة تُظهر باستمرار Admission Webhooks غير متوافقة وAPIs مهجورة.
- إدارة الإضافات عبر IaC. كل إضافة جوهرية—CoreDNS وkube-proxy وVPC CNI وcluster autoscaler وcert-manager وexternal-dns—يجب إدارتها من خلال طبقة IaC، وليس بأوامر
kubectl applyالمتفرقة. الإضافات غير المُدارة تنحرف عن حالتها المطلوبة في غضون أسابيع.
kubectl delete events --all -A وراقب تضخم تخزين CRD.
استراتيجية الـ Nodes: تركيبة الأسطول
تعامل مع اختيار الـ Nodes باعتباره مسألة تحسين بين التكلفة والأداء، لا مجرد توفير سعة. الهدف هو تقليل إجمالي ساعات vCPU المستهلكة لإنتاجية عمل معطاة. يُرتِّب تصميم أسطول الإنتاج عادةً طبقات متعددة من الـ Nodes:
- General Purpose (m6i, n2-standard): منطقة الهبوط الافتراضية للخدمات الدقيقة المتنوعة. النسبة 4:1 بين الذاكرة والمعالج تناسب معظم الـ Pods. استخدمها كقاعدة on-demand يهيئها Karpenter أولاً.
- Compute-Optimised (c6i, c2-standard): بوابات API المرهِقة للمعالج، إنهاء TLS، المهام الدُفعية كثيفة الضغط. يتجنب دفع تكلفة ذاكرة لن تُستخدم.
- Memory-Optimised (r6i, m1-ultramem): الخدمات الثقيلة على JVM، وسطاء Kafka داخل الكلاستر، ذاكرة التحليلات الـ In-Memory.
- Spot / Preemptible: الأحمال عديمة الحالة ومجموعات مشغّلات CI—توفير يصل إلى 80%. اقرن Nodes الـ Spot بـ
PodDisruptionBudgetوtopologySpreadConstraintsلمنع استرداد الـ Spot من إخلاء جميع النسخ في آنٍ واحد.
Node Groups المُدارة مقابل Karpenter. Node Groups المُدارة متوقعة لكنها بطيئة: 2-3 دقائق لتهيئة Node جديد. يهيئ Karpenter Nodes في نحو 30 ثانية باستدعاء EC2 API مباشرةً. تقوم خوارزمية الدمج (Consolidation) بتصغير حجم الـ Nodes الأقل استخداماً، موفّرةً 15-25% من تكلفة الحوسبة دون أي تحسين يدوي.
طوبولوجيا البيئات المتعددة
تتقارب فرق المنصة في شركات التقنية الكبرى نحو أحد نمطين للبيئات المتعددة:
النمط أ — كلاستر لكل بيئة. كلاسترات منفصلة لـ dev وstaging وprod. هذا هو النمط السائد في الشركات ذات المتطلبات الأمنية الصارمة (SOC2، PCI-DSS، HIPAA). عزل نطاق الضرر يكون في أقصى درجاته؛ إعداد RBAC خاطئ أو Operator مارق في بيئة dev لا يمكنه لمس الإنتاج. التكلفة هي العبء التشغيلي: ثلاث دورات ترقية للكلاستر، وثلاث مجموعات إضافات للصيانة.
النمط ب — عزل بالـ Namespace داخل كلاستر واحد. بيئات متعددة تتشارك كلاستراً واحداً، مفصولة بـ Namespaces وNetworkPolicy. هذا ممكن لبيئات dev وstaging، لكن أحمال الإنتاج التي تعالج بيانات العملاء أو المدفوعات يجب أن تعيش في كلاستر مخصص بسبب المتطلبات التنظيمية.
الطوبولوجيا المعيارية لفريق مكوّن من 10-50 مهندساً هي هجينة: كلاستر الخدمات المشتركة (أدوات داخلية، مشغّلات CI، مكدس المراقبة، ArgoCD)، وكلاستر غير الإنتاج (dev + staging بعزل Namespace)، وكلاستر إنتاج واحد أو أكثر (واحد لكل منطقة).
platform-shared-use1 وworkloads-nonprod-use1 وworkloads-prod-use1. الكلاسترات المُسمّاة بالإصدار (eks-v127-prod) تخلق ارتباكاً خلال ترقيات Blue/Green حين تتواجد كلتا النسختين في kubeconfig في آنٍ واحد.
عزل الأحمال: Taints وTopology Spread
Node Pools وحدها لا تكفي. داخل الكلاستر، يجب التحكم في أي Pods تهبط على أي Nodes وكيف تنتشر عبر نطاقات الفشل. تعمل ثلاثة عناصر أولية معاً:
- Taints + Tolerations — إبعاد الأحمال عن Nodes غير المُهيَّأة لها (مثال GPU Pool أعلاه).
- Node Affinity — قواعد ناعمة أو صارمة لتوجيه Pods نحو فئات Node معينة.
- TopologySpreadConstraints — العنصر الأكثر إهمالاً في الإنتاج. يضمن قيد
maxSkew: 1عبرtopology.kubernetes.io/zoneتوزيع النسخ على مناطق التوفر. بدونه، يضع المُجدوِل الافتراضي Pods على Nodes المتاحة وقد تنتهي جميع النسخ في منطقة توفر واحدة—مما يجعل الخدمة غير متاحة عند فشل منطقة.
limits.cpu: 500m سيُقنَّن عندما يرتفع الحِمل إلى 600m بغض النظر عن حِمل الـ Node—يظهر هذا على شكل ارتفاع في زمن الاستجابة يصعب تشخيصه. ضع requests للـ CPU لأغراض الجدولة واترك الـ Pod يزيد استهلاكه بحرية. ضع حدوداً للذاكرة فقط لأن الذاكرة غير قابلة للضغط.
التحجيم التلقائي: VPA وHPA وKEDA
تستخدم كلاسترات المؤسسات الكبرى الأدوات الثلاثة لأغراض مختلفة؛ فهي ليست بدائل لبعضها بل تكاملية:
- HPA: تحجيم النسخ بناءً على CPU أو الذاكرة أو مقاييس مخصصة. المعيار للخدمات عديمة الحالة. استهدف 65-70% استخدام CPU؛ الاستهداف الأعلى يسبب تذبذباً في ظل حركة مرور متقطعة.
- VPA: يعمل في وضع التوصية فقط في الإنتاج. لا تُفعِّل التطبيق التلقائي؛ فهو يُخلي Pods لإعادة تحجيمها. استخدم توصيات VPA لتحديث طلبات الموارد الثابتة في دورة النشر التالية.
- KEDA: التحجيم بناءً على مصادر أحداث خارجية: عمق قائمة انتظار SQS، تأخر مستهلك Kafka، نتائج استعلام Prometheus. لا غنى عنه للأحمال غير المتزامنة حيث لا تعكس CPU والذاكرة الحِمل الفعلي.
--horizontal-pod-autoscaler-initial-readiness-delay=30s و--horizontal-pod-autoscaler-cpu-initialization-period=5m في إعدادات Controller Manager. بدون ذلك، يحتسب HPA Pods المُشغَّلة حديثاً—التي لم تُدفّئ بعد JVM أو connection pools الخاصة بها—كأحمال منخفضة ويُقلِّص الحجم مبكراً ثم يعود فيوسّعه، مسبّباً حلقة تذبذب تظهر كـ 503s دورية.