Kubernetes abstrait le réseau afin que chaque Pod possède sa propre IP et que les services soient découvertes automatiquement. Ce module clarifie la circulation du trafic et comment l’exposer en interne comme en externe.
Table of Contents
Objectifs
- Visualiser le modèle réseau cluster (CNI, kube-proxy, CoreDNS).
- Choisir le bon type de Service : ClusterIP, NodePort, LoadBalancer.
- Mettre en place un Ingress Controller et rédiger des règles HTTP(S).
- Sécuriser les échanges avec NetworkPolicy.
1. Modèle réseau Kubernetes
- Chaque Pod obtient une IP unique routable dans le cluster (pas de NAT intra-cluster).
- Le CNI (Calico, Cilium, Flannel…) s’occupe de l’attribution d’adresses et du routage.
- kube-proxy (iptables ou IPVS) gère les règles pour exposer les Services.
- CoreDNS fournit la résolution
service.namespace.svc.cluster.local.
Vérifiez votre CNI :
kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl get pods -n kube-system -l k8s-app=calico-node
2. Services : ClusterIP, NodePort, LoadBalancer
Un Service sélectionne des Pods via des labels et expose un endpoint stable.
apiVersion: v1
kind: Service
metadata:
name: webapp
namespace: staging
spec:
selector:
app: webapp
ports:
- name: http
port: 80
targetPort: 8080
type: ClusterIP
- ClusterIP : visibilité uniquement intra-cluster.
- NodePort : ouvre un port (30000-32767) sur chaque nœud pour accéder depuis l’extérieur.
- LoadBalancer : provisionne un LB via le cloud provider (ou MetalLB en bare metal).
Pour convertir en NodePort :
kubectl patch svc webapp -p '{"spec": {"type": "NodePort", "ports": [{"port":80,"targetPort":8080,"nodePort":31080}]}}'
3. Ingress HTTP(S)
Un Ingress Controller (NGINX, Traefik, HAProxy, Istio Gateway) observe les ressources Ingress et configure la passerelle.
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml
kubectl get pods -n ingress-nginx
Déclarez ensuite une règle :
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: webapp
namespace: staging
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
tls:
- hosts:
- webapp.local
secretName: webapp-tls
rules:
- host: webapp.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: webapp
port:
number: 80
Sur votre poste :
echo "127.0.0.1 webapp.local" | sudo tee -a /etc/hosts
curl -H "Host: webapp.local" http://127.0.0.1:8080
4. DNS et découverte
CoreDNS résout automatiquement les services. Testez depuis un Pod utilitaire :
kubectl run dnsutils --image=ghcr.io/linuxserver/bind-tools -it --rm -- /bin/sh
# Dans le pod
nslookup webapp.staging.svc.cluster.local
curl webapp.staging.svc.cluster.local:80
5. NetworkPolicies
Sans NetworkPolicy, tout le trafic est autorisé. Restreignez les flux :
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend
namespace: staging
spec:
podSelector:
matchLabels:
app: webapp
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
env: frontend
- podSelector:
matchLabels:
role: gateway
ports:
- protocol: TCP
port: 80
Pour filtrer le egress (sortie) : ajoutez policyTypes: ["Ingress", "Egress"] et définissez des egress rules.
6. Lab complet
- Déployez
webapp(module 2) et exposez-le via un Service NodePort (port 31080). - Installez ingress-nginx (commande ci-dessus) et créez un Ingress
webapp. - Ajoutez un certificat auto-signé :
openssl req -new -x509 -nodes -out webapp.crt -keyout webapp.key -subj "/CN=webapp.local" kubectl create secret tls webapp-tls --cert=webapp.crt --key=webapp.key -n staging - Appliquez la NetworkPolicy
allow-frontendpuis créez deux namespaces :frontend(labelenv=frontend) etbackend. Vérifiez que seulfrontendaccède au Service. - Inspectez les tables iptables :
sudo iptables-save | grep KUBE-SVC(sur un nœud worker).
Solution détaillée
- Service NodePort
kubectl get svc webapp -n stagingdoit afficherTYPE NodePortavecPORT(S) 80:31080/TCP.
Test local :curl http://$(kind get clusters >/dev/null && kubectl get nodes -o jsonpath='{.items[0].status.addresses[?(@.type=="InternalIP")].address}'):31080. - Ingress
kubectl get ingress -n stagingdoit montrerHOSTS webapp.local.
curl -H "Host: webapp.local" http://127.0.0.1:8080renvoie la page (ouIngress Controllerdefault backend si Service incorrect). - TLS
kubectl get secret webapp-tls -n staging→ typekubernetes.io/tls.
curl -k https://webapp.local:8443(si vous exposez port 8443) doit répondre 200. - DNS
Dans le Poddnsutils:nslookup webapp.staging.svc.cluster.localrenvoie l’IP ClusterIP.curl webapp.staging.svc.cluster.localdoit réussir. - NetworkPolicy
Après application dedeny-all, tout trafic doit être bloqué. Déployez un Podbusyboxdans un namespace sans label et testez :curl webapp.staging.svc.cluster.local→ timeout.
Ajoutez le namespacefrontendavec labelenv=frontendet un Pod test : l’accès doit fonctionner.
Consignez les sorties kubectl describe ingress, kubectl get networkpolicy et un test curl réussi depuis le namespace autorisé.
Challenge
- Mettre en place MetalLB ou kind loadbalancer pour tester le type
LoadBalancer. - Déployer Traefik et comparer la configuration (
kubectl get configmap -n kube-system traefik). - Créer une NetworkPolicy default deny sur le namespace
staginget autoriser explicitement chaque flux.
Pièges récurrents
- Oublier de créer le secret TLS référencé par un Ingress → code HTTP 502/404.
- Mettre un Ingress sans contrôleur : la ressource est créée mais sans effet.
- NetworkPolicy non appliquée car le CNI ne la supporte pas (ex. Flannel vanilla). Vérifiez la documentation de votre CNI.
Ressources
Checklist
- ✅ Vous pouvez expliquer la différence entre ClusterIP, NodePort, LoadBalancer.
- ✅ Vous avez configuré un Ingress et testé une résolution DNS intra-cluster.
- ✅ Vous contrôlez le trafic avec une NetworkPolicy et savez valider son effet.


