Kubernetes · موثوقية الجدولة

توزيع Kubernetes عبر المناطق: صمّم لفشل Zone لا لمتوسط جميل

دليل إنتاجي لـTopology Spread وmaxSkew وminDomains وAffinity وTaints وAutoscaling وجدولة Kubernetes المقاومة لفشل المناطق.

المسار المرتبطالسحابة وDevOps وKubernetes
رسم تحريري تصوري لستة أحمال موزعة على ثلاث Zones، مع منطقة متوقفة ومنطقتين مستمرتين؛ وليس واجهة Kubernetes.
تصوّر بصري للفكرة — يتبعه شرح ومخطط تنفيذي داخل المقال.

لا تتحقق موثوقية Kubernetes متعددة المناطق بمجرد إضافة ثلاث Replicas والأمل أن يفصلها الـScheduler. حدّد Nodes المؤهلة، ووزّع Pods المتطابقة بين Zones وHosts، وقرر هل يجب أن يمنع نقص المناطق Placement، واحجز سعة لفقدان Zone، ثم اختبر الفشل. Topology Spread Constraints هي الأداة المناسبة عندما تريد تفاوتًا محدودًا مثل 2-2-1؛ أما Anti-affinity فتناسب قاعدة صارمة مثل نسخة واحدة لكل Domain. ولا تستبدل أي منهما تكرار التطبيق أوتكرار البيانات أوTraffic Health Checks أوDisruption Budget.

تم التحقق من وثائق Kubernetes الرسمية المشار إليها في 6 أكتوبر 2026. سلوك الحقول حقيقة موثقة؛ أما حدود الإطلاق ونموذج السعة وتمارين الفشل أدناه فهي توصيات هندسية.

ابدأ من الفشل الذي يجب أن تنجو منه

Topology Domain هي مجموعة Nodes تشترك في قيمة Label، وغالبًا `topology.kubernetes.io/zone` أو`kubernetes.io/hostname`. لا يستطيع Scheduler استنتاج Failure Domains التجارية من عدد Replicas. إذا كانت النسخ الثلاث مؤهلة لـNode كبيرة واحدة فقد يضعها Cluster السليم معًا، ويزيل فشل Node الخدمة كلها.

اكتب Availability Contract أولًا: يجب ألا يزيل فشل Node كل النسخ الخادمة؛ ويجب أن تتحمل الخدمة فقد Zone مع قدرة المناطق الباقية على حمل Traffic المطلوبة؛ ويجب ألا يجمع Rolling Update النسخ السليمة في Zone واحدة؛ ويجب ألا ينتظر Scale-up إلى الأبد Domain لا يمكن إنشاؤها. هذه ضمانات مختلفة تحتاج قيودًا وسعة مختلفة.

تصف وثائق Kubernetes لتوزيع Pods الحقل `spec.topologySpreadConstraints` كطريقة لضبط توزيع Pods على Failure Domains. وتذكر حدًا مهمًا: يضع Scheduler Pods القادمة، لكن Scale-down أوتغير Nodes لاحقًا قد يترك التوزيع غير متوازن. سياسة الجدولة ليست Rebalancer مستمرًا.

ابنِ مجموعة Nodes المؤهلة قبل حساب Skew

يحتاج Scheduler أولًا مجموعة مرشحين صحيحة. استخدم Node Affinity لمتطلبات مثل Architecture أوCompliance Tier أوNode Pool مخصصة. واستخدم Taints وTolerations لإبعاد الأحمال العامة عن Nodes متخصصة. Toleration تسمح بالجدولة على Node عليها Taint لكنها لا تفرضها.

بعد تحديد الأهلية، يحسب Topology Spread عدد Pods المطابقة في كل Domain مؤهلة. إذا كان الحمل مسموحًا في A وB فقط، فإدخال C في الحساب يصنع حدًا أدنى مضللًا. تجعل `nodeAffinityPolicy: Honor` الحساب يحترم Node Affinity أوSelectors. وتجعل `nodeTaintsPolicy: Honor` الحساب يشمل Nodes بلا Taints أوذات Taints تتحملها Pod القادمة. توثق Kubernetes أن السياستين أصبحتا GA منذ v1.33.

حافظ على Labels متسقة. غياب `topology.kubernetes.io/zone` يجعل Node غير ظاهرة لذلك القيد، وقد تختلف دلالة Label خاصة بين البيئات. افحص Labels أثناء Provisioning لا بعد حادث Placement.

افهم maxSkew وminDomains بدقة

تحد `maxSkew` الفرق بين عدد Pods المطابقة والحد الأدنى العام. توزيع 2 و2 و1 عبر ثلاث Zones يحقق `maxSkew: 1`. أما 3 و1 و1 فـSkew يساوي 2، ويرفض القيد الصارم Placement جديدة تبقي هذا التفاوت.

تحدد `minDomains` الحد الأدنى لعدد Domains المؤهلة قبل تطبيق الحد الأدنى العادي. عندما يوجد أقل منها تعامل Kubernetes الحد الأدنى العام كصفر. لذلك قد يؤدي فقد Zone مع `minDomains: 3` إلى جعل `DoNotSchedule` تمنع Pods جديدة تتجاوز Skew المسموح. قد يحمي ذلك عقد التوزيع، لكنه قد يوقف التعافي أثناء Incident.

اختر السلوك من Service Objective. استخدم `DoNotSchedule` لأنظمة حساسة لـQuorum حيث تكديس النسخ يصنع خطرًا أسوأ. واستخدم `ScheduleAnyway` لواجهات Stateless يجب أن تستمر في Topology متدهورة؛ يفضل Scheduler المنطقة الأقل ازدحامًا لكنه يستطيع الجدولة في غيرها عند نقص السعة. سياسة صارمة بلا Spare Capacity غالبًا تحول حادث Zone إلى Pods في Pending بدل المرونة.

تجمع الجدولة الموثوقة بين مجموعة Nodes مؤهلة، وقيود توزيع على Zone وHost، وسعة احتياطية، وسياسة Disruption، وتمارين فشل؛ فالـScheduler يضع Pods الجديدة ولا يعيد موازنة القديمة باستمرار.
تجمع الجدولة الموثوقة بين مجموعة Nodes مؤهلة، وقيود توزيع على Zone وHost، وسعة احتياطية، وسياسة Disruption، وتمارين فشل؛ فالـScheduler يضع Pods الجديدة ولا يعيد موازنة القديمة باستمرار. اضغط لعرض أكبر

نمط Deployment إنتاجي

يوزع المثال التالي Deployment بين Zones ثم Hosts. قاعدة Zone صارمة، بينما قاعدة Host مفضلة كيلا تعلق Cluster صغيرة. يجب أن يطابق Selector Labels الخاصة بـPod نفسها؛ وإلا تحذر Kubernetes من "Ghost Pods" لا تحسب نفسها.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: checkout
spec:
  replicas: 6
  selector:
    matchLabels:
      app: checkout
  template:
    metadata:
      labels:
        app: checkout
    spec:
      topologySpreadConstraints:
        - maxSkew: 1
          minDomains: 3
          topologyKey: topology.kubernetes.io/zone
          whenUnsatisfiable: DoNotSchedule
          labelSelector:
            matchLabels:
              app: checkout
          matchLabelKeys:
            - pod-template-hash
          nodeAffinityPolicy: Honor
          nodeTaintsPolicy: Honor
        - maxSkew: 1
          topologyKey: kubernetes.io/hostname
          whenUnsatisfiable: ScheduleAnyway
          labelSelector:
            matchLabels:
              app: checkout
      containers:
        - name: app
          image: registry.example.com/checkout@sha256:<reviewed-digest>
          resources:
            requests:
              cpu: 500m
              memory: 512Mi

تفصل `matchLabelKeys: [pod-template-hash]` إصدارات Deployment في حساب التوزيع حتى لا يدمج Rolling Update الـReplicaSets القديمة والجديدة كمجموعة واحدة. تذكر الوثائق أنه منذ v1.34 تدمج القيم المطابقة صراحة في Selector. تحقق من السلوك في إصدار Kubernetes لديك.

لا تنسخ `minDomains: 3` إلى Cluster من منطقتين. ولا تجعل قيدي Zone وHostname صارمين قبل نمذجة كل Replica Count وRollout Surge وحدود Node Pool. تُجمع القيود المتعددة بمنطق AND، وقد يكون تقاطعها فارغًا رغم أن كل قيد يبدو معقولًا منفردًا.

السعة جزء من عقد الجدولة

ينجو توزيع 2-2-2 من فقد Zone فقط إذا استطاعت المناطق الباقية تشغيل النسخ المزاحة أوإذا كانت أربع Replicas كافية لهدف الخدمة. تقود Requests قرار Scheduler؛ Requests المبالغ فيها تجعل العقد مستحيلًا، والمنخفضة جدًا تسمح بPlacement ثم يحدث Throttling أوOOM. يغطي دليل Kubernetes Requests وLimits هذه الطبقة.

نمذج N-1 Capacity صراحة. لكل Workload حرجة سجل الحد الأدنى للنسخ الخادمة بعد فقد Zone، والسعة الاحتياطية المطلوبة، وأقصى Pending مقبول، وزمن استجابة Autoscaler. إذا كان Node Group يستطيع Scale to Zero في Domain، توثق Kubernetes أن Scheduler قد لا يعرف أن Domain موجودة حتى تظهر Node واحدة. استخدم Autoscaler واعيًا بـTopology Spread أواحتفظ بحد أدنى في المناطق المطلوبة.

تضيف Pod Scheduling Readiness بوابات تبقي Pod خارج محاولات الجدولة حتى يزيل Controller خارجي Gate. تقدمها الوثائق الرسمية كطريقة لتجنب محاولات غير ضرورية. تفيد في Placement منسقة، لكن تعطل Controller يحولها إلى Pending دائم، لذلك راقب Gate Age والمالك.

أفضل الممارسات والأنماط المضادة

فضّل Topology Spread على Required Pod Anti-affinity عندما يكون المطلوب توزيعًا محدود التفاوت لا نسخة واحدة بالضبط لكل Domain. Required Anti-affinity على Hostname مع Replicas أكثر من Nodes تضمن Pending. تستطيع Spread Constraints التعبير عن Skew مقبول والجمع بين هدف Zone وHost.

اجعل Selector ضيقًا ليمثل Failure Unit واحدة. لا تحسب تطبيقات غير مرتبطة معًا لأنها تشترك في Label عامة. حافظ على القيود نفسها لكل Pods في المجموعة، واستخدم Admission Policy أومكتبة Workload لمنع Drift.

تجنب التناقضات المخفية: Node Selector لمنطقة واحدة مع `minDomains: 3`؛ أوToleration تغير Nodes الداخلة في الحساب؛ أوقاعدة Zone صارمة مع Volume في Zone واحدة؛ أوDeployment Surge يحتاج Slots أكثر من المتاح. افحص Scheduler Events وDomains المؤهلة بدقة قبل إرخاء السياسة.

لا تستخدم `ScheduleAnyway` ثم تسمي النتيجة High Availability مضمونة؛ إنها Preference. ولا تستخدم `DoNotSchedule` بلا خطة Incident لـPending Replicas. ولا تفترض استمرار التوازن بعد Scale-down؛ إذا كانت إعادة الموازنة مهمة فاستخدم عملية تشغيلية معتمدة وأدوات تراعي Disruptions.

اختبر الضمان لا Manifest فقط

في Staging سجل أعداد Pods حسب Zone وNode. نفذ Cordon وDrain لـNode، ثم تحقق من Replacement Placement وصحة الخدمة وRollout. بعد ذلك حاكِ Zone غير متاحة أوأزل سعتها المؤهلة. تأكد هل القيود الصارمة تنتج Pending متوقعة أوهل سياسة Degraded Placement تبقي الخدمة.

اختبر Replica Counts أقل من عدد Zones ومساوية له وأكبر منه. اختبر Rolling Update مع `maxSurge`، وHPA Scale-up، وتأخر Cluster Autoscaler، وNode Pool عليها Taint. تحقق أن Selector يطابق Pods وأن Node Labels صحيحة. أنشئ Alerts على Unschedulable Pods حسب السبب، وعدم توازن Topology، وعدد Domains المؤهلة، وGate Age، وCapacity Headroom.

اربط اختبارات الجدولة بـReadiness وGraceful Termination وDisruption Budgets. يشرح دليل Kubernetes Rollout الآمن كيف تحدد هذه الضوابط هل تخدم Pod الموضوعة بصورة صحيحة وتخرج بأمان. Placement تحمي من فقد بنية مترابط؛ وReadiness وDraining تحمي Traffic أثناء التغيير.

متى لا تستخدم Topology Spread

لا تكسب خدمة Development بنسخة واحدة Availability بين Zones من هذا القيد. ولا يصبح Workload مربوطًا بـZonal Disk متعدد المناطق بمجرد Scheduler Configuration. وقد تحتاج قاعدة بيانات تديرها Consensus Operator إلى قواعد Placement يملكها Operator لاDeployment عام. وفي Clusters الصغيرة قد تكون قاعدة Preferred مع Degraded Mode واضح أكثر أمانًا من Strict Policy تعطل كل Deploy.

إذا كان المطلوب Co-location لخفض Latency فاستخدم Pod Affinity. وإذا كان المطلوب أهلية Hardware أوCompliance فاستخدم Node Affinity وTaints. وإذا كان المطلوب نسخة واحدة على كل Node فاستخدم Required Anti-affinity أوDaemonSet. Topology Spread ممتازة عندما يكون المطلوب توزيعًا قابلًا للقياس عبر Failure Domains.

قرار الإنتاج

عامل الجدولة كعقد Availability: حدد Nodes المؤهلة، واختر Topology Domains، واضبط Skew مبررًا، وقرر سلوك Topology المتدهورة، واحجز N-1 Capacity، واختبر الفشل. الهدف ليس Dashboard متوازنة؛ بل استمرار الخدمة الصحيحة بعد فقد Node أوZone.

ابدأ بـPreferred Spread على Hostname وقاعدة Zone مختبرة بعناية. لا تجعل قاعدة Zone صارمة إلا عندما يستطيع Workload والتخزين والسعة احترامها أثناء Rollouts والأعطال. واربط السياسة بـهندسة السحابة والنشر حتى يطبق Node Provisioning وAutoscaling وObservability وIncident Response العقد نفسه.

المراجع الرسمية

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

إعداد: Noor Yasser

من القرار إلى التنفيذ

تعمل على تحدٍ تقني مشابه؟

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

احجز لقاءً لمدة ٣٠ دقيقةالخدمة المرتبطةتحسين الأداء والبنية السحابية والنشرمشروع من الأعمالمنصة اللوجستيات