Introduction
Les Services Kubernetes sont essentiels pour connecter les applications exécutées dans des pods. Ils fournissent des identités réseau stables, un équilibrage de charge et une découverte de services, mais leur comportement peut être subtil, notamment lors du dépannage du DNS, de la sélection des endpoints ou des politiques réseau. Mettre en place un laboratoire local dédié vous permet d'expérimenter en toute sécurité, de casser des choses volontairement et de développer des réflexes pour le dépannage en production. Ce guide décrit un processus reproductible pour créer un environnement Kubernetes minimal sur votre ordinateur portable, déployer des charges de travail d'exemple et explorer le comportement des Services avec des commandes concrètes et des sorties attendues. À la fin, vous disposerez d'un laboratoire que vous pourrez détruire et recréer en quelques minutes, ainsi qu'un ensemble d'exercices qui renforcent la compréhension du fonctionnement interne des Services.
Une configuration claire de Services Kubernetes réduit les reprises en séparant la recherche, le brief, la génération de l'article, l'évaluation, l'approbation et la publication. Dans ce contexte, cela signifie séparer les étapes d'apprentissage : provisionnement de l'environnement, déploiement de la charge de travail, création du Service et vérification. Pour un laboratoire local de Services Kubernetes, le premier pilote utile doit être étroit, mesurable et facile à inspecter localement avant le déploiement. Nous suivrons ce principe en commençant par un cluster à nœud unique et une application simple.
Inventaire des versions et de l'environnement
Avant de créer des ressources, documentez les versions et la topologie. Cela évite les confusions lorsque les commandes se comportent différemment selon les versions de Kubernetes. Le laboratoire décrit ici utilise les composants suivants :
| Composant | Version | Objectif |
|---|---|---|
| Kubernetes | 1.28 (ou dernière version stable) | Orchestration de base |
| kubectl | 1.28 | Client CLI |
| minikube | 1.32 | Cluster local à nœud unique |
| Runtime de conteneurs | Docker 24.x ou containerd | Exécute les pods |
| Application d'exemple | nginx:1.25 | Serveur web simple |
Ces versions sont des exemples construits et peuvent être ajustées. La topologie est un cluster à nœud unique avec un plan de contrôle et aucun nœud worker (par défaut avec minikube). Cela suffit pour les expériences sur les Services car tous les pods peuvent être planifiés sur le même nœud.
Prérequis
- Une machine avec au moins 2 CPU, 4 Go de RAM et 20 Go d'espace disque libre.
- Un hyperviseur comme VirtualBox, Hyper-V ou KVM, ou un runtime de conteneurs comme Docker.
- kubectl installé et dans votre PATH. Vérifiez avec
kubectl version --client. - minikube installé. Vérifiez avec
minikube version.
Installez minikube et kubectl à l'aide de votre gestionnaire de paquets ou depuis la documentation officielle. Pour ce guide, nous supposons que les deux sont installés.
Chemin de configuration sûr
Nous procéderons par petites étapes réversibles. Chaque étape est indépendante et peut être annulée en supprimant la ressource créée.
Étape 1 : Démarrer le cluster
Démarrez minikube avec une version spécifique de Kubernetes pour correspondre à votre documentation. Cela crée un nouveau cluster :
minikube start --kubernetes-version=v1.28.0
La sortie attendue comprend des lignes comme :
* minikube v1.32.0 on Ubuntu 22.04
* Using the docker driver based on existing profile
* Starting control plane node minikube in cluster minikube
* Pulling base image ...
* Creating docker container (CPUs=2, Memory=4000MB) ...
* Preparing Kubernetes v1.28.0 on Docker 24.0.7 ...
* Verifying Kubernetes components...
- Using image gcr.io/k8s-minikube/storage-provisioner: v5
* Enabled addons: storage-provisioner, default-storageclass
* kubectl not found. If you need it, try: 'minikube kubectl -- get pods -A'
* Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default
Vérifiez que le cluster est accessible :
kubectl cluster-info
Sortie attendue :
Kubernetes control plane is running at https://192.168.49.2:8443
CoreDNS is running at https://192.168.49.2:8443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
Étape 2 : Créer un namespace
Utilisez un namespace dédié pour isoler les ressources du laboratoire et simplifier le nettoyage.
kubectl create namespace service-lab
Sortie attendue : namespace/service-lab created
Étape 3 : Déployer une application backend
Créez un Deployment avec deux réplicas nginx à l'aide d'une commande impérative. Les pods serviront de backend pour notre Service.
kubectl create deployment nginx-deployment --image=nginx:1.25 --replicas=2 --namespace=service-lab
Sortie attendue : deployment.apps/nginx-deployment created
Vérifiez l'état des pods :
kubectl get pods -n service-lab -o wide
Sortie attendue (les noms et les IP varieront) :
NAME READY STATUS RESTARTS AGE IP NODE
nginx-deployment-7c79c4bf97-9x6k2 1/1 Running 0 10s 10.244.0.5 minikube
nginx-deployment-7c79c4bf97-j2p8t 1/1 Running 0 10s 10.244.0.6 minikube
Étape 4 : Créer un Service ClusterIP
Exposez le Deployment en tant que Service ClusterIP à l'aide de kubectl expose. C'est le type de Service par défaut et il fournit un équilibrage de charge interne. Le Service sélectionne automatiquement les pods en fonction des libellés du Deployment.
kubectl expose deployment nginx-deployment --name=nginx-service --namespace=service-lab --type=ClusterIP --port=80 --target-port=80
Sortie attendue : service/nginx-service exposed
Inspectez le Service :
kubectl get service nginx-service -n service-lab -o wide
Sortie attendue :
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
nginx-service ClusterIP 10.96.100.200 <none> 80/TCP 5s app=nginx-deployment
Notez que CLUSTER-IP est un exemple ; votre cluster en attribuera une différente.
Étape 5 : Créer un Service NodePort (optionnel)
Pour accéder au Service depuis l'extérieur du cluster, exposez le Deployment en tant que Service NodePort. Kubernetes attribuera un port aléatoire dans la plage NodePort. Si vous avez besoin d'un port spécifique, vous pouvez utiliser kubectl create service nodeport avec une configuration supplémentaire, mais pour ce laboratoire, un port aléatoire suffit.
kubectl expose deployment nginx-deployment --name=nginx-nodeport --namespace=service-lab --type=NodePort --port=80 --target-port=80
Obtenez le service :
kubectl get service nginx-nodeport -n service-lab
Sortie attendue (le port du nœud est attribué dynamiquement) :
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-nodeport NodePort 10.96.150.77 <none> 80:3xxxx/TCP 10s
Vous pouvez accéder à la page d'accueil de nginx en ouvrant http://<minikube-ip>:<nodePort> dans un navigateur, ou utiliser minikube service nginx-nodeport -n service-lab pour ouvrir un tunnel.
Vérification et diagnostics
Maintenant que les Services sont en cours d'exécution, nous vérifions leur comportement à l'aide de commandes kubectl et d'une communication directe pod-à-service.
Vérifier les endpoints
Les endpoints sont les IP réelles des pods qui soutiennent le Service. Vérifiez que les deux IP de pods sont répertoriées :
kubectl get endpoints nginx-service -n service-lab
Sortie attendue :
NAME ENDPOINTS AGE
nginx-service 10.244.0.5:80,10.244.0.6:80 2m
Tester le Service depuis un pod
Nous pouvons exécuter un pod temporaire et utiliser curl pour accéder au Service par son nom DNS. Cela teste la résolution DNS et l'équilibrage de charge.
kubectl run -it --rm --restart=Never --image=curlimages/curl curl-test -n service-lab -- sh
À l'intérieur du pod, exécutez :
curl http://nginx-service
Sortie attendue : Le contenu HTML de la page d'accueil de nginx. Appuyez sur Ctrl-D pour quitter ; le pod sera supprimé.
Testez l'équilibrage de charge en exécutant curl plusieurs fois et en observant les journaux des pods. Dans des terminaux séparés, surveillez les journaux :
kubectl logs -f -l app=nginx-deployment -n service-lab
Lorsque vous émettez des curls, vous devriez voir des entrées de journal alterner entre les deux pods nginx, démontrant une distribution round-robin.
Inspecter les détails du Service
Décrivez le Service pour voir sa configuration et ses événements :
kubectl describe service nginx-service -n service-lab
La sortie attendue comprend :
Name: nginx-service
Namespace: service-lab
Labels: <none>
Annotations: <none>
Selector: app=nginx-deployment
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.96.100.200
IPs: 10.96.100.200
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.0.5:80,10.244.0.6:80
Session Affinity: None
Events: <none>
Vérifier la résolution DNS
Kubernetes crée une entrée DNS pour chaque Service sous la forme <service-name>.<namespace>.svc.cluster.local. Testez-la depuis le pod curl :
nslookup nginx-service.service-lab.svc.cluster.local
La sortie attendue comprend le ClusterIP :
Server: 10.96.0.10
Address: 10.96.0.10#53
Name: nginx-service.service-lab.svc.cluster.local
Address: 10.96.100.200
Pièges courants et comment les éviter
Travailler avec des Services Kubernetes localement révèle souvent des erreurs qui se produisent également en production. Voici les plus fréquentes, pourquoi elles surviennent et comment s'en remettre.
Piège 1 : Inadéquation du sélecteur menant à des endpoints vides
Pourquoi cela arrive : Le sélecteur du Service ne correspond à aucun libellé de pod. Cela peut être dû à une faute de frappe, à l'utilisation de clés de libellés différentes ou à l'application du Service avant que le Deployment ne soit prêt.
Comment détecter : Exécutez kubectl get endpoints nginx-service -n service-lab. Si la colonne ENDPOINTS affiche <none>, le Service n'a aucun pod de soutien.
Comment récupérer : Comparez le sélecteur du Service avec les libellés des pods :
kubectl get pods -n service-lab --show-labels
kubectl get service nginx-service -n service-lab -o yaml | grep -A2 selector
Corrigez l'inadéquation en mettant à jour soit le sélecteur du Service, soit les libellés du modèle de pod, puis réappliquez. Une solution rapide consiste à s'assurer que les deux utilisent app: nginx-deployment.
Piège 2 : Échec de la résolution DNS à l'intérieur des pods
Pourquoi cela arrive : Les pods CoreDNS peuvent être en panne, ou la politique DNS du pod client est définie sur Default au lieu de ClusterFirst, ce qui l'amène à contourner le DNS du cluster.
Comment détecter : Depuis l'intérieur d'un pod, exécutez nslookup nginx-service.service-lab.svc.cluster.local. Si la recherche expire ou renvoie NXDOMAIN, le DNS ne fonctionne pas correctement.
Comment récupérer :
kubectl get pods -n kube-system -l k8s-app=kube-dns
Si les pods CoreDNS sont absents ou non prêts, redémarrez-les :
kubectl rollout restart deployment coredns -n kube-system
Vérifiez également la configuration DNS du pod client :
kubectl exec -n service-lab <pod-name> -- cat /etc/resolv.conf
Assurez-vous que le serveur de noms pointe vers l'IP DNS du cluster (souvent 10.96.0.10). Sinon, vérifiez le paramètre dnsPolicy du pod et définissez-le sur ClusterFirst.
Piège 3 : Service NodePort non accessible depuis l'hôte
Pourquoi cela arrive : Avec minikube utilisant le pilote Docker, le NodePort est exposé sur la VM minikube, pas directement sur localhost. Les pare-feu ou l'utilisation d'une mauvaise IP peuvent également bloquer l'accès.
Comment détecter : minikube ip renvoie l'IP de la VM, mais curl sur cette IP avec le NodePort échoue ou expire.
Comment récupérer : Utilisez la commande minikube service pour ouvrir un tunnel ou obtenir l'URL correcte :
minikube service nginx-nodeport -n service-lab
Cette commande affiche une URL qui transfère le trafic vers le Service. Alternativement, utilisez kubectl port-forward pour un test rapide :
kubectl port-forward service/nginx-nodeport 8080:80 -n service-lab
Accédez ensuite à http://localhost:8080.
Piège 4 : Oublier de supprimer les ressources du laboratoire
Pourquoi cela arrive : Vous pourriez laisser le cluster en cours d'exécution et oublier de nettoyer, consommant des ressources locales.
Comment éviter : Supprimez toujours le namespace lorsque vous terminez les expériences :
kubectl delete namespace service-lab
Cela supprime toutes les ressources du namespace. Si vous souhaitez conserver le cluster mais supprimer uniquement des objets spécifiques, supprimez-les par nom :
kubectl delete service nginx-service nginx-nodeport -n service-lab
kubectl delete deployment nginx-deployment -n service-lab
Modes de défaillance et récupération
Les Services dépendent de la correspondance des sélecteurs avec les libellés des pods et des composants réseau. Les défaillances courantes et leurs étapes de récupération sont répertoriées ci-dessous.
Défaillance : Le Service n'a pas d'endpoints
Si le sélecteur ne correspond à aucun pod, le Service aura des endpoints vides.
Diagnostic :
kubectl get endpoints nginx-service -n service-lab
Si la sortie affiche <none> pour ENDPOINTS, vérifiez le sélecteur et les libellés des pods.
Récupération :
- Vérifiez les libellés des pods :
kubectl get pods -n service-lab --show-labels - Vérifiez le sélecteur du Service :
kubectl get service nginx-service -n service-lab -o yaml | grep -A2 selector - Corrigez l'inadéquation en modifiant le Service ou le Deployment.
Défaillance : Le nom DNS ne se résout pas
Si nslookup à l'intérieur du pod échoue, cela peut être dû à ce que CoreDNS ne fonctionne pas ou à une politique DNS du pod incorrecte.
Diagnostic :
kubectl get pods -n kube-system -l k8s-app=kube-dns
Récupération :
- Si les pods CoreDNS sont absents, redémarrez-les :
kubectl rollout restart deployment coredns -n kube-system - Vérifiez la configuration DNS du pod :
kubectl exec -n service-lab -- cat /etc/resolv.conf
Défaillance : Service de type NodePort non accessible
Si vous ne pouvez pas atteindre le NodePort depuis votre hôte, vérifiez les règles de pare-feu ou l'IP du nœud.
Diagnostic :
minikube ip
kubectl get service nginx-nodeport -n service-lab
Récupération :
- Assurez-vous d'utiliser la bonne IP et le bon port.
- Pour minikube avec le pilote Docker, vous devrez peut-être utiliser
minikube service nginx-nodeport -n service-labpour ouvrir un tunnel.
Stratégie de retour en arrière
Comme les ressources ont été créées avec des commandes, le retour en arrière consiste simplement à supprimer les objets créés.
Pour supprimer tout le laboratoire, supprimez le namespace :
kubectl delete namespace service-lab
Sortie attendue : namespace "service-lab" deleted
Alternativement, supprimez des ressources individuelles en utilisant kubectl delete <ressource> <nom> -n service-lab.
Liste de contrôle des opérations
Utilisez cette liste de contrôle chaque fois que vous configurez ou modifiez le laboratoire pour garantir la cohérence.
| Tâche | Commande | Résultat attendu |
|---|---|---|
| Démarrer le cluster | minikube start | Cluster en cours d'exécution, kubectl configuré |
| Créer un namespace | kubectl create namespace service-lab | Namespace créé |
| Déployer le backend | kubectl create deployment nginx-deployment --image=nginx:1.25 --replicas=2 -n service-lab | 2 pods en cours d'exécution |
| Créer un Service ClusterIP | kubectl expose deployment nginx-deployment --name=nginx-service --type=ClusterIP --port=80 --target-port=80 -n service-lab | Service avec ClusterIP attribué |
| Vérifier les endpoints | kubectl get endpoints nginx-service -n service-lab | Deux IP de pods répertoriées |
| Tester depuis un pod | kubectl run ... curl http://nginx-service | Réponse HTML |
| Tester le DNS | nslookup nginx-service.service-lab.svc.cluster.local | Renvoie le ClusterIP |
| Nettoyer | kubectl delete namespace service-lab | Aucune ressource restante |
Après chaque expérience, capturez les commandes et les sorties dans vos notes. Cela construit une base de connaissances personnelle et aide lorsque vous passez à la production.
Conclusion
Vous disposez maintenant d'un laboratoire local fonctionnel pour les Services Kubernetes. Vous avez provisionné un cluster à nœud unique, déployé une application d'exemple, créé des Services ClusterIP et NodePort, et vérifié leur comportement via les endpoints, le DNS et l'accès direct. Vous avez également vu les modes de défaillance courants et comment s'en remettre. La prochaine étape consiste à étendre le laboratoire : essayez de créer un Service avec plusieurs ports, expérimentez avec externalTrafficPolicy, ou ajoutez une NetworkPolicy pour voir comment elle affecte l'accès au Service. Comme la configuration utilise des commandes simples, vous pouvez itérer en toute sécurité et détruire l'environnement à tout moment. Ce laboratoire fournit une base solide pour comprendre les Services Kubernetes en production. Gardez la liste de contrôle des opérations à portée de main et répétez les exercices jusqu'à ce que les commandes deviennent une seconde nature.