Kubernetes · Control-plane reliability

Kubernetes API Priority and Fairness: اعزل الـControllers المزعجة

تصميم عملي لـAPF يحمي kube-apiserver من اندفاعات Controllers وOperators ووكلاء AI من دون تجويع الطلبات الحرجة.

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

قد تكون Control Plane في Kubernetes سليمة عند مستوى Nodes وPods بينما يقترب API Server من التوقف الفعلي. قد يعيد Operator فيه خلل سرد آلاف Objects، أوينفذ Deployment Controller محاولات سريعة أثناء عطل، أو تنشئ مجموعة من وكلاء AI وظائف قصيرة وتراقب Resources كثيرة في الوقت نفسه. لا تحمي CPU Limits الخاصة بهذه Pods خدمة `kube-apiserver`؛ المورد النادر هنا هو API-server concurrency.

تمثل API Priority and Fairness أو APF نظام Kubernetes المدمج للتحكم في الحمل الزائد. أصبحت Stable منذ Kubernetes v1.29 وهي مفعلة افتراضيًا. تصنف APF الطلبات عبر Objects من نوع `FlowSchema`، وتربطها بـ`PriorityLevelConfiguration`، ثم تطبق حدود Concurrency معزولة وطوابير عادلة. الهدف ليس جعل كل طلب سريعًا، بل الحفاظ على تقدم مفيد عندما يتجاوز الطلب ما يستطيع API Server تنفيذه.

تزداد أهمية ذلك مع انتشار Custom Controllers والعملاء الذاتيين. قد يكون Controller غير الكفؤ مجرد عبء صغير في الأوقات الهادئة، لكنه يتحول إلى حادثة Control Plane عندما تنفذ Tenants كثيرة Reconcile معًا. تمنح APF فرق المنصة وسيلة لحصر Blast Radius من دون منح كل عميل مهم إعفاءً غير محدود.

APF ليست Pod Priority ولا CPU QoS

تؤثر Pod Priority في الجدولة وPreemption على Worker Nodes. وتضبط Resource Requests وLimits معالج وذاكرة Containers. أما APF فتحكم HTTP Requests الداخلة إلى `kube-apiserver`. قد تستهلك Pod قدرًا قليلًا من CPU لكنها ترسل `LIST` مكلفة تعيد آلاف Objects؛ وتوضح Kubernetes أن عمليات List الكبيرة قد تشغل أكثر من Execution Seat واحدة.

مسار الطلب هو: مطابقة `FlowSchema`، ثم اختيار Priority Level، ثم تمييز Flow الخاصة بالطلب، وبعدها Dispatch أوQueue أوReject. تُفحص قيم `matchingPrecedence` الرقمية الأصغر أولًا، وأول تطابق يفوز. يسهل الخطأ في هذا الترتيب؛ فقد تلتقط قاعدة واسعة موضوعة مبكرًا Traffic كانت مخصصة لقاعدة أدق.

تستطيع `FlowSchema` مطابقة Users وGroups وService Accounts، ودمج الهوية مع Verbs وAPI Groups وResources وNamespaces. ويمكن لـ`distinguisherMethod` فصل Flows حسب User أو Namespace. الفصل مهم لأن العدالة تعمل بين Flows داخل Priority Level؛ ومن دون Distinguisher مفيد قد تنهار Tenants كثيرة في Flow واحدة وتتشارك المصير نفسه.

صمم مستويات الأولوية حسب حدود الفشل

ابدأ من فئات Traffic لا التطبيقات الفردية. أبقِ Defaults الإلزامية والمقترحة في Kubernetes مرئية، خصوصًا Node Health وSystem Controllers وLeader Election. أضف Priority Level محدودة للأتمتة المخصصة القادرة على تحمل التأخير، مثل Report Generators وDeployment Bots وPolicy Scanners ووكلاء AI. أنشئ مستوى منفصلًا فقط عندما تختلف Failure Behavior أو Latency Objective أو Ownership بوضوح.

تعرف Priority Level المحدودة Nominal Concurrency Shares، ونسبة السعة غير المستخدمة القابلة للإقراض، وكيفية التعامل مع Overload. يعيد `Reject` استجابة HTTP 429 فور بلوغ الحد. أما `Queue` فتمتص الاندفاع القصير وتوزع العمل بعدالة. تناسب الطوابير عادة Controllers حسنة السلوك لأن عملاء Kubernetes يفترض أن يعيدوا المحاولة مع Backoff، لكن Queue ليست سعة مجانية؛ فالطابور الطويل يحول الحمل الزائد إلى Latency واستهلاك ذاكرة.

apiVersion: flowcontrol.apiserver.k8s.io/v1
kind: PriorityLevelConfiguration
metadata:
  name: automation-low
spec:
  type: Limited
  limited:
    nominalConcurrencyShares: 10
    lendablePercent: 50
    limitResponse:
      type: Queue
      queuing:
        queues: 64
        handSize: 6
        queueLengthLimit: 50

عامل هذه القيم كتجربة أولية لا كإعداد عام. يقلل عدد Queues الأكبر تصادم Flows غير المرتبطة، لكنه يستهلك ذاكرة أكثر. وتمتص `queueLengthLimit` الأكبر اندفاعًا أوسع لكنها تسمح بانتظار أطول. ويقلل `handSize` الأكبر احتمال تصادم Flow محددة مع أخرى، لكنه يمنح عددًا قليلًا من Flows تأثيرًا في Queues أكثر. تستخدم Kubernetes تقنية Shuffle Sharding لاختيار مجموعة صغيرة من الطوابير لكل Flow؛ يأتي العزل من هذا الفصل الاحتمالي، لا من Queue مخصصة لكل عميل.

طابق العميل بدقة واحتفظ بمسار نجاة

اربط Priority Level بـ`FlowSchema` ضيقة. على سبيل المثال، اعزل Service Account الخاصة بـAutomation Controller وقيّد المطابقة بالـVerbs والـResources التي تحتاجها فعلًا. تجنب قاعدة Wildcard لجميع Service Accounts إلا إذا كانت النية عالمية بوضوح.

apiVersion: flowcontrol.apiserver.k8s.io/v1
kind: FlowSchema
metadata:
  name: automation-jobs
spec:
  matchingPrecedence: 800
  distinguisherMethod:
    type: ByNamespace
  priorityLevelConfiguration:
    name: automation-low
  rules:
  - subjects:
    - kind: ServiceAccount
      serviceAccount:
        name: job-orchestrator
        namespace: automation
    resourceRules:
    - verbs: [get, list, watch, create, patch]
      apiGroups: ["", batch]
      resources: [pods, jobs]
      namespaces: ["*"]

قبل تطبيق القاعدة، افحص Objects الموجودة وحدد أي Schema تطابق الطلبات الممثلة حاليًا. احتفظ بمسار Break-glass للإدارة، لكن لا تضع Application Clients عشوائيًا في مستوى `exempt`. تتجاوز Exempt Traffic التحكم بالكامل؛ وقد يستهلك عميل مخترق أو عالق في Loop السعة التي يفترض أن تحميها APF.

تحتاج مسارات الطلب Recursive إلى عناية إضافية. قد تستدعي Admission Webhooks وAggregated API Servers خدمة `kube-apiserver` مجددًا بينما يحتفظ الطلب الأصلي بالسعة. تحذر Kubernetes من أن تطبيق التحكم بالأولوية على الطبقتين قد يصنع Priority Inversion أو Deadlock. مثل هذه Call Graphs صراحة، وتأكد أن الطلب التابع يستطيع التقدم عند أولوية كافية.

تصنف APF كل طلب، وتربطه بمستوى أولوية، ثم تضع الحمل الزائد في طابور أو ترفضه حتى لا يستهلك Flow مزعج الـControl Plane.
تصنف APF كل طلب، وتربطه بمستوى أولوية، ثم تضع الحمل الزائد في طابور أو ترفضه حتى لا يستهلك Flow مزعج الـControl Plane. اضغط لعرض أكبر

قلل عمل API قبل شراء Seats إضافية

APF نظام أمان وليست إذنًا بالإبقاء على عملاء غير كفؤين. فضل Shared Informers وWatches على Full Lists المتكررة. استخدم Pagination للقوائم الكبيرة، وScope للـCaches حسب Namespace عندما يمكن، وأضف Jitter إلى Resynchronization على مستوى الأسطول، واستخدم Exponential Backoff مع 429 والأعطال العابرة. لا تشغل Polling Loop متطابقة لكل Tenant إذا كانت Watch واحدة تستطيع تغذية العمل الخاص بكل Tenant.

بالنسبة لوكلاء AI، ضع مراقبة Cluster خلف Tool Service محدودة. تستطيع الخدمة Cache للـDiscovery، وفرض Namespace وVerb Scopes، ودمج القراءات المتكررة، ووضع Mutations في Queue. لا تمنح Agent بيانات اعتماد واسعة ليجرب Kubernetes API بحرية داخل Reasoning Loop. تحتوي APF الطلب بعد Authentication؛ لكنها لا تستبدل RBAC ولاAdmission Control ولاBudgets على مستوى الأدوات.

إذا بدأت APF رفض طلبات عبر Priority Levels عديدة بينما حجم العمل ثابت، فابحث في Control-plane latency بدل زيادة Shares فقط. يؤدي بطء Storage أو Admission أو API Server مثقل إلى احتفاظ الطلبات بالـSeats مدة أطول. إعادة توزيع Pool ثابتة لا تصلح تبعية مشبعة.

شغّل النظام انطلاقًا من أربع إشارات

يعرض مرجع Kubernetes Metrics الإشارات اللازمة لتمييز Burst من Starvation مستمرة. أنشئ Alert على معدل `apiserver_flowcontrol_rejected_requests_total` حسب `flow_schema` و`priority_level` و`reason`. وراقب `apiserver_flowcontrol_current_inqueue_requests` وp95 وp99 من `apiserver_flowcontrol_request_wait_duration_seconds`. وقارنها مع `apiserver_flowcontrol_nominal_limit_seats` ومقاييس Occupied Seats.

فسرها معًا. تعني Rejections بسبب `queue-full` مع ارتفاع Wait Time حملًا زائدًا مستمرًا. وتعني `concurrency-limit` أن المستوى يرفض بدل الانتظار. وقد يخالف ارتفاع Wait Time من دون رفض مواعيد Controllers النهائية. أما الرفض الواسع عبر مستويات عديدة مع ارتفاع Execution Latency فيشير إلى Control-plane bottleneck لا Flow مزعجة واحدة.

نفذ Rollout لفئة Traffic واحدة في كل مرة. التقط Baseline، وطبق FlowSchema وPriority Level في Cluster غير حرجة، وأعد Burst مضبوطة، وتحقق أن Leader Election وSystem Controllers تواصل التقدم. ثم اختبر معالجة 429 وتأخير Queue وترتيب القواعد وRollback. خزّن Objects الخاصة بـAPF كبنية تحتية ذات Version، لكن قارنها مع Defaults التي يديرها Server عند ترقية Kubernetes لأن Suggested Objects تملك سلوك Auto-update.

القاعدة العملية بسيطة: يجوز أن تصبح الأتمتة غير الأساسية أبطأ أو تتلقى 429، لكنها يجب ألا تمنع Node Health وLeader Election وعمليات Reconciliation الأساسية من التقدم. عندما تصبح هذه القاعدة قابلة للقياس، تحول APF حمل Control Plane الزائد من عطل مبهم إلى Failure Mode معزول وقابل للتشخيص.

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

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

إعداد: Noor Yasser

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

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

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

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