EduFlow

الوحدة 4 · أساسيات Kubernetes

حلقة التحكّم وأول cluster لك

16 دقراءة 4 درتّب الخطوات

الدرس في لمحة

اشرح كيف يحوّل Kubernetes الحالة المرغوبة المصرَّح بها إلى containers تعمل عبر حلقات التحكّم، وسمِّ المكوّنات الرئيسية في الـ cluster، وأنشئ cluster محليًا بـ kind لتعمل فيه.

  1. 1حلقة التحكّم
  2. 2أجزاء الـ cluster
  3. 3cluster على حاسوبك
  4. 4راقب الحلقة وهي تعمل

لا فيديو هنا، بل الشيء الحقيقي: درس مكتوب وأمثلة قابلة للتشغيل واختبار وتدريب.

‏Compose يشغّل بيئتك على جهاز واحد. حين يموت ذلك الجهاز، تموت خدمتك معه، ولا شيء يعيدها حتى يلاحظ أحد. ‏Kubernetes موجود للحالة الأخرى: أجهزة كثيرة، وcontainers يجب أن تستمر في العمل حين يفشل أي جهاز منها، وتغييرات تُنشر دون توقّف للخدمة. لتستخدمه جيدًا، تحتاج إلى فكرة واحدة أكثر من حاجتك إلى أي أمر.

حلقة التحكّم

في Kubernetes لا تقول «شغّل ثلاثة containers». تقول «يجب أن توجد ثلاث نسخ من notes-api»، وتخزّن ذلك ككائن في الـ cluster (العنقود). ثم يشغّل controller حلقة، بلا توقّف:

  1. راقب الحالة الفعلية: كم Pod من notes-api موجود ويعمل؟
  2. قارن بينها وبين الحالة المرغوبة في الكائن.
  3. تصرّف لسدّ الفجوة: أنشئ Pod، أو احذف واحدًا، أو استبدل واحدًا.

الحلقة لا تنتهي أبدًا. إذا مات node وأخذ معه Pod، فالدورة التالية ترى اثنين حيث المطلوب ثلاثة فتنشئ واحدًا. إذا غيّرت العدد المرغوب إلى خمسة، تنشئ اثنين آخرين. وإذا حذف أحدهم Pod يدويًا، يُستبدل خلال ثوانٍ. هذا ما يقصده الناس بـ التصريحي (declarative): تصف الوجهة، والنظام يواصل التوجّه نحوها.

تشبيه منظّم الحرارة مفيد هنا. تضبطه على 21°C؛ فلا يشغّل المنظّم سكربتًا ثابتًا من نوع «سخّن لمدة 20 دقيقة». إنه يقيس ويقارن ويشغّل المدفأة أو يطفئها ما دام موصولًا بالكهرباء.

أجزاء الـ cluster

‏kubectl يرسل الكائنات إلى الـ API server، الذي يخزّنها في etcd. الـ scheduler والـ controller manager يراقبان الـ API server. على كل node عامل، يراقب الـ kubelet الـ Pods المسندة إليه ويشغّل الـ containers عبر الـ container runtime. kubectl مستوى التحكّم (control plane) API server etcd scheduler controller manager node 1 kubelet → containerd pod pod node 2 kubelet → containerd pod مراقبة: Pods هذا الـ node
كل مكوّن يتحدّث مع الـ API server؛ والـ controllers والـ kubelets توفّق الحالة
  • الـ API server هو الباب الأمامي. ‏kubectl والـ controllers والـ kubelets كلها تتحدّث معه، وهو يتحقّق من صحة كل طلب ومن هوية مرسله وصلاحياته.
  • الـ etcd مخزن مفتاح-قيمة متّسق يحفظ كل الكائنات. لا يتحدّث معه إلا الـ API server.
  • الـ scheduler (المُجدوِل) يراقب الـ Pods التي لا node لها ويختار لها واحدًا، بناءً على الموارد الحرّة والقيود والتوزيع.
  • الـ controller manager يشغّل الـ controllers المدمجة: الـ Deployments، والـ ReplicaSets، والـ Jobs، وصحة الـ nodes، وغيرها.
  • على كل node (عقدة) عامل، يراقب الـ kubelet الـ Pods المسندة إلى الـ node الخاص به ويشغّل الـ containers الخاصة بها عبر container runtime، وهو عادةً containerd. الـ images التي بنيتها بـ Docker تعمل هناك دون تغيير، لأن الـ images تتبع معيار OCI.

الخدمات المُدارة مثل Amazon EKS تشغّل مستوى التحكّم نيابة عنك. لكنك ما زلت تحتاج إلى فهمه، لأن كل رسالة خطأ ستقرؤها تشير إلى أحد هذه الأجزاء.

cluster على حاسوبك

‏kind ‏(“Kubernetes in Docker”) يشغّل cluster كاملًا داخل containers في Docker. إنشاؤه سريع والتخلّص منه سريع، وهذا بالضبط ما تريده للتعلّم:

Terminal
kind create cluster --name notes
kubectl config current-context      # kind-notes
kubectl get nodes
kind load docker-image notes-api:1.0.0 --name notes

الأمر الأخير ينسخ الـ image المحلية إلى الـ node في kind، فيستطيع الـ cluster تشغيلها دون registry. يعمل minikube وKubernetes المدمج في Docker Desktop أيضًا؛ وأوامر kubectl في هذه الدورة هي نفسها في كل مكان.

في kind، يعمل مستوى التحكّم نفسه كـ Pods على الـ node المخصّص له. شغّل kubectl get pods -n kube-system وسترى الـ API server وetcd والـ scheduler والـ controller manager مدرجة مثل أي حمل عمل آخر، ومعها DNS الخاص بالـ cluster ‏(CoreDNS) وkube-proxy. أما في cluster مُدار فلن ترى مستوى التحكّم هناك، لأن المزوّد يشغّله بعيدًا عن الأنظار.

راقب الحلقة وهي تعمل

أنشئ Deployment بالأوامر المباشرة، مرة واحدة، لترى التوفيق بعينيك:

Terminal
kubectl create deployment notes-api --image=notes-api:1.0.0 --replicas=3
kubectl get pods
kubectl delete pod <one-of-the-pod-names>
kubectl get pods --watch

خلال ثوانٍ يظهر Pod جديد باسم جديد. لم تطلبه؛ الـ controller أدّى عمله. والآن انظر إلى ما أنشأته:

Terminal
kubectl get deployment notes-api -o yaml
kubectl explain deployment.spec.replicas
kubectl delete deployment notes-api

الخيار -o yaml يعرض الكائن الكامل الذي خزّنه Kubernetes، بما فيه قيم افتراضية كثيرة لم تضبطها. والأمر kubectl explain يوثّق أي حقل من الـ cluster نفسه؛ إنه أسرع مرجع لديك. بدءًا من الدرس التالي ستكتب هذه الكائنات كملفات وتطبّقها، وهكذا تعمل الفرق الحقيقية.

التالي: الكائنات التي لمحتها للتوّ، مكتوبة كما يجب. الـ Pods والـ ReplicaSets والـ Deployments.

أهم النقاط

  • تخبر Kubernetes بالحالة التي تريدها؛ والـ controllers تواصل مقارنتها بالحالة الفعلية وتتصرّف لسدّ الفجوة، إلى الأبد.
  • الـ API server هو الباب الأمامي، وهو المكوّن الوحيد الذي يتحدّث مع etcd، حيث تُخزَّن كل حالة الـ cluster.
  • الـ scheduler يختار node لكل Pod جديد؛ والـ kubelet على ذلك الـ node يشغّل الـ containers الخاصة به عبر الـ container runtime.
  • حذف Pod يديره controller لا يزيله لوقت طويل، لأن الـ controller يرى أن واحدًا ناقص فينشئ بديلًا.
  • تحقّق دائمًا من الـ cluster الذي يشير إليه kubectl بالأمر kubectl config current-context قبل تغيير أي شيء.

قراءات إضافية

تحقّق من فهمك

4 أسئلة

السؤال 1 من 4

‏Deployment يريد 3 نسخ (replicas). ينهار node ويأخذ معه Pod واحدًا. ما الذي يعيد الـ Pod الثالث؟

السؤال 2 من 4

أي مكوّن هو الوحيد الذي يقرأ etcd ويكتب فيه مباشرة؟

السؤال 3 من 4

تحذف Pod أنشأه Deployment بالأمر kubectl delete pod notes-api-7d9c-xk2lp. ماذا ترى بعد بضع ثوانٍ في kubectl get pods؟

السؤال 4 من 4

قبل تشغيل kubectl delete deployment notes-api، ما الذي يجب أن تتحقّق منه؟

تدريب

رتّب الخطوات

من kubectl apply إلى container يعمل

تشغّل kubectl apply -f deployment.yaml لـ notes-api مع 3 نسخ على cluster جديد. رتّب ما يحدث بعد ذلك.

استخدم أزرار الأسهم لإعادة الترتيب.

  1. 1ينشئ الـ controller الخاص بالـ ReplicaSet ثلاثة كائنات Pod
  2. 2يتحقّق الـ API server منه ويخزّنه في etcd
  3. 3ينشئ الـ controller الخاص بالـ Deployments كائن ReplicaSet
  4. 4يسحب الـ kubelet في كل node الـ image ويشغّل الـ containers
  5. 5يُسند الـ scheduler كل Pod إلى node
  6. 6يُبلغ الـ kubelet عن حالة الـ Pod إلى الـ API server
  7. 7يرسل kubectl الـ Deployment إلى الـ API server