kubectl والـ API
kubectl والـ API
كل إجراء تنفذه في Kubernetes — جدولة Pod، أو تغيير عدد النسخ، أو قراءة السجلات — هو في جوهره استدعاء HTTP موجَّه إلى خادم API الخاص بـ Kubernetes. لا يعدو kubectl كونه عميل HTTP متطور يتحدث بروتوكول Kubernetes API، ويُنسّق استجابات JSON، ويوفر الإكمال التلقائي للأوامر. حين تستوعب هذا النموذج، يصبح كل شيء آخر في واجهة سطر الأوامر واضحاً ومفهوماً.
خادم API بوصفه مصدر الحقيقة
مكونات مستوى التحكم التي تعرفت عليها في الدرس الثاني — المجدول، ومدير المتحكمات، و etcd — لا تتحدث مع بعضها مباشرةً. كلها تمر عبر خادم API. بمعنى أن كل تغيير في حالة الكلاستر هو استدعاء API، وكل حلقة مزامنة تراقب API لرصد التغييرات. أما kubectl فهو ببساطة نافذتك على هذا الـ API نفسه.
حين تنفذ kubectl get pods، يُصدر kubectl طلب GET إلى /api/v1/namespaces/default/pods. وحين تنفذ kubectl apply -f deployment.yaml، يُصدر طلب PATCH باستخدام server-side apply إلى النقطة الطرفية المناسبة. يمكنك مشاهدة هذا حياً بالأمر kubectl --v=8 get pods الذي يطبع كل طلب HTTP واستجابته.
أفعال kubectl ونموذج الموارد
يعرض Kubernetes موارد (Pods، Deployments، Services، ConfigMaps…) ويعرض kubectl أفعالاً تُعيّن على أساليب HTTP. معرفة مجموعة الأفعال القياسية تُغنيك عن حفظ عشرات الأوامر الفرعية:
get— استرجاع مورد أو أكثر (HTTP GET). أضف-o yamlأو-o jsonللحصول على الكائن كاملاً.describe— تفاصيل الكائن بصيغة مقروءة مع الأحداث الأخيرة (لا غنى عنه في التشخيص).create— نشر مورد جديد بطريقة POST. يُخفق إن كان المورد موجوداً مسبقاً.apply— دمج/إنشاء إعلاني باستخدام ملف manifest. ثابت المُدخلات (Idempotent) — آمن التكرار.delete— حذف مورد، ويبدأ Kubernetes فوراً دورة حياة الإنهاء.edit— فتح الكائن الحي في$EDITOR(يُعدّل مباشرةً في الـ API لا في ملف محلي).patch— تحديث حقل بعينه:kubectl patch deployment api --type=json -p '[{"op":"replace","path":"/spec/replicas","value":5}]'rollout— إدارة طرح Deployment:statusوhistoryوundo.exec— تشغيل أمر داخل حاوية قيد التشغيل (ترقية WebSocket، شبيه SSH لكنه مؤقت).logs— بث stdout/stderr من الحاوية.port-forward— نفق منفذ TCP محلي إلى منفذ Pod (ليس لحركة مرور الإنتاج).top— استخدام CPU/الذاكرة الحي (يتطلب تثبيت metrics-server).
kubectl apply عند كل push إلى git. لأن apply ثابت المُدخلات، لن يُخفق عند الموارد الموجودة مسبقاً — بل يحسب الفرق ويُطبّق التعديل. دائماً فضّل apply على create في الأتمتة.
ملفات YAML Manifests والحقول الأربعة المطلوبة
كل manifest في Kubernetes يحتاج أربعة حقول على المستوى الأعلى. كل كائن في الكلاستر — بصرف النظر عن تعقيده — يتبع هذا العقد:
لاحظ غياب status — هذا الحقل تملكه Kubernetes وتملأه بعد الإنشاء. أنت تُعرّف spec (الحالة المطلوبة) والكلاستر يملأ status (الحالة الملاحظة). هذا هو عقد المزامنة الذي يُشغّل كل شيء.
apply مقابل create — ومتى يُخفق كل منهما
يمكن للأمرين إنشاء موارد، لكن دلالاتهما تتباين بحدة في بيئة الإنتاج:
kubectl create -f manifest.yaml— أمري وأحادي التنفيذ. يرفضه الـ API بخطأAlreadyExistsإن كان المورد موجوداً. مفيد للتهيئة الأولية (Namespaces وSecrets في سكريبت إعداد)، لكنه سيء في الأنابيب.kubectl apply -f manifest.yaml— إعلاني وثابت المُدخلات. يتتبع Kubernetes حقل التعليق last-applied-configuration لحساب دمج ثلاثي: آخر حالة مُطبَّقة + الكائن الحي الحالي + الـ manifest الجديد. الحقول التي تحذفها من manifest تُحذف تلقائياً. هذا هو الافتراضي الصحيح لكل ما تلمسه CI/CD.
kubectl edit deployment/api في الإنتاج لزيادة عدد النسخ في حالة طارئة، ثم نفّذ أنبوب CI أمر kubectl apply بالـ manifest القديم، تُلغى التغييرات اليدوية بصمت. الحل: تعامل مع manifests git بوصفها المصدر الوحيد للحقيقة، واحمِ الكائنات الحية بـ admission webhooks أو بوابات pull-request الخاصة بـ GitOps.
السياقات وملف kubeconfig
المهندس الحقيقي يدير كلاسترات متعددة: dev وstaging وproduction وربما منطقة DR. يقرأ kubectl ملف ~/.kube/config (أو $KUBECONFIG) ليعرف أي كلاستر يتحدث إليه، وأي بيانات اعتماد يستخدم، وأي namespace يُعيّن افتراضياً. يُجمّع الملف هذه المعلومات في سياقات (contexts).
kubectl config use-context وkubectl config set-context --current --namespace بأوامر قصيرة: kubectx prod وkubens payments. يستخدمهما كل SRE محترف. ثبّتهما بـ brew install kubectx أو من إصدار GitHub. تعرضان السياق النشط والـ namespace في موجّه الأوامر عبر إضافة kube-ps1 — مما يُجنّبك فئة الحوادث الإنتاجية الناتجة عن تنفيذ أمر في الكلاستر الخطأ.
الـ Namespaces بوصفها حدود نطاق
حين تمرر --namespace (أو اختصاره -n)، فأنت تخبر kubectl بأي namespace يُحدّد نطاق استدعاء الـ API. تتغير مسار الـ API من /api/v1/namespaces/default/pods إلى /api/v1/namespaces/payments/pods. بعض الموارد تعمل على مستوى الكلاستر (Nodes وPersistentVolumes وClusterRoles) ولا تقبل علامة الـ namespace — الاستعلام عنها على المستوى namespace يُعيد خطأً.
سير العمل اليومي الجوهري
تسلسل واقعي لنشر workload وفحصها يبدو كالتالي:
هذا سير العمل — apply ثم status ثم describe ثم logs ثم exec ثم rollout undo — يُغطي الغالبية العظمى من العمليات اليومية. أتقنه قبل اللجوء إلى أدوات أكثر تخصصاً. الدرس القادم يتناول ReplicaSets والـ Deployments بعمق، حيث يُصبح الفعل rollout محورياً.