📍 Article principal du cluster : CKAD Certified Kubernetes Application Developer — guide pratique 2026
Ce tutoriel fait partie du cluster certification CKAD. Pour la vue d’ensemble, lisez d’abord le pilier.
Introduction
Les domaines 4 (Services and Networking, 20 %) et 5 (Application Observability and Maintenance, 15 %) couvrent ensemble 35 % de l’examen CKAD. Concrètement, ils testent votre capacité à exposer une application avec le bon type de Service, à segmenter le trafic réseau avec des NetworkPolicies, à configurer un Ingress pour le HTTP externe, et à diagnostiquer une chaîne de microservices qui ne fonctionne pas. Ce tutoriel pratique chacun de ces axes sur un cluster kind 1.35 avec NetworkPolicy support activé via Calico ou Cilium léger.
Prérequis
- Cluster kind 1.35 fonctionnel
- Avoir terminé les tutoriels Pods et ConfigMaps du cluster
- 40 minutes
Étape 1 — Activer le support NetworkPolicy avec Calico
Le CNI par défaut de kind (kindnet) ne supporte pas les NetworkPolicies. Pour pratiquer le domaine 4 sérieusement, on installe Calico — un CNI qui implémente complètement la spec NetworkPolicy de Kubernetes.
kind delete cluster --name ckad-prep
cat > /tmp/kind-calico.yaml <<EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
- role: worker
- role: worker
networking:
disableDefaultCNI: true
podSubnet: "192.168.0.0/16"
EOF
kind create cluster --config /tmp/kind-calico.yaml --name ckad-prep --image kindest/node:v1.35.0
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.30.0/manifests/calico.yaml
sleep 30
kubectl get pods -n kube-system | grep calico
Attendez que les Pods Calico passent en Running (calico-node, calico-kube-controllers, typha). C’est le moment où le cluster est pleinement opérationnel et accepte les NetworkPolicies.
Étape 2 — Service ClusterIP
Le ClusterIP est le type de Service par défaut. Il expose un Pod sur une IP virtuelle interne au cluster. Toute requête vers cette IP est load-balancée vers les Pods sains derrière le selector.
k create deploy web --image=nginx:1.27 --replicas=3
k expose deploy web --port=80 --target-port=80 --name=web-svc
k get svc web-svc
k describe svc web-svc | grep -E "IP|Port|Endpoints"
L’IP du Service apparaît avec ses Endpoints (les 3 IPs des Pods nginx). Testez la résolution DNS interne : `k run tester –rm -it –image=busybox — wget -qO- web-svc:80 | head -5` doit retourner la page d’accueil nginx.
Étape 3 — Service NodePort pour debug
Le NodePort expose un Service sur un port haut (30000-32767) de chaque nœud. Pratique pour exposer rapidement un service sans LoadBalancer cloud.
k expose deploy web --port=80 --type=NodePort --name=web-np
k get svc web-np
NP_PORT=$(k get svc web-np -o jsonpath='{.spec.ports[0].nodePort}')
echo "NodePort: $NP_PORT"
docker exec ckad-prep-control-plane curl -s http://127.0.0.1:$NP_PORT | head -3
L’accès via NodePort fonctionne depuis n’importe quel nœud du cluster — kube-proxy gère le routage. En production, le NodePort est typiquement utilisé pour debug ou pour fronter un LoadBalancer externe.
Étape 4 — NetworkPolicy default-deny
La sécurité réseau Kubernetes commence par un default-deny qui bloque tout le trafic, puis on ouvre explicitement les flux nécessaires. Pattern zero-trust.
k create namespace secure-app
k label namespace secure-app team=alpha
k create deploy backend --image=nginx:1.27 --replicas=2 -n secure-app
k expose deploy backend --port=80 -n secure-app
k label deploy backend role=backend -n secure-app
k label pods -l app=backend role=backend -n secure-app
cat > deny-all.yaml <<'EOF'
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: secure-app
spec:
podSelector: {}
policyTypes:
- Ingress
EOF
k apply -f deny-all.yaml
k run tester --rm -it --image=busybox:1.37 -n secure-app -- wget -qO- --timeout=3 backend
# Doit timeout — toutes les ingress refusées
Le tester ne peut plus joindre backend même au sein du namespace. C’est volontaire : aucune NetworkPolicy n’autorise le trafic, donc tout est refusé. C’est exactement le pattern qu’attendent les questions du domaine 4 sur les NetworkPolicies.
Étape 5 — NetworkPolicy allow ciblée
On ouvre maintenant explicitement le flux web → backend en autorisant les Pods avec label `role=frontend` à atteindre les Pods avec label `role=backend` sur le port 80.
cat > allow-frontend.yaml <<'EOF'
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
namespace: secure-app
spec:
podSelector:
matchLabels:
role: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
role: frontend
ports:
- protocol: TCP
port: 80
EOF
k apply -f allow-frontend.yaml
k run frontend --rm -it --image=busybox:1.37 -n secure-app --labels=role=frontend -- wget -qO- backend | head -3
Cette fois la requête passe — le Pod frontend matche le selector autorisé. Tout autre Pod sans label `role=frontend` reste bloqué. C’est la finesse de segmentation que vise la spec NetworkPolicy.
Étape 6 — Ingress avec nginx-ingress-controller
L’Ingress route le trafic HTTP externe vers les Services internes selon des règles host/path. Pour kind, on installe le controller nginx avec un manifest officiel adapté.
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.13.0/deploy/static/provider/kind/deploy.yaml
sleep 30
kubectl wait --namespace ingress-nginx --for=condition=ready pod --selector=app.kubernetes.io/component=controller --timeout=120s
cat > ingress.yaml <<'EOF'
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: web.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-svc
port:
number: 80
EOF
k apply -f ingress.yaml
k get ingress
curl -H "Host: web.local" http://localhost | head -3
L’Ingress route le trafic vers le Service `web-svc`. Le `Host:` header simule la requête depuis web.local — sans configurer le DNS local, c’est la méthode standard pour tester un Ingress en kind.
Étape 7 — Liveness, readiness et startup probes
Les probes sont au cœur du domaine 5 (observabilité). La liveness redémarre un conteneur défaillant ; la readiness retire un Pod du Service quand non prêt ; la startup donne du temps aux applis lentes à démarrer.
cat > pod-probes.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
name: probed-app
spec:
containers:
- name: app
image: nginx:1.27
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 2
periodSeconds: 5
startupProbe:
httpGet:
path: /
port: 80
failureThreshold: 30
periodSeconds: 2
EOF
k apply -f pod-probes.yaml
sleep 10
k get pod probed-app
k describe pod probed-app | grep -A 3 "Liveness\|Readiness\|Startup"
Vous voyez les trois probes configurées. La startup probe désactive temporairement les liveness et readiness probes pendant le démarrage — utile pour les applis Spring Boot ou Django qui prennent 30+ secondes à initialiser.
Étape 8 — Debug systématique d’un service en panne
La séquence de debug à mémoriser : `describe`, `logs`, `events`, `exec`, `port-forward`. C’est testé directement en domaine 5d.
k run broken-app --image=httpd:badtag
sleep 5
k get pod broken-app
k describe pod broken-app | tail -10
k get events --sort-by=.lastTimestamp -n default | tail -5
# Pour un service intermittent en HTTP
k port-forward pod/probed-app 8888:80 &
sleep 2
curl -s http://localhost:8888 | head -1
pkill -f "port-forward pod/probed-app"
Le `describe pod` montre exactement pourquoi le Pod est en ImagePullBackOff. Le `events` confirme avec un message descriptif. Le `port-forward` permet de tester un Service ou Pod sans l’exposer publiquement — extrêmement utile en debug.
Comprendre la différence Ingress, Gateway API et Service LoadBalancer
Trois primitives Kubernetes pour exposer du trafic externe, avec des positionnements différents. Service LoadBalancer demande au cloud provider (AWS, GCP, Azure, Hetzner) de provisionner un LB externe pour exposer un Service. Simple mais limité au L4 (TCP/UDP, pas de routing HTTP intelligent). Ingress ajoute un routage L7 (host, path, header) via un controller (nginx, Traefik, HAProxy). API stable et largement supportée. Gateway API est la nouvelle génération (GA depuis K8s 1.31) qui sépare les responsabilités entre infra (GatewayClass), opérateurs (Gateway), et développeurs applicatifs (HTTPRoute). Plus expressive mais demande des controllers compatibles (Envoy Gateway, Cilium Gateway, Istio Gateway).
Pour CKAD 1.35, vous devez connaître Ingress par cœur et avoir une compréhension de base de Gateway API. Le LoadBalancer est testé incidemment.
Erreurs fréquentes
| Erreur | Cause | Solution |
|---|---|---|
| NetworkPolicy ignorée | CNI par défaut sans support | Installer Calico ou Cilium |
| Ingress 503 Service Unavailable | Service backend incorrect | Vérifier `kubectl get endpoints SVC` — doit lister des IPs de Pods |
| Pod NotReady à cause de readinessProbe | Probe trop agressive | Augmenter `initialDelaySeconds` |
| Liveness probe tue les Pods en boucle | App lente à démarrer | Ajouter une startupProbe pour donner plus de temps |
| Port-forward ne fonctionne pas | Pod en CrashLoopBackOff | Le Pod doit être Running pour le port-forward — debug d’abord |
Adaptation au contexte ouest-africain
Pour les équipes plateforme à Dakar et Abidjan, les NetworkPolicies sont essentielles dès qu’on déploie des applications réglementées (paiement mobile money, données de santé, données financières). La segmentation par namespace + NetworkPolicy default-deny + allow ciblé est la baseline minimale demandée par les auditeurs PCI-DSS et OHADA-PD. Pour les Ingress en production, privilégiez Traefik ou nginx-ingress-controller plutôt que les solutions cloud propriétaires — ce qui vous permet de migrer entre Hostinger, AWS, Azure sans réécrire votre couche d’exposition.
Tutoriels frères
Pour aller plus loin
- 🔝 Retour au pilier : CKAD — guide pratique
- Documentation Services : kubernetes.io/docs/concepts/services-networking/service
- Documentation NetworkPolicies : kubernetes.io/docs/concepts/services-networking/network-policies
- Documentation Probes : kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes
FAQ
Combien de NetworkPolicies par namespace ?
Pas de limite, mais en pratique 5-10 max par namespace pour rester maintenable. Plus signifie souvent une mauvaise organisation logique des Pods.
Quelle différence entre Ingress et Service LoadBalancer ?
LoadBalancer expose un Service au L4. Ingress route HTTP/HTTPS au L7 avec règles host/path. Souvent on combine : un Service LoadBalancer pour exposer le controller Ingress, qui à son tour route vers les services.
Mots-clés secondaires : ckad networkpolicy, service ingress kubernetes, calico ckad, gateway api k8s, liveness readiness startup probe, debug pod kubectl