kubectl، تحكم المجموعة

11 دقيقة
الجمهور المستهدف
مبتدئ، مع تفعيل Kubernetes الخاص بـ Docker Desktop (الدرس 02)
المدة
35 إلى 45 دقيقة
الوحدة
1/8
الكفاءة المستهدفة
معرفة أي ملف تنفيذي لـkubectl يستجيب ومع أي كتلة يتحدّث، تصحيح تحذير إصدار، قراءة أمر kubectl كجملة (فعل، مورد، اسم، خيارات)، وإنشاء أول namespace خاص بك

في صورة واحدة

kubectl جهاز تحكم عن بُعد شامل. لا يفعل شيئاً بنفسه: فهو يُرسل أوامر إلى جهاز، وهو API server من الدرس 01، عبر HTTPS على المنفذ 6443. له مُحدِّد مصدر، وهو السياق (context)، يُحدّد الكتلة المستهدَفة (docker-desktop، أو minikube قديم، أو بيئة إنتاج شركتك): تضغط على «Play» موجّهاً إلى الجهاز الخطأ ولا يتحرّك شيء، فتظنّ أن جهاز التحكم معطّل. له بطاريات بجهد معيّن: kubectl بإصدار 1.30 أمام كتلة بإصدار 1.34 يعمل تقريباً، لكنه يُحذّرك من أنه لم يعد يضمن شيئاً. ويتحدّث بقواعد نحوية ثابتة: فعل (get)، ومورد (pods)، وأحياناً اسم، ثم خيارات (-n premiers-pas -o wide). خلال أربعين دقيقة ستعرف قراءة هذه الجملة من أول محاولة، وستكون قد صحّحت فخّ إصدار حقيقياً، وفتحت دُرجك الخاص في الكتلة: namespace باسم premiers-pas، حيث ستجري كل هذه الوحدة.

كيف يعمل الأمر

يقرأ kubectl ملفاً واحداً عند الإقلاع: ~/.kube/config (C:\Users\<أنت>\.kube\config على Windows)، وهو kubeconfig. يحتوي على ثلاث قوائم: clusters (عنوان API والشهادة التي تسمح بالتعرّف عليه)، وusers (بيانات الاعتماد: هنا شهادة عميل ولّدها Docker Desktop)، وcontexts، التي تربط كتلة بمستخدم، مع namespace افتراضي اختياري. يُحدّد السطر current-context السياق الذي يستخدمه كل أمر. يكتب Docker Desktop فيه docker-desktop عند التفعيل؛ وتضيف minikube أو kind أو مزوّد سحابي سياقاتها الخاصة، وهكذا يتحكّم نفس kubectl في عدة كتل.

تُقرأ كل أمر كجملة: kubectl <فعل> <مورد> [اسم] [خيارات]. يقول الفعل ماذا نفعل؛ والمورد على أي نوع من الكائنات؛ ويستهدف الاسم كائناً محدداً (بدون اسم، يُطبَّق الفعل على جميع كائنات النطاق الحالي)؛ وتُحدّد الخيارات الدُرج (-n)، والصيغة (-o)، والنطاق (-A)، أو المتابعة المباشرة (-w). تقبل الموارد اختصارات يسردها kubectl api-resources في عمود SHORTNAMES.

الجزءأمثلةالدور
الفعلget، describe، create، apply، delete، logs، exec، scale، explainالإجراء المطلوب من الـ API
الموردpods (podeployments (deployservices (svcnamespaces (nsnodes (no)نوع الكائن؛ pod/api يعادل pod api
الاسمapi، api-9bfb55fc6-988xh، docker-desktopكائن محدد؛ غيابه = كل كائنات الـ namespace
-n <ns>-n premiers-pasالـ namespace المستهدَف؛ بدونه، default (لا تستخدمه الدورة أبداً)
-Akubectl get pods -Aكل الـ namespaces (يضيف عمود NAMESPACE)
-o wide / -o yaml / -o json / -o namekubectl get pods -o wideأعمدة إضافية / الكائن الكامل كما يُخزّنه الـ API / نفس الشيء بصيغة JSON / فقط النوع/الاسم
-wkubectl get pods -n premiers-pas -wيبقى متصلاً ويعرض كل تغيير (Ctrl+C للخروج)
--helpkubectl get --helpمساعدة أي فعل، مع أمثلة

الـ namespaces هي أدراج الكتلة: يمكن لنفس اسم Pod أو Service أن يوجد في namespace-ين دون تعارض، وترتبط الحصص (quotas) والصلاحيات بالـ namespace، ويُفرّغ kubectl delete namespace كل شيء دفعة واحدة. تُولد الكتلة مع default، وkube-system (control plane)، وkube-public، وkube-node-lease. لا تكتب هذه الدورة أبداً في default: لكل وحدة namespace خاص بها، وتحمل كل أمر -n. نسيان -n يعني البحث عن Pod الخاص بك في الدُرج الخطأ: «لا وجود له»، بينما هو يعمل بشكل ممتاز إلى جانبه. ستستحضر هذا الخطأ في العملية الموجهة كي لا تقع فيه أبداً بعد الآن.

ما تريد معرفتهالأمريتحدّث مع الكتلة؟
أي ملف تنفيذي يستجيبwhere.exe kubectl (Windows) / which -a kubectl (bash)لا
إصدار العميل والخادمkubectl versionنعم
إلى أي كتلة أُشيرkubectl config current-contextلا
كل الكتل المعروفةkubectl config get-contextsلا
محتوى حقل YAMLkubectl explain deployment.spec.replicasنعم
كل أنواع الكائنات واختصاراتهاkubectl api-resourcesنعم

خطوة بخطوة

على PowerShell، تحتفظ آلة الدورة عمداً بفخّ: ثلاث نسخ من kubectl في PATH، من بينها نسخة قديمة 1.30 ثُبِّتت يدوياً قبل Docker Desktop. عندك على الأرجح نسخة واحدة فقط؛ لكن نفّذ مع ذلك الخطوات من 1 إلى 3، فهي ستوفّر عليك ساعة من الحيرة يوم تُثبِّت أداة ثانية.

  1. اكتشف أي kubectl يستجيب. يأخذ الصدفة (shell) أول ملف تنفيذي يجده حسب ترتيب PATH.

    powershell
    where.exe kubectl
    bash
    which -a kubectl

    المخرجات الحقيقية (Windows):

    text
    C:\Program Files\Docker\Docker\resources\bin\kubectl.exe
    C:\Users\<toi>\Documents\kubectl\kubectl.exe
    C:\kubectl\kubectl.exe

    ما يجب ملاحظته: السطر الأول هو الذي يُنفَّذ عندما تكتب kubectl. هنا إنه سطر Docker Desktop، لأن PATH أُعيد ترتيبه؛ تُظهر الخطوة 2 ما يحدث عندما لا يكون الأمر كذلك. على macOS، توقّع /usr/local/bin/kubectl (Docker Desktop) وربما /opt/homebrew/bin/kubectl (Homebrew).

  2. انتبه جيداً لما سيحدث: تشغيل kubectl القديم عمداً. على آلة الدورة، الملف التنفيذي الثاني هو إصدار 1.30. استدعاؤه بمساره الكامل أمام كتلة بإصدار 1.34:

    powershell
    & "C:\Users\<toi>\Documents\kubectl\kubectl.exe" version

    المخرجات الحقيقية:

    text
    Client Version: v1.30.0
    Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
    Server Version: v1.34.1
    WARNING: version difference between client (1.30) and server (1.34) exceeds the supported minor version skew of +/-1

    ما يجب ملاحظته: يستجيب الأمر مع ذلك (الكتلة قابلة للوصول)، لكن التحذير واضح: لا يضمن Kubernetes kubectl إلا مع إصدار فرعي واحد من فرق عن الخادم (1.33 أو 1.34 أو 1.35 لكتلة بإصدار 1.34). فيما يتجاوز ذلك، تتصرّف بعض الأوامر الفرعية بشكل غريب أو تتجاهل حقولاً حديثة. إذا رأيت هذا السطر عندك، فهو نفس الفخّ: نسخة قديمة من kubectl (Homebrew، Chocolatey، تحميل يدوي) تسبق نسخة Docker Desktop.

  3. تصحيح ترتيب PATH. لجلسة PowerShell الحالية، ثم التحقق:

    powershell
    $env:Path = "C:\Program Files\Docker\Docker\resources\bin;" + $env:Path
    kubectl version

    المخرجات الحقيقية:

    text
    Client Version: v1.34.1
    Kustomize Version: v5.7.1
    Server Version: v1.34.1

    ما يجب ملاحظته: العميل والخادم متطابقان على v1.34.1، بدون تحذير. لجعل التغيير دائماً على Windows: Paramètres → Système → Informations système → Paramètres système avancés → Variables d'environnement → Path الخاص بمستخدمك → أعِد C:\Program Files\Docker\Docker\resources\bin إلى المقدّمة (أو احذف إدخال kubectl القديم)، ثم أعد فتح الطرفية. على macOS/Linux، احذف التكرار (brew uninstall kubectl) أو ضع /usr/local/bin قبله في ~/.zshrc. يتحقق سكريبت الحزمة من ذلك بدلاً عنك: يعرض .\labo.ps1 prerequis الرسالة ✘ kubectl client v1.30.0 trop ancien (minimum 1.33) — … طالما كان الترتيب خاطئاً.

  4. قراءة kubeconfig والسياق الحالي. أمران لا يلمسان الكتلة.

    bash
    kubectl config get-contexts
    kubectl config current-context

    المخرجات الحقيقية:

    text
    CURRENT   NAME             CLUSTER          AUTHINFO         NAMESPACE
    *         docker-desktop   docker-desktop   docker-desktop
              minikube         minikube         minikube         default
    docker-desktop

    ما يجب ملاحظته: النجمة على docker-desktop. تحتفظ آلة الدورة بسياق minikube من كتلة قديمة مطفأة: إنه نوع البقايا التي تجعل الشخص يقول «لم يعد kubectl يعمل» عندما يصبح النشط بالخطأ. إذا كانت النجمة عندك في مكان آخر، فإن kubectl config use-context docker-desktop تنقلها (لا تكتبها إن كانت في المكان الصحيح بالفعل: يُعيد الأمر كتابة ~/.kube/config). يعني عمود NAMESPACE الفارغ «default ما لم أمرّر -n»؛ لن نملأه، فالدورة تريد أن يكون -n عادة تلقائية.

  5. اقرأ أمراً كجملة، باستخدام explain. الدليل موجود داخل الكتلة: يطلب kubectl explain من API server توثيق نوع أو حقل، مطابقاً تماماً للإصدار الذي تستخدمه.

    bash
    kubectl explain deployment.spec.replicas

    المخرجات الحقيقية:

    text
    GROUP:      apps
    KIND:       Deployment
    VERSION:    v1
    
    FIELD: replicas <integer>
    
    
    DESCRIPTION:
        Number of desired pods. This is a pointer to distinguish between explicit
        zero and not specified. Defaults to 1.

    ثم انزل مستوى داخل Pod:

    bash
    kubectl explain pod.spec.containers

    المخرجات الحقيقية (مختصرة: القائمة الكاملة تضمّ نحو ثلاثين حقلاً):

    text
    KIND:       Pod
    VERSION:    v1
    
    FIELD: containers <[]Container>
    
    
    DESCRIPTION:
        List of containers belonging to the pod. Containers cannot currently be
        added or removed. There must be at least one container in a Pod. Cannot be
        updated.
        A single application container that you want to run within a pod.
    
    FIELDS:
      args	<[]string>
        Arguments to the entrypoint. The container image's CMD is used if this is
        not provided. …
    
      image	<string>
        Container image name. More info:
        https://kubernetes.io/docs/concepts/containers/images …
    
      imagePullPolicy	<string>
      enum: Always, IfNotPresent, Never
        Image pull policy. One of Always, Never, IfNotPresent. Defaults to Always if
        :latest tag is specified, or IfNotPresent otherwise. Cannot be updated. …
    
      name	<string> -required-
        Name of the container specified as a DNS_LABEL. Each container in a pod must
        have a unique name (DNS_LABEL). Cannot be updated.
    
      ports	<[]ContainerPort>
        List of ports to expose from the container. …

    ما يجب ملاحظته: تعني <[]Container> «قائمة»، وتُشير -required- إلى الحقول الإلزامية (name؛ image ليس إلزامياً بشكل رسمي، لكن حاوية بدون صورة لا تُقلع)، ويشرح السطر imagePullPolicy … Defaults to Always if :latest tag is specified سبب عدم كتابة هذه الدورة أبداً :latest: فلن تعرف بعد ذلك أي إصدار يعمل، وسيُعيد Kubernetes تحميله في كل مرة إقلاع.

  6. اكتشف الموارد واختصاراتها. تتجاوز القائمة الكاملة خمسين سطراً؛ رشّح الأنواع التي ستصادفها في الوحدات الثلاث الأولى.

    powershell
    kubectl api-resources | Select-String -Pattern '^(pods|deployments|services|namespaces|nodes|configmaps|secrets|replicasets|jobs|cronjobs|ingresses)\s'
    bash
    kubectl api-resources | grep -E '^(pods|deployments|services|namespaces|nodes|configmaps|secrets|replicasets|jobs|cronjobs|ingresses) '

    المخرجات الحقيقية:

    text
    configmaps                          cm           v1                                true         ConfigMap
    namespaces                          ns           v1                                false        Namespace
    nodes                               no           v1                                false        Node
    pods                                po           v1                                true         Pod
    secrets                                          v1                                true         Secret
    services                            svc          v1                                true         Service
    deployments                         deploy       apps/v1                           true         Deployment
    replicasets                         rs           apps/v1                           true         ReplicaSet
    cronjobs                            cj           batch/v1                          true         CronJob
    jobs                                             batch/v1                          true         Job
    ingresses                           ing          networking.k8s.io/v1              true         Ingress

    ما يجب ملاحظته: عمود SHORTNAMES (po، deploy، svc، ns، no، cm، rs)، وعمود APIVERSION الذي ستنسخه في مقدّمة كل ملف YAML (v1 لـ Pod، apps/v1 لـ Deployment)، وقبل كل شيء NAMESPACED: true لـ Pod أو Service (تعيش في دُرج، -n إلزامي)، وfalse لـnamespaces وnodes (تنتمي إلى الكتلة كلها، لا معنى لـ-n).

  7. أنشئ دُرجك: namespace باسم premiers-pas. أول أمر يكتب داخل الكتلة.

    bash
    kubectl create namespace premiers-pas
    kubectl get namespace premiers-pas
    kubectl get pods -n premiers-pas

    المخرجات الحقيقية:

    text
    namespace/premiers-pas created
    NAME           STATUS   AGE
    premiers-pas   Active   0s
    No resources found in premiers-pas namespace.

    ما يجب ملاحظته: الاستجابة النمطية لعملية إنشاء، type/nom created؛ وnamespace نشِط (Active) على الفور؛ ورسالة الدُرج الفارغ، No resources found in premiers-pas namespace.: ليست خطأً، بل هي الإجابة الصحيحة على سؤال «ماذا يوجد هنا؟» عندما لا يوجد شيء. إذا أجاب الأمر الأول بـError from server (AlreadyExists)، فإن الـ namespace موجود بالفعل (ربما سبقت الدرس 04): تابع.

  8. سهّل حياتك: الاختصارات والإكمال التلقائي. k بدلاً من kubectl ومفتاح Tab الذي يُكمل الأفعال والموارد وأسماء الكائنات. أضف هذه الأسطر إلى ملفك الشخصي كي تُعاد تحميلها في كل طرفية.

    powershell
    notepad $PROFILE

    الصق داخل الملف المفتوح (أنشئه إن اقترحه Notepad):

    powershell
    $env:Path = "C:\Program Files\Docker\Docker\resources\bin;" + $env:Path
    kubectl completion powershell | Out-String | Invoke-Expression
    Set-Alias k kubectl

    على bash (ملف ~/.bashrc):

    bash
    source <(kubectl completion bash)
    alias k=kubectl
    complete -o default -F __start_kubectl k

    على zsh (~/.zshrc، الصدفة الافتراضية لـ macOS):

    bash
    source <(kubectl completion zsh)
    alias k=kubectl
    compdef __start_kubectl k

    أعد فتح الطرفية، ثم اكتب kubectl get dep واضغط Tab. النتيجة الحقيقية على PowerShell: يصبح السطر kubectl get deployments.apps. اكتب بعد ذلك k get nodes:

    text
    NAME             STATUS   ROLES           AGE   VERSION
    docker-desktop   Ready    control-plane   18d   v1.34.1

    ما يجب ملاحظته: يستجيب k تماماً كـkubectl. تستمر الدورة في كتابة kubectl كاملة للحفاظ على وضوح القراءة؛ أما أنت فاكتب k. لا شيء لتنظيفه: يبقى namespace premiers-pas في مكانه، ويستخدمه الدرس 04 فوراً.

إذا واجهت مشكلة

  • WARNING: version difference between client (1.30) and server (1.34) exceeds the supported minor version skew of +/-1 ← نسخة قديمة من kubectl تسبق نسخة Docker Desktop في PATH. where.exe kubectl / which -a kubectl لرؤيتها، والخطوة 3 للتصحيح. عمل الأمر مع ذلك: التحذير لا يمنع، بل يُنبّه.
  • Unable to connect to the server: dial tcp 127.0.0.1:6443: connectex: No connection could be made because the target machine actively refused it. ← Docker Desktop متوقف أو Kubernetes معطّل (الدرس 02). ليست هذه أبداً مشكلة في kubectl نفسه: يستجيب kubectl version --client دائماً، أما kubectl version فلا.
  • Error in configuration: context was not found for specified context: … أو يُعيد kubectl config current-context الرسالة error: current-context is not set ← السياق المطلوب غير موجود في kubeconfig المقروء، أو أن هذا الملف فارغ (أداة أخرى أعادت كتابة ~/.kube/config، أو أن المتغيّر KUBECONFIG يُشير إلى مكان آخر: رسائل تم استحضارها بتوجيه سياق bogus ثم ملف فارغ). تحقّق من echo $env:KUBECONFIG (PowerShell) / echo $KUBECONFIG (bash): يجب أن تكون فارغة؛ وإلا عطّل ثم أعد تفعيل Kubernetes في Docker Desktop، فهو يُعيد كتابة السياق.
  • Error from server (NotFound): pods "api-…" not found بينما تظهر الـ Pod في kubectl get pods -n premiers-pas ← نسيت -n premiers-pas: بحث kubectl في default. أضف الخيار. يُظهر kubectl get pods -A كل الـ Pods مع الـ namespace الخاص بها عندما لا تعود تعرف أين وضعت شيئاً.
  • kubectl : Impossible de charger le fichier … completion أو Invoke-Expression : … n'est pas reconnu في $PROFILE ← يُنفَّذ السطر kubectl completion … قبل أن يحتوي PATH على kubectl. ضع السطر $env:Path = … أولاً في الملف الشخصي، كما في الخطوة 8؛ وإذا رفض PowerShell تنفيذ الملف الشخصي، Set-ExecutionPolicy -Scope CurrentUser RemoteSigned.
  • Error from server (AlreadyExists): namespaces "premiers-pas" already exists ← الـ namespace موجود بالفعل، لا شيء لفعله. للانطلاق من الصفر: kubectl delete namespace premiers-pas، انتظر اختفاءه من kubectl get ns (10 إلى 30 ثانية)، أعد إنشاءه.

ما يجب تذكّره

  • تُقرأ kubectl <فعل> <مورد> [اسم] [خيارات]: تُقرأ kubectl get pods -n premiers-pas -o wide كـ«أظهر Pods دُرج premiers-pas، مع الأعمدة الإضافية».
  • يكشف where.exe kubectl / which -a kubectl عن الملف التنفيذي الذي يستجيب؛ ويجب أن يعرض kubectl version عميلاً بفارق إصدار فرعي واحد على الأكثر عن الخادم (v1.34.1 على الجانبين على Docker Desktop 4.68)، وإلا صحّح ترتيب PATH.
  • يجب أن يقول kubectl config current-context بـdocker-desktop؛ ويسرد kubectl config get-contexts الكتل الأخرى المعروفة؛ ولا تُكتب use-context إلا إذا كانت النجمة في المكان الخطأ.
  • الـ namespace دُرج: kubectl create namespace premiers-pas، ثم -n premiers-pas على كل أمر؛ يُخبرك kubectl api-resources بأي الموارد NAMESPACED.
  • kubectl explain pod.spec.containers هو الدليل المدمج، الدقيق لإصدارك؛ يُعطي kubectl get --help أمثلة لكل فعل.
  • الدرس القادم: أول نشر (déploiement) لك في خمس دقائق، مع Service يستجيب على http://localhost:8080 وPod تُبعث من جديد عندما تحذفها.

لمزيد من التعمّق

kubeconfig ليس حكراً على Docker Desktop: يوم يمنحك فريقك وصولاً إلى كتلة اختبار في السحابة، ستحصل على ملف بنفس الصيغة (تكتبه لك az aks get-credentials، aws eks update-kubeconfig، gcloud container clusters get-credentials) وسيعرض kubectl config get-contexts سطراً إضافياً. اتّخذ منذ الآن عادة التحقق من current-context قبل أي delete: لا يسأل الأمر أبداً «هل أنت متأكد؟». المرجع الكامل للأفعال والخيارات وصيغ المخرجات موجود في kubectl Quick Reference (kubernetes.io)، مع نفس أسطر الإكمال التلقائي في مقدّمة الصفحة كما في الخطوة 8.