kubectl, η τηλεχειριστήριο του cluster

13 λεπτά
Κοινό
αρχάριος, Kubernetes του Docker Desktop ενεργοποιημένο (μάθημα 02)
Διάρκεια
35 έως 45 λεπτά
Ενότητα
1/8
Στοχευόμενη δεξιότητα
να ξέρεις ποιο εκτελέσιμο kubectl απαντά και σε ποιο cluster μιλά, να διορθώνεις μια προειδοποίηση έκδοσης, να διαβάζεις μια εντολή kubectl σαν φράση (ρήμα, πόρος, όνομα, επιλογές) και να δημιουργείς το πρώτο σου namespace

Σε μία εικόνα

Το kubectl είναι ένα τηλεχειριστήριο γενικής χρήσης. Δεν κάνει τίποτα από μόνο του: στέλνει εντολές σε μια συσκευή, τον API server του μαθήματος 01, σε HTTPS στη θύρα 6443. Έχει έναν επιλογέα πηγής, το context, που λέει ποιο cluster να στοχεύσει (docker-desktop, ένα παλιό minikube, η παραγωγή της επιχείρησής σου): πάτα «Play» στοχεύοντας τη λάθος συσκευή και τίποτα δεν κουνιέται, πιστεύεις ότι το τηλεχειριστήριο χάλασε. Έχει μπαταρίες μιας ορισμένης τάσης: ένα kubectl 1.30 μπροστά σε ένα cluster 1.34 δουλεύει περίπου, αλλά σε προειδοποιεί ότι δεν εγγυάται πια τίποτα. Και μιλά μια σταθερή γραμματική: ένα ρήμα (get), έναν πόρο (pods), μερικές φορές ένα όνομα, έπειτα επιλογές (-n premiers-pas -o wide). Σε σαράντα λεπτά θα ξέρεις να διαβάζεις αυτή τη φράση με την πρώτη, θα έχεις διορθώσει μια πραγματική παγίδα έκδοσης, και θα έχεις ανοίξει το δικό σου συρτάρι στο cluster: το namespace premiers-pas, όπου θα συμβεί όλη η ενότητα.

Πώς λειτουργεί

Το kubectl διαβάζει ένα μόνο αρχείο στην εκκίνηση: το ~/.kube/config (C:\Users\<εσύ>\.kube\config σε Windows), το kubeconfig. Περιέχει τρεις λίστες: clusters (μια διεύθυνση API και το πιστοποιητικό που επιτρέπει να την αναγνωρίσεις), users (τα διαπιστευτήρια: εδώ ένα πιστοποιητικό πελάτη που παρήγαγε το Docker Desktop) και contexts, που συνδέουν ένα cluster με έναν χρήστη, με ενδεχομένως ένα προεπιλεγμένο namespace. Η γραμμή current-context ορίζει αυτό που χρησιμοποιεί κάθε εντολή. Το Docker Desktop γράφει εκεί docker-desktop κατά την ενεργοποίηση· το minikube, το kind ή ένας πάροχος cloud προσθέτουν τα δικά τους, και έτσι ένα ίδιο kubectl χειρίζεται πολλά clusters.

Κάθε εντολή διαβάζεται σαν φράση: kubectl <ρήμα> <πόρος> [όνομα] [επιλογές]. Το ρήμα λέει τι να κάνεις· ο πόρος, σε ποιον τύπο αντικειμένου· το όνομα στοχεύει ένα συγκεκριμένο αντικείμενο (χωρίς όνομα, το ρήμα εφαρμόζεται σε όλα αυτά του namespace)· οι επιλογές διευκρινίζουν το συρτάρι (-n), τη μορφή (-o), την εμβέλεια (-A) ή τη ζωντανή παρακολούθηση (-w). Οι πόροι δέχονται συντομεύσεις που το kubectl api-resources λιστάρει στη στήλη του SHORTNAMES.

ΚομμάτιΠαραδείγματαΡόλος
ρήμαget, describe, create, apply, delete, logs, exec, scale, explainη ενέργεια που ζητείται από το API
πόροςpods (po), deployments (deploy), services (svc), namespaces (ns), nodes (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 είναι τα συρτάρια του cluster: ένα ίδιο όνομα Pod ή Service μπορεί να υπάρχει σε δύο namespaces χωρίς σύγκρουση, τα quotas και τα δικαιώματα δεσμεύονται στο namespace, και το kubectl delete namespace αδειάζει όλα με μία κίνηση. Το cluster γεννιέται με default, kube-system (το control plane), kube-public και kube-node-lease. Αυτό το μάθημα δεν γράφει ποτέ στο default: κάθε ενότητα έχει το namespace της, και κάθε εντολή φέρει -n. Να ξεχάσεις το -n σημαίνει να ψάχνεις το Pod σου στο λάθος συρτάρι: «δεν υπάρχει», ενώ τρέχει μια χαρά δίπλα. Θα προκαλέσεις αυτό το λάθος στην καθοδηγούμενη πρακτική για να μην σε ξαναπιάσει ποτέ.

Τι θέλεις να μάθειςΕντολήΜιλά στο cluster;
ποιο εκτελέσιμο απαντάwhere.exe kubectl (Windows) / which -a kubectl (bash)όχι
έκδοση πελάτη και serverkubectl versionναι
σε ποιο cluster δείχνωkubectl config current-contextόχι
όλα τα γνωστά clusterskubectl 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. Καλούμενο με την πλήρη διαδρομή του μπροστά στο cluster 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

    Τι πρέπει να δεις: η εντολή απαντά παρ' όλα αυτά (το cluster είναι προσβάσιμο), αλλά η προειδοποίηση είναι σαφής: το Kubernetes εγγυάται το kubectl μόνο σε απόσταση μίας δευτερεύουσας έκδοσης από τον server (1.33, 1.34 ή 1.35 για ένα cluster 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

    Τι πρέπει να δεις: πελάτης και server ευθυγραμμισμένοι στο v1.34.1, καμία προειδοποίηση πια. Για να κάνεις την αλλαγή μόνιμη σε Windows: Ρυθμίσεις → Σύστημα → Πληροφορίες συστήματος → Ρυθμίσεις συστήματος για προχωρημένους → Μεταβλητές περιβάλλοντος → Path του χρήστη σου → ανέβασε το C:\Program Files\Docker\Docker\resources\bin στην κορυφή (ή διάγραψε την καταχώρηση του παλιού kubectl), έπειτα ξανάνοιξε το τερματικό. Σε macOS/Linux, διάγραψε το διπλότυπο (brew uninstall kubectl) ή βάλε το /usr/local/bin πιο μπροστά στο ~/.zshrc σου. Το script του kit το επαληθεύει για σένα: το .\labo.ps1 prerequis εμφανίζει ✘ kubectl client v1.30.0 trop ancien (minimum 1.33) — … όσο η σειρά είναι λάθος.

  4. Διάβασε το kubeconfig και το τρέχον context. Δύο εντολές που δεν αγγίζουν το cluster.

    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. Το μηχάνημα του μαθήματος κρατά ένα context minikube από ένα παλιό σβηστό cluster: είναι το είδος του υπολείμματος που κάνει κάποιον να λέει «το kubectl δεν δουλεύει πια» όταν γίνεται τρέχον κατά λάθος. Αν σε σένα το αστεράκι είναι αλλού, το kubectl config use-context docker-desktop το μετακινεί (μην το πληκτρολογήσεις αν είναι ήδη στη σωστή θέση: η εντολή ξαναγράφει το ~/.kube/config). Η άδεια στήλη NAMESPACE σημαίνει «default εκτός αν δώσω -n»· δεν θα τη γεμίσουμε, το μάθημα θέλει το -n να γίνει αντανακλαστικό.

  5. Διάβασε μια εντολή σαν φράση, με το explain. Το εγχειρίδιο είναι μέσα στο cluster: το 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 δεν είναι τυπικά, αλλά ένα container χωρίς εικόνα δεν ξεκινά), και η γραμμή 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 (ανήκουν σε ολόκληρο το cluster, το -n δεν έχει νόημα).

  7. Δημιούργησε το συρτάρι σου: το namespace premiers-pas. Πρώτη εντολή που γράφει στο cluster.

    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.

    Τι πρέπει να δεις: η τυπική απάντηση μιας δημιουργίας, τύπος/όνομα created· ένα namespace Active αμέσως· και το μήνυμα ενός άδειου συρταριού, No resources found in premiers-pas namespace.: δεν είναι λάθος, είναι η σωστή απάντηση στο «τι υπάρχει εδώ;» όταν δεν υπάρχει τίποτα. Αν η πρώτη εντολή απαντήσει Error from server (AlreadyExists), το namespace υπάρχει ήδη (ίσως προχώρησες στο μάθημα 04 νωρίτερα): συνέχισε.

  8. Κάνε τη ζωή σου εύκολη: alias και αυτόματη συμπλήρωση. 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, το προεπιλεγμένο shell του 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 → το ζητούμενο context δεν υπάρχει στο kubeconfig που διαβάζεται, ή αυτό το αρχείο είναι άδειο (ένα άλλο εργαλείο ξαναέγραψε το ~/.kube/config, ή η μεταβλητή KUBECONFIG δείχνει αλλού: μηνύματα που προκλήθηκαν στοχεύοντας ένα context bogus και έπειτα ένα άδειο αρχείο). Έλεγξε echo $env:KUBECONFIG (PowerShell) / echo $KUBECONFIG (bash): πρέπει να είναι άδεια· αλλιώς απενεργοποίησε και ξαναενεργοποίησε το Kubernetes στο Docker Desktop, ξαναγράφει το context.
  • 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 πρέπει να δείχνει έναν πελάτη το πολύ μία δευτερεύουσα έκδοση μακριά από τον server (v1.34.1 και στις δύο πλευρές σε Docker Desktop 4.68), αλλιώς διόρθωσε τη σειρά του PATH.
  • Το kubectl config current-context πρέπει να λέει docker-desktop· το kubectl config get-contexts λιστάρει τα άλλα γνωστά clusters· το use-context πληκτρολογείται μόνο αν το αστεράκι είναι στη λάθος θέση.
  • Ένα namespace είναι ένα συρτάρι: kubectl create namespace premiers-pas, έπειτα -n premiers-pas σε κάθε εντολή· το kubectl api-resources σου λέει ποιοι πόροι είναι NAMESPACED.
  • Το kubectl explain pod.spec.containers είναι το ενσωματωμένο εγχειρίδιο, ακριβές για την έκδοσή σου· το kubectl get --help δίνει παραδείγματα για κάθε ρήμα.
  • Επόμενο μάθημα: η πρώτη σου ανάπτυξη σε πέντε λεπτά, με ένα Service που απαντά στο http://localhost:8080 και ένα Pod που ξαναγεννιέται όταν το διαγράφεις.

Για να πας παραπέρα

Το kubeconfig δεν είναι αποκλειστικό του Docker Desktop: τη μέρα που η ομάδα σου θα σου δώσει πρόσβαση σε ένα cluster δοκιμών στο cloud, θα λάβεις ένα αρχείο ίδιας μορφής (τα 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.