التحكم في القبول والـ Webhooks
التحكم في القبول والـ Webhooks
في كل مرة تنفذ فيها kubectl apply، يمر طلبك عبر عدة طبقات قبل أن يُنشأ أي Pod. الطبقة الأخيرة من البوابات — تلك التي تتيح لشركات مثل Google وStripe وغيرها فرض سياسات الأمان وحقن الـ sidecars والتحقق من حصص الموارد في الوقت الفعلي — هي نظام التحكم في القبول (Admission Control). فهم هذا النظام بعمق يعني أنك قادر على الاعتماد عليه لحماية الكلاستر وتشخيص مشكلاته حين يرفض أعمالك بصمت.
دورة حياة طلب الـ API
قبل الخوض في الـ Webhooks، تتبع المسار الكامل الذي يسلكه الطلب عبر الـ API Server. هذا التسلسل حتمي ولا استثناء منه:
الفكرة المحورية هنا: تعمل الـ Mutating webhooks قبل الـ Validating webhooks. هذا الترتيب مقصود — تقوم الـ Mutators أولاً بتعديل الكائن (حقن الـ sidecars، إضافة التسميات، تعيين القيم الافتراضية)، ثم يتحقق المُدقِّق من الشكل النهائي. لو عملت الـ Validating webhook قبل التعديل، كانت السياسات ستفشل على كائنات كان المُعدِّل سيصلحها.
وحدات التحكم المدمجة مقابل الـ Webhooks
تأتي Kubernetes بوحدات تحكم في القبول مترجمة مسبقاً ومُفعَّلة بشكل افتراضي (مثل NamespaceLifecycle وLimitRanger وResourceQuota وPodSecurity). تعمل هذه قبل الـ Webhooks وتتولى الضمانات الأكثر أهمية. توسّع النظام عبر القبول الديناميكي بنوعين من الـ Webhooks:
- MutatingAdmissionWebhook — يمكنه تعديل الكائن عبر استجابة JSON Patch. يُستخدم لحقن الـ sidecars (Istio، Linkerd)، تشفير الـ secrets افتراضياً، ووضع التسميات تلقائياً.
- ValidatingAdmissionWebhook — يملك صلاحية السماح أو الرفض فقط. يُستخدم لفرض السياسات (OPA/Gatekeeper، Kyverno)، والسماح بسجلات صور محددة، والتحقق من وجود annotations إلزامية.
failurePolicy هي Fail، سيُرفض كل طلب API مطابق إلى كلاسترك حتى يتعافى الـ Webhook. تسبّب هذا في حوادث كبرى في شركات عملاقة. انشر دائماً خوادم الـ Webhook بنسختين على الأقل مع PodDisruptionBudget.
تسجيل Validating Webhook
تُسجَّل الـ Webhooks بكائنات ValidatingWebhookConfiguration أو MutatingWebhookConfiguration. يستخدمها الـ API Server لمعرفة أي نقطة HTTPS يستدعيها، وأي مجموعات من الموارد والعمليات تشغّلها.
حقل caBundle بالغ الأهمية — يستخدمه الـ API Server للتحقق من شهادة TLS الخاصة بالـ Webhook. في الإنتاج، استخدم cert-manager مع مورد Certificate والـ cainjector لتعبئة caBundle تلقائياً. تدوير هذه الشهادة يدوياً هو فخ تشغيلي.
ما يعيده خادم الـ Webhook
الـ Webhook الخاص بك هو مجرد خادم HTTPS عادي. يرسل الـ API Server جسم JSON من نوع AdmissionReview ويتوقع استجابة بنفس النوع. للـ Validating Webhook الاستجابة بسيطة:
تُعيد الـ Mutating Webhook نفس البنية لكن مع حقل patch (JSON Patch مشفّر بـ base64) و"patchType": "JSONPatch". يمكن للـ Patch إضافة حقول أو حذفها أو استبدالها في الكائن.
Kyverno وOPA Gatekeeper — محركات السياسات في الإنتاج
كتابة خوادم Webhook خام عُرضةٌ للأخطاء على نطاق واسع. تستخدم الكلاسترات الإنتاجية في كبريات الشركات محركات سياسات تُنفِّذ الـ Webhooks داخلياً وتتيح لك كتابة سياسات تصريحية بدلاً من خوادم Go أو Python.
- Kyverno — أصيل في Kubernetes. السياسات هي CRDs (
ClusterPolicy). صياغة YAML أبسط، دعم مدمج للتعديل التلقائي، ووضع التدقيق. - OPA Gatekeeper — يستخدم
ConstraintTemplateبلغة Rego. أكثر تعبيراً، أفضل للتحقق المعقد متعدد الحقول. معيار في Google والشركات الكبرى.
validationFailureAction: Audit أولاً. يسجّل هذا الانتهاكات دون حجب الأعمال، مما يتيح لك اكتشاف عدد الموارد الموجودة التي تنتهك السياسة قبل تطبيقها. لو فرضت السياسة مباشرة في كلاستر كبير، ستحجب خطوط CD الخاصة بك.
أوضاع الفشل والتشخيص
حين يرفض الـ Webhook طلبك، يعرض kubectl الرسالة من status.message مباشرةً. لكن الـ Webhooks يمكن أن تفشل بطرق أكثر خفاءً:
- انتهاء المهلة (Timeout) — إذا استغرق خادم الـ Webhook أطول من
timeoutSeconds، يعامله الـ API Server كفشل. معfailurePolicy: Failيحجب الطلب؛ معIgnoreيتجاوزه بصمت. كلاهما خطير. - عدم تطابق TLS — شهادة منتهية الصلاحية أو مُجدَّدة لم تُنشر في
caBundleيؤدي لفشل جميع الطلبات برسالة خطأ TLS بدلاً من رسالة سياسة مفيدة. - حلقة الـ Webhook — Mutating Webhook يراقب كائناته الخاصة ويعدّلها مجدداً. أضف دائماً
namespaceSelectorأوobjectSelectorلاستثناء namespace الـ Webhook نفسه.
failurePolicy: Fail على Webhook يستدعي خدمة خارجية (مثل خادم OPA بعيد، أو مخزن secrets خارجي). التبعيات الخارجية تُدخل زمن استجابة وخطر توقف. إذا توقفت تلك الخدمة 5 دقائق، لن يتمكن كلاسترك من إنشاء أي Pod. استخدم Ignore للـ Webhooks ذات التبعيات الخارجية، وعوّض ذلك بأدوات تدقيق ما بعد القبول.
أفضل الممارسات على نطاق واسع
- حدّد النطاق بدقة — استخدم
namespaceSelectorوobjectSelectorوقواعدrulesمحددة للمطابقة مع ما تحتاجه فقط. الـ Webhook الذي يُشغَّل على كل كائن في الكلاستر يُضاعف زمن استجابة الـ API Server. - استخدم cert-manager — لا تدر شهادات TLS للـ Webhook يدوياً أبداً. الـ
cainjectorيبقيcaBundleمتزامناً تلقائياً. - اضبط
sideEffects: None— مطلوب لدعم التشغيل الجاف (kubectl apply --dry-run=server). إن كان لـ Webhook آثار جانبية (يكتب في قاعدة بيانات، يستدعي API)، صرّح بـNoneOnDryRunونفّذ كشف التشغيل الجاف. - استثنِ namespaces النظام — استثنِ دائماً
kube-systemوnamespace الـ Webhook نفسه من قواعد الـ Webhook لتجنب تعطل طائرة التحكم. - راقب زمن استجابة الـ Webhook — اعرض نقطة
/metricsعلى خادم الـ Webhook وأنشئ تنبيهاً على زمن الاستجابة p99 أكثر من ثانيتين. تعرض مقاييس الـ API Server نفسهapiserver_admission_webhook_admission_duration_seconds.