0%
Installation et configuration

Installation

Un cluster local jetable, et un kubectl qui pointe au bon endroit.

15-20 min

Installation et configuration

Apprendre Kubernetes sur un cluster de production est une mauvaise idée pour une raison simple : vous allez casser des choses, et c’est exactement ce qu’il faut faire. Vous avez besoin d’un cluster qu’on peut détruire d’une commande et recréer en deux minutes, sur lequel une erreur ne coûte rien.

Il existe deux façons d’obtenir ça sur un poste de travail, et le choix n’est pas indifférent. minikube simule un cluster complet dans une machine virtuelle ou un conteneur, avec des extensions prêtes à l’emploi — un tableau de bord, un contrôleur d’entrée, un simulateur d’équilibreur de charge. kind (Kubernetes in Docker) fait tourner chaque nœud comme un conteneur Docker : c’est plus léger, plus rapide à démarrer, et c’est le choix habituel en intégration continue.

Mais avant le cluster, il y a kubectl. C’est le point que les débutants inversent souvent : kubectl n’est pas un composant du cluster, c’est un client HTTP qui parle à une API distante. Il s’installe indépendamment, fonctionne avec n’importe quel cluster, et lit à quel cluster il doit parler dans un fichier de configuration local. La moitié des « ça ne marche pas » des premiers jours vient de là : kubectl interroge un autre cluster que celui qu’on croit.

Cette leçon installe l’outillage, puis s’attarde sur ce fichier de configuration — contextes et namespaces — parce que c’est ce qui vous évitera un jour d’appliquer en production un manifeste destiné à votre poste.

Installer kubectl

kubectl est un binaire unique, sans dépendance. Choisissez la méthode de votre système :

# macOS avec Homebrew
brew install kubectl

# Linux (Debian/Ubuntu) : dépôt officiel Kubernetes
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl gnupg
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.31/deb/Release.key \
  | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.31/deb/ /' \
  | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update && sudo apt-get install -y kubectl
# Windows avec winget
winget install -e --id Kubernetes.kubectl

Vérifiez ensuite l’installation. La commande suivante affiche la version du client, puis tente de joindre un serveur :

kubectl version --client

Tant qu’aucun cluster ne tourne, une commande comme kubectl get nodes échouera avec un message de connexion refusée. C’est normal, et c’est déjà une information utile : le client fonctionne, il n’a simplement personne à qui parler.

Sur quelle version se caler

Kubernetes tolère un écart d’une version mineure entre le client et le serveur. Un kubectl 1.31 parle correctement à un cluster 1.30, 1.31 ou 1.32. Au-delà, certaines ressources peuvent devenir invisibles pour le client sans message clair. En cas de comportement inexplicable, la première vérification est celle-ci :

# Compare la version du client et celle du serveur
kubectl version

Option A : minikube

minikube démarre un cluster à un nœud dans un pilote de virtualisation. Le pilote docker est le plus simple si Docker est déjà installé.

# Installation (macOS)
brew install minikube

# Démarrage : le premier lancement télécharge l'image du nœud, comptez quelques minutes
minikube start --driver=docker --cpus=2 --memory=4096

# minikube a écrit la configuration de connexion pour kubectl : on vérifie
kubectl get nodes

Sortie attendue :

NAME       STATUS   ROLES           AGE   VERSION
minikube   Ready    control-plane   47s   v1.31.0

Un seul nœud, qui porte à la fois le plan de contrôle et vos charges. En production ces rôles sont séparés ; ici la simplification est sans conséquence pour apprendre.

Les commandes de gestion du cycle de vie :

minikube status          # état du cluster et de ses composants
minikube stop            # arrête sans détruire : l'état est conservé
minikube start           # redémarre là où on s'était arrêté
minikube delete          # détruit tout, y compris les données
minikube dashboard       # ouvre l'interface web dans le navigateur

minikube fournit des extensions activables. Deux sont utiles pour la suite du cours :

# Le contrôleur d'entrée, nécessaire pour les Ingress de la leçon 6
minikube addons enable ingress

# Le serveur de métriques, nécessaire pour kubectl top et l'autoscaling
minikube addons enable metrics-server

minikube addons list     # voir tout ce qui est disponible

Option B : kind

kind fait de chaque nœud un conteneur Docker. Démarrage plus rapide, consommation plus faible, et surtout la possibilité de simuler plusieurs nœuds — utile pour observer une reprogrammation de Pod.

# Installation (macOS)
brew install kind

# Cluster à un nœud
kind create cluster --name atelier

# Vérification
kubectl cluster-info --context kind-atelier

Pour un cluster multi-nœuds, kind lit un fichier de configuration. Attention : ce fichier utilise l’API de kind, pas celle de Kubernetes, d’où un apiVersion d’apparence inhabituelle.

# kind-cluster.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: atelier
nodes:
  - role: control-plane
  - role: worker
  - role: worker
kind create cluster --config kind-cluster.yaml

kubectl get nodes
# atelier-control-plane, atelier-worker, atelier-worker2

kind delete cluster --name atelier   # suppression

Une différence à connaître tout de suite : kind ne voit pas les images de votre démon Docker local. Une image construite localement doit être injectée explicitement dans le cluster, sinon le Pod reste bloqué en ErrImagePull alors que docker images la montre bien présente.

docker build -t mon-api:dev .
kind load docker-image mon-api:dev --name atelier

Avec minikube, l’équivalent consiste à pointer le client Docker vers le démon interne du cluster :

eval $(minikube docker-env)
docker build -t mon-api:dev .   # l'image est construite dans le cluster

Dans les deux cas, précisez imagePullPolicy: IfNotPresent dans vos manifestes, faute de quoi Kubernetes tentera de télécharger l’image dev depuis un registre public où elle n’existe pas.

Le fichier kubeconfig et les contextes

Ce fichier est la pièce que l’on ignore trop longtemps. Par défaut ~/.kube/config, il contient trois listes indépendantes :

  • clusters : les adresses des serveurs d’API et leurs certificats ;
  • users : les identités qui servent à s’authentifier ;
  • contexts : les associations (cluster, utilisateur, namespace).

Un contexte est donc simplement le triplet que kubectl utilise pour chaque appel. Changer de contexte, c’est changer de cluster cible — d’où la nécessité de savoir en permanence lequel est actif.

# Lister les contextes ; l'astérisque marque celui qui est actif
kubectl config get-contexts

# Afficher uniquement le nom du contexte actif
kubectl config current-context

# Basculer de cluster
kubectl config use-context kind-atelier

# Voir la configuration complète, secrets masqués
kubectl config view

Prenez l’habitude de vérifier le contexte avant toute commande d’écriture. C’est un réflexe qui paraît excessif jusqu’au jour où il vous évite un kubectl delete sur le mauvais cluster :

# Rendre le contexte visible dans le prompt, ou au minimum le vérifier
kubectl config current-context && kubectl get nodes

Les namespaces

Un namespace est une partition logique du cluster. Il permet d’isoler des ensembles de ressources par équipe, par environnement ou par application, et sert de support aux quotas et aux règles d’accès.

Point important qui surprend souvent : le namespace n’isole pas le réseau. Par défaut, un Pod du namespace dev peut joindre un Pod du namespace prod. Cette isolation-là demande des NetworkPolicy, qui dépendent du greffon réseau installé.

# Les namespaces créés d'office
kubectl get namespaces
# default, kube-system, kube-public, kube-node-lease

kube-system héberge les composants du cluster. On n’y déploie rien de personnel, et on évite d’y appliquer un manifeste par inadvertance — encore une raison de surveiller son contexte.

Créez un namespace de travail, en déclaratif de préférence, pour que sa définition vive dans votre dépôt :

apiVersion: v1
kind: Namespace
metadata:
  name: atelier
  labels:
    environnement: developpement
kubectl apply -f namespace.yaml

# Équivalent impératif, pratique pour du jetable
kubectl create namespace atelier

Toutes les commandes de lecture et d’écriture acceptent -n (ou --namespace). Sans cette option, kubectl utilise le namespace inscrit dans le contexte actif, default la plupart du temps :

kubectl get pods -n atelier          # dans un namespace précis
kubectl get pods --all-namespaces    # partout ; alias : -A

# Changer le namespace par défaut du contexte actif
kubectl config set-context --current --namespace=atelier

Cette dernière commande évite de répéter -n atelier cinquante fois. Elle a une contrepartie : vous ne voyez plus dans la commande où elle s’applique. Vérifiez donc régulièrement :

kubectl config view --minify --output 'jsonpath={..namespace}'

Enfin, une propriété à connaître avant de l’apprendre à ses frais : supprimer un namespace supprime tout ce qu’il contient, en cascade et sans confirmation.

kubectl delete namespace atelier   # Pods, Services, Secrets, PVC : tout part

Vérifier que tout est en place

Enchaînez ces quatre commandes. Si elles répondent toutes, votre environnement est prêt pour la leçon suivante :

# 1. Le client joint bien le serveur d'API
kubectl cluster-info

# 2. Le ou les nœuds sont Ready
kubectl get nodes

# 3. Les composants du plan de contrôle tournent
kubectl get pods -n kube-system

# 4. Un Pod éphémère peut réellement démarrer et sortir sur le réseau
kubectl run test --image=busybox:1.36 --rm -it --restart=Never -- \
  wget -qO- https://kubernetes.io/fr/ | head -n 5

La quatrième mérite un mot : --rm supprime le Pod à la sortie, --restart=Never crée un Pod isolé plutôt qu’un Deployment, et -it attache le terminal. Si elle réussit, le runtime télécharge des images, l’ordonnanceur place les Pods et le réseau sortant fonctionne. Trois validations en une commande.

Autocomplétion et alias

Les noms de ressources générés par Kubernetes sont longs et aléatoires (mon-api-7d4b8c9f5-xk2mp). Sans autocomplétion, vous allez les retaper à la main toute la journée.

# bash : ajouter à ~/.bashrc
source <(kubectl completion bash)
alias k=kubectl
complete -o default -F __start_kubectl k

# zsh : ajouter à ~/.zshrc
source <(kubectl completion zsh)
alias k=kubectl
# PowerShell : ajouter au profil ($PROFILE)
kubectl completion powershell | Out-String | Invoke-Expression
Set-Alias -Name k -Value kubectl

Deux options de lecture à connaître dès maintenant, parce qu’elles servent constamment :

# -o wide ajoute l'IP du Pod et le nœud qui l'héberge
kubectl get pods -o wide

# -w (watch) suit les changements en direct : indispensable pendant un déploiement
kubectl get pods -w

À retenir

  • kubectl est un client indépendant du cluster. Il obéit au contexte actif de ~/.kube/config, et l’erreur la plus fréquente du débutant est de parler à un autre cluster que celui qu’il croit.
  • minikube offre un cluster complet avec extensions (ingress, metrics-server) ; kind est plus léger et permet de simuler plusieurs nœuds. Les deux conviennent pour ce cours.
  • Une image construite localement n’est pas visible par le cluster : passez par kind load docker-image ou eval $(minikube docker-env), et déclarez imagePullPolicy: IfNotPresent.
  • Un namespace partitionne les ressources et sert de support aux quotas, mais n’isole pas le réseau sans NetworkPolicy. Le supprimer détruit tout son contenu en cascade.
  • Vérifiez toujours un déploiement sur l’état observé (kubectl get, kubectl describe), et le contexte actif avant toute commande d’écriture.

Conseil : détruisez et recréez votre cluster local au moins une fois. Savoir qu’on peut repartir de zéro en deux minutes change complètement le rapport à l’expérimentation.

Commentaires

Les commentaires sont alimentés par GitHub Discussions

Connectez-vous avec GitHub pour participer à la discussion

Lien copié !