kubectl est une télécommande universelle. Elle ne fait rien par elle-même : elle envoie des ordres à un appareil, l'API server de la leçon 01, en HTTPS sur le port 6443. Elle a un sélecteur de source, le contexte, qui dit quel cluster viser (docker-desktop, un vieux minikube, la production de ton entreprise) : appuie sur « Play » en visant le mauvais appareil et rien ne bouge, tu crois la télécommande cassée. Elle a des piles d'une certaine tension : un kubectl 1.30 devant un cluster 1.34 marche à peu près, mais te prévient qu'il ne garantit plus rien. Et elle parle une grammaire fixe : un verbe (get), une ressource (pods), parfois un nom, puis des options (-n premiers-pas -o wide). Dans quarante minutes tu sauras lire cette phrase du premier coup, tu auras corrigé un vrai piège de version, et tu auras ouvert ton propre tiroir dans le cluster : le namespace premiers-pas, où tout le module va se passer.
kubectl lit un seul fichier au démarrage : ~/.kube/config (C:\Users\<toi>\.kube\config sous Windows), le kubeconfig. Il contient trois listes : des clusters (une adresse d'API et le certificat qui permet de la reconnaître), des users (les identifiants : ici un certificat client généré par Docker Desktop) et des contexts, qui associent un cluster à un utilisateur, avec éventuellement un namespace par défaut. La ligne current-context désigne celui qu'utilise chaque commande. Docker Desktop y écrit docker-desktop à l'activation ; minikube, kind ou un fournisseur cloud ajoutent les leurs, et c'est ainsi qu'un même kubectl pilote plusieurs clusters.
Chaque commande se lit comme une phrase : kubectl <verbe> <ressource> [nom] [options]. Le verbe dit quoi faire ; la ressource, sur quel type d'objet ; le nom cible un objet précis (sans nom, le verbe s'applique à tous ceux du namespace) ; les options précisent le tiroir (-n), le format (-o), la portée (-A) ou le suivi en direct (-w). Les ressources acceptent des raccourcis que kubectl api-resources liste dans sa colonne SHORTNAMES.
| Morceau | Exemples | Rôle |
|---|---|---|
| verbe | get, describe, create, apply, delete, logs, exec, scale, explain | l'action demandée à l'API |
| ressource | pods (po), deployments (deploy), services (svc), namespaces (ns), nodes (no) | le type d'objet ; pod/api équivaut à pod api |
| nom | api, api-9bfb55fc6-988xh, docker-desktop | un objet précis ; absent = tous les objets du namespace |
-n <ns> | -n premiers-pas | le namespace visé ; sans lui, default (le cours ne s'en sert jamais) |
-A | kubectl get pods -A | tous les namespaces (ajoute une colonne NAMESPACE) |
-o wide / -o yaml / -o json / -o name | kubectl get pods -o wide | plus de colonnes / l'objet complet tel que l'API le stocke / idem en JSON / seulement type/nom |
-w | kubectl get pods -n premiers-pas -w | reste connecté et affiche chaque changement (Ctrl+C pour sortir) |
--help | kubectl get --help | l'aide de n'importe quel verbe, avec exemples |
Les namespaces sont les tiroirs du cluster : un même nom de Pod ou de Service peut exister dans deux namespaces sans conflit, les quotas et les droits s'attachent au namespace, et kubectl delete namespace vide tout d'un coup. Le cluster naît avec default, kube-system (le control plane), kube-public et kube-node-lease. Ce cours n'écrit jamais dans default : chaque module a son namespace, et chaque commande porte -n. Oublier -n, c'est chercher ton Pod dans le mauvais tiroir : il « n'existe pas », alors qu'il tourne très bien à côté. Tu provoqueras cette erreur en pratique guidée pour ne plus jamais t'y faire prendre.
| Ce que tu veux savoir | Commande | Parle au cluster ? |
|---|---|---|
| quel binaire répond | where.exe kubectl (Windows) / which -a kubectl (bash) | non |
| version du client et du serveur | kubectl version | oui |
| vers quel cluster je pointe | kubectl config current-context | non |
| tous les clusters connus | kubectl config get-contexts | non |
| que contient un champ YAML | kubectl explain deployment.spec.replicas | oui |
| tous les types d'objets et leurs raccourcis | kubectl api-resources | oui |
Sous PowerShell, la machine du cours garde volontairement un piège : trois kubectl dans le PATH, dont un vieux 1.30 installé à la main avant Docker Desktop. Chez toi il n'y en a sans doute qu'un ; fais quand même les étapes 1 à 3, elles t'éviteront une heure de confusion le jour où tu installeras un second outil.
Trouver quel kubectl répond. Le shell prend le premier binaire trouvé dans l'ordre du PATH.
where.exe kubectlwhich -a kubectlSortie réelle (Windows) :
C:\Program Files\Docker\Docker\resources\bin\kubectl.exe
C:\Users\<toi>\Documents\kubectl\kubectl.exe
C:\kubectl\kubectl.exeCe qu'il faut voir : la première ligne est celle qui s'exécute quand tu tapes kubectl. Ici c'est celle de Docker Desktop, parce que le PATH a été réordonné ; l'étape 2 montre ce qui se passe quand ce n'est pas le cas. Sous macOS, attends-toi à /usr/local/bin/kubectl (Docker Desktop) et peut-être /opt/homebrew/bin/kubectl (Homebrew).
Regarde bien ce qui va se passer : lancer le vieux kubectl exprès. Sur la machine du cours, le deuxième binaire est un 1.30. Appelé par son chemin complet devant le cluster 1.34 :
& "C:\Users\<toi>\Documents\kubectl\kubectl.exe" versionSortie réelle :
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 +/-1Ce qu'il faut voir : la commande répond quand même (le cluster est joignable), mais l'avertissement est explicite : Kubernetes ne garantit kubectl qu'à une version mineure d'écart du serveur (1.33, 1.34 ou 1.35 pour un cluster 1.34). Au-delà, certaines sous-commandes se comportent bizarrement ou ignorent des champs récents. Si tu vois cette ligne chez toi, c'est ce piège : un vieux kubectl (Homebrew, Chocolatey, téléchargement manuel) passe devant celui de Docker Desktop.
Corriger l'ordre du PATH. Pour la session PowerShell en cours, puis vérifier :
$env:Path = "C:\Program Files\Docker\Docker\resources\bin;" + $env:Path
kubectl versionSortie réelle :
Client Version: v1.34.1
Kustomize Version: v5.7.1
Server Version: v1.34.1Ce qu'il faut voir : client et serveur alignés sur v1.34.1, plus d'avertissement. Pour rendre le changement permanent sous Windows : Paramètres → Système → Informations système → Paramètres système avancés → Variables d'environnement → Path de ton utilisateur → remonte C:\Program Files\Docker\Docker\resources\bin en tête (ou supprime l'entrée du vieux kubectl), puis rouvre le terminal. Sous macOS/Linux, supprime le doublon (brew uninstall kubectl) ou mets /usr/local/bin avant dans ton ~/.zshrc. Le script du kit le vérifie pour toi : .\labo.ps1 prerequis affiche ✘ kubectl client v1.30.0 trop ancien (minimum 1.33) — … tant que l'ordre est mauvais.
Lire le kubeconfig et le contexte courant. Deux commandes qui ne touchent pas au cluster.
kubectl config get-contexts
kubectl config current-contextSortie réelle :
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* docker-desktop docker-desktop docker-desktop
minikube minikube minikube default
docker-desktopCe qu'il faut voir : l'étoile sur docker-desktop. La machine du cours garde un contexte minikube d'un ancien cluster éteint : c'est le genre de reste qui fait dire « kubectl ne marche plus » quand il devient courant par accident. Si chez toi l'étoile est ailleurs, kubectl config use-context docker-desktop la déplace (ne le tape pas si elle est déjà au bon endroit : la commande réécrit ~/.kube/config). La colonne NAMESPACE vide signifie « default sauf si je passe -n » ; on ne la remplira pas, le cours veut que -n soit un réflexe.
Lire une commande comme une phrase, avec explain. Le manuel est dans le cluster : kubectl explain demande à l'API server la documentation d'un type ou d'un champ, pour la version exacte que tu utilises.
kubectl explain deployment.spec.replicasSortie réelle :
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.Puis descends d'un niveau dans un Pod :
kubectl explain pod.spec.containersSortie réelle (raccourcie : la liste complète compte une trentaine de champs) :
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. …Ce qu'il faut voir : <[]Container> dit « une liste », -required- marque les champs obligatoires (name ; image ne l'est pas formellement, mais un conteneur sans image ne démarre pas), et la ligne imagePullPolicy … Defaults to Always if :latest tag is specified explique pourquoi ce cours n'écrit jamais :latest : tu ne saurais plus quelle version tourne, et Kubernetes irait la retélécharger à chaque démarrage.
Découvrir les ressources et leurs raccourcis. La liste complète dépasse cinquante lignes ; filtre les types que tu croiseras dans les trois premiers modules.
kubectl api-resources | Select-String -Pattern '^(pods|deployments|services|namespaces|nodes|configmaps|secrets|replicasets|jobs|cronjobs|ingresses)\s'kubectl api-resources | grep -E '^(pods|deployments|services|namespaces|nodes|configmaps|secrets|replicasets|jobs|cronjobs|ingresses) 'Sortie réelle :
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 IngressCe qu'il faut voir : la colonne SHORTNAMES (po, deploy, svc, ns, no, cm, rs), la colonne APIVERSION que tu recopieras en tête de chaque YAML (v1 pour un Pod, apps/v1 pour un Deployment), et surtout NAMESPACED : true pour un Pod ou un Service (ils vivent dans un tiroir, -n obligatoire), false pour namespaces et nodes (ils appartiennent au cluster entier, -n n'a pas de sens).
Créer ton tiroir : le namespace premiers-pas. Première commande qui écrit dans le cluster.
kubectl create namespace premiers-pas
kubectl get namespace premiers-pas
kubectl get pods -n premiers-pasSortie réelle :
namespace/premiers-pas created
NAME STATUS AGE
premiers-pas Active 0s
No resources found in premiers-pas namespace.Ce qu'il faut voir : la réponse type d'une création, type/nom created ; un namespace Active immédiatement ; et le message d'un tiroir vide, No resources found in premiers-pas namespace. : ce n'est pas une erreur, c'est la réponse correcte à « qu'y a-t-il ici ? » quand il n'y a rien. Si la première commande répond Error from server (AlreadyExists), le namespace existe déjà (tu as peut-être pris de l'avance sur la leçon 04) : continue.
Se faire la vie facile : alias et autocomplétion. k à la place de kubectl et la touche Tab qui complète verbes, ressources et noms d'objets. Ajoute ces lignes à ton profil pour qu'elles se rechargent à chaque terminal.
notepad $PROFILEColle dans le fichier ouvert (crée-le si Notepad le propose) :
$env:Path = "C:\Program Files\Docker\Docker\resources\bin;" + $env:Path
kubectl completion powershell | Out-String | Invoke-Expression
Set-Alias k kubectlSous bash (fichier ~/.bashrc) :
source <(kubectl completion bash)
alias k=kubectl
complete -o default -F __start_kubectl kSous zsh (~/.zshrc, le shell par défaut de macOS) :
source <(kubectl completion zsh)
alias k=kubectl
compdef __start_kubectl kRouvre le terminal, puis tape kubectl get dep et appuie sur Tab. Résultat réel sous PowerShell : la ligne devient kubectl get deployments.apps. Tape ensuite k get nodes :
NAME STATUS ROLES AGE VERSION
docker-desktop Ready control-plane 18d v1.34.1Ce qu'il faut voir : k répond exactement comme kubectl. Le cours continue d'écrire kubectl en entier pour rester lisible ; toi, tape k. Rien à nettoyer : le namespace premiers-pas reste en place, la leçon 04 s'en sert tout de suite.
WARNING: version difference between client (1.30) and server (1.34) exceeds the supported minor version skew of +/-1 → un vieux kubectl passe devant celui de Docker Desktop dans le PATH. where.exe kubectl / which -a kubectl pour le voir, étape 3 pour corriger. La commande a quand même fonctionné : l'avertissement ne bloque pas, il prévient.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 est arrêté ou Kubernetes est désactivé (leçon 02). Ce n'est jamais kubectl lui-même : kubectl version --client répond toujours, kubectl version non.Error in configuration: context was not found for specified context: … ou kubectl config current-context qui renvoie error: current-context is not set → le contexte demandé n'existe pas dans le kubeconfig lu, ou ce fichier est vide (un autre outil a réécrit ~/.kube/config, ou la variable KUBECONFIG pointe ailleurs : messages provoqués en visant un contexte bogus puis un fichier vide). Vérifie echo $env:KUBECONFIG (PowerShell) / echo $KUBECONFIG (bash) : elle doit être vide ; sinon désactive puis réactive Kubernetes dans Docker Desktop, il réécrit le contexte.Error from server (NotFound): pods "api-…" not found alors que le Pod apparaît dans kubectl get pods -n premiers-pas → tu as oublié -n premiers-pas : kubectl a cherché dans default. Ajoute l'option. kubectl get pods -A montre tous les Pods avec leur namespace quand tu ne sais plus où tu as rangé quelque chose.kubectl : Impossible de charger le fichier … completion ou Invoke-Expression : … n'est pas reconnu dans $PROFILE → la ligne kubectl completion … s'exécute avant que le PATH contienne kubectl. Mets la ligne $env:Path = … en premier dans le profil, comme à l'étape 8 ; et si PowerShell refuse d'exécuter le profil, Set-ExecutionPolicy -Scope CurrentUser RemoteSigned.Error from server (AlreadyExists): namespaces "premiers-pas" already exists → le namespace est déjà là, rien à faire. Pour repartir de zéro : kubectl delete namespace premiers-pas, attends qu'il disparaisse de kubectl get ns (10 à 30 s), recrée-le.kubectl <verbe> <ressource> [nom] [options] : kubectl get pods -n premiers-pas -o wide se lit « montre les Pods du tiroir premiers-pas, avec les colonnes en plus ».where.exe kubectl / which -a kubectl révèle le binaire qui répond ; kubectl version doit afficher un client à au plus une version mineure du serveur (v1.34.1 des deux côtés sur Docker Desktop 4.68), sinon corrige l'ordre du PATH.kubectl config current-context doit dire docker-desktop ; kubectl config get-contexts liste les autres clusters connus ; use-context ne se tape que si l'étoile est au mauvais endroit.kubectl create namespace premiers-pas, puis -n premiers-pas sur chaque commande ; kubectl api-resources te dit quelles ressources sont NAMESPACED.kubectl explain pod.spec.containers est le manuel intégré, exact pour ta version ; kubectl get --help donne des exemples pour chaque verbe.http://localhost:8080 et un Pod qui renaît quand tu le supprimes.Le kubeconfig n'est pas réservé à Docker Desktop : le jour où ton équipe te donne accès à un cluster de test dans le cloud, tu recevras un fichier du même format (az aks get-credentials, aws eks update-kubeconfig, gcloud container clusters get-credentials l'écrivent pour toi) et kubectl config get-contexts affichera une ligne de plus. Prends dès maintenant l'habitude de vérifier current-context avant tout delete : la commande ne demande jamais « es-tu sûr ? ». La référence complète des verbes, options et formats de sortie est sur kubectl Quick Reference (kubernetes.io), avec en tête de page les mêmes lignes d'autocomplétion qu'à l'étape 8.