
Les NetworkPolicies contrôlent quels Pods peuvent communiquer entre eux et avec l’extérieur au niveau IP et port (L3/L4). Par défaut, Kubernetes n’applique aucune restriction : tous les Pods se parlent librement. Les NetworkPolicies permettent de cloisonner ces flux selon le principe du moindre privilège.
Ce guide couvre la création de policies ingress et egress, les cas critiques comme le DNS, et les techniques de debug indispensables.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Comprendre le modèle : sélection par labels, union des règles, logique source/destination
- Créer des policies : deny par défaut, autorisation ciblée, filtrage par namespace
- Gérer l’egress : ne pas casser le DNS, autoriser les flux nécessaires
- Débugger : diagnostiquer pourquoi un flux est bloqué ou autorisé
À quoi servent les NetworkPolicies
Section intitulée « À quoi servent les NetworkPolicies »En l’absence de restrictions réseau applicables, les Pods peuvent généralement communiquer largement entre eux, y compris entre namespaces. C’est le comportement réseau permissif par défaut de Kubernetes.
Les NetworkPolicies permettent de :
- Restreindre les connexions entrantes vers un Pod (ingress)
- Restreindre les connexions sortantes depuis un Pod (egress)
- Isoler des environnements (production, staging, test)
- Limiter la propagation en cas de compromission d’un Pod
Condition préalable : un CNI compatible
Section intitulée « Condition préalable : un CNI compatible »Kubernetes définit les NetworkPolicies, mais ne les applique pas lui-même. C’est le plugin réseau (CNI) qui doit implémenter cette fonctionnalité.
Avant d’écrire des NetworkPolicies, vérifiez dans la documentation de votre plugin réseau qu’il applique bien les policies Kubernetes.
Parmi les implémentations souvent utilisées qui supportent les NetworkPolicies :
| CNI | Support NetworkPolicy | Notes |
|---|---|---|
| Calico | ✅ Complet | Policies étendues disponibles |
| Cilium | ✅ Complet | Filtrage L7 optionnel |
| Weave Net | ✅ Complet | — |
| Antrea | ✅ Complet | Orienté VMware/vSphere |
| Flannel | ⚠️ Partiel | Nécessite un complément (ex: Calico) |
Vérifier le CNI installé :
kubectl get pods -n kube-system -l k8s-app=calico-nodekubectl get pods -n kube-system -l k8s-app=ciliumComment fonctionne le modèle
Section intitulée « Comment fonctionne le modèle »Sélection par labels
Section intitulée « Sélection par labels »Une NetworkPolicy cible les Pods via un podSelector basé sur leurs labels.
Sans sélection valide, la policy ne s’applique à aucun Pod.
spec: podSelector: matchLabels: app: backendCette policy s’applique uniquement aux Pods ayant le label app: backend dans
le namespace où elle est déployée.
Sélectionner tous les Pods d’un namespace :
spec: podSelector: {}Ingress et Egress
Section intitulée « Ingress et Egress »| Direction | Contrôle | Quand restreindre |
|---|---|---|
| Ingress | Connexions entrantes vers le Pod | Limiter qui peut accéder à un service |
| Egress | Connexions sortantes depuis le Pod | Limiter où un Pod peut se connecter |
Déclarez explicitement policyTypes pour éviter les ambiguïtés :
spec: policyTypes: - Ingress - EgressUnion des règles
Section intitulée « Union des règles »Les NetworkPolicies ne se remplacent pas l’une l’autre. Les connexions autorisées résultent de l’union de toutes les règles applicables au Pod pour la direction concernée.
Exemple : si deux policies autorisent des sources différentes vers le même Pod, les deux sources sont autorisées.
Policy A : autorise frontend → backendPolicy B : autorise monitoring → backendRésultat : frontend ET monitoring peuvent accéder à backendLogique source + destination
Section intitulée « Logique source + destination »Pour qu’une connexion fonctionne, elle doit être autorisée des deux côtés si des restrictions existent :
- L’egress du Pod source doit autoriser la sortie vers la destination
- L’ingress du Pod destination doit autoriser l’entrée depuis la source
Pod A (egress restreint) → Pod B (ingress restreint)
✅ Fonctionne si : - Policy egress de A autorise B - Policy ingress de B autorise A
❌ Échoue si : - L'une des deux policies manque l'autorisationC’est un point fondamental pour le dépannage : vérifiez toujours les policies des deux côtés.
Premier cas : autoriser frontend vers backend
Section intitulée « Premier cas : autoriser frontend vers backend »Commençons par un cas classique : seuls les Pods frontend peuvent accéder
aux Pods backend sur le port 8080.
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: allow-frontend-to-backend namespace: defaultspec: podSelector: matchLabels: app: backend policyTypes: - Ingress ingress: - from: - podSelector: matchLabels: app: frontend ports: - protocol: TCP port: 8080Ce que fait cette policy :
- Sélectionne les Pods
app: backenddans le namespacedefault - Restreint leur trafic ingress (entrées deviennent contrôlées)
- Autorise uniquement les connexions depuis les Pods
app: frontend - Limite au port TCP 8080
Appliquer et tester :
kubectl apply -f allow-frontend-to-backend.yaml
# Depuis un Pod frontendkubectl exec -it deploy/frontend -- curl backend:8080# Résultat : connexion réussie
# Depuis un autre Podkubectl exec -it deploy/autre-app -- curl backend:8080# Résultat : timeout (bloqué)Default deny ingress
Section intitulée « Default deny ingress »Pour isoler complètement un namespace ou un groupe de Pods, commencez par bloquer tout le trafic entrant :
Pour tout un namespace
Section intitulée « Pour tout un namespace »apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: default-deny-ingress namespace: productionspec: podSelector: {} # Tous les Pods du namespace policyTypes: - Ingress # Pas de section ingress = rien n'est autoriséCette policy :
- Sélectionne tous les Pods du namespace
production - Déclare qu’elle contrôle l’ingress
- N’autorise aucune connexion entrante (pas de règle
ingress)
Pour un groupe de Pods spécifique
Section intitulée « Pour un groupe de Pods spécifique »apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: deny-ingress-backend namespace: defaultspec: podSelector: matchLabels: app: backend policyTypes: - Ingress ingress: []Default deny egress
Section intitulée « Default deny egress »Restreindre les connexions sortantes est tout aussi important, mais nécessite plus d’attention car cela peut casser des fonctionnalités critiques.
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: default-deny-egress namespace: productionspec: podSelector: {} policyTypes: - Egress # Pas de section egress = rien n'est autoriséAutoriser le DNS
Section intitulée « Autoriser le DNS »C’est le premier réflexe dès que vous restreignez l’egress. Sans DNS,
vos applications ne peuvent plus résoudre mon-service.namespace.svc.cluster.local.
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: allow-dns-egress namespace: productionspec: podSelector: {} # Tous les Pods du namespace policyTypes: - Egress egress: - to: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: kube-system podSelector: matchLabels: k8s-app: kube-dns ports: - protocol: UDP port: 53 - protocol: TCP port: 53Alternative plus simple (moins restrictive) :
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: allow-dns-egress-simple namespace: productionspec: podSelector: {} policyTypes: - Egress egress: - ports: - protocol: UDP port: 53 - protocol: TCP port: 53Cette version autorise le port 53 vers n’importe quelle destination. Plus permissive, mais plus simple à maintenir.
Exemple complet : egress contrôlé
Section intitulée « Exemple complet : egress contrôlé »Voici une policy qui autorise un Pod à :
- Résoudre le DNS
- Accéder à une base de données PostgreSQL interne
- Rien d’autre
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: backend-egress-controlled namespace: productionspec: podSelector: matchLabels: app: backend policyTypes: - Egress egress: # DNS - ports: - protocol: UDP port: 53 - protocol: TCP port: 53 # PostgreSQL interne - to: - podSelector: matchLabels: app: postgresql ports: - protocol: TCP port: 5432Sélection par namespace
Section intitulée « Sélection par namespace »Pour autoriser des flux entre namespaces, utilisez namespaceSelector.
Autoriser depuis un namespace spécifique
Section intitulée « Autoriser depuis un namespace spécifique »apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: allow-from-monitoring namespace: productionspec: podSelector: matchLabels: app: backend policyTypes: - Ingress ingress: - from: - namespaceSelector: matchLabels: name: monitoringCombiner namespace et pod selector
Section intitulée « Combiner namespace et pod selector »Pour cibler des Pods spécifiques dans un namespace spécifique :
ingress: - from: - namespaceSelector: matchLabels: name: monitoring podSelector: matchLabels: app: prometheusAttention à la syntaxe : les deux sélecteurs dans le même item - signifie
ET logique. Séparés, c’est OU logique :
# ET logique : namespace monitoring ET pod prometheus- from: - namespaceSelector: matchLabels: name: monitoring podSelector: matchLabels: app: prometheus
# OU logique : namespace monitoring OU pod prometheus (dans le même namespace)- from: - namespaceSelector: matchLabels: name: monitoring - podSelector: matchLabels: app: prometheusUtiliser ipBlock
Section intitulée « Utiliser ipBlock »ipBlock permet d’autoriser des plages d’adresses IP, typiquement pour
des systèmes externes au cluster.
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: allow-external-api namespace: productionspec: podSelector: matchLabels: app: backend policyTypes: - Egress egress: - to: - ipBlock: cidr: 203.0.113.0/24 except: - 203.0.113.128/25 ports: - protocol: TCP port: 443Ce que les NetworkPolicies ne font pas
Section intitulée « Ce que les NetworkPolicies ne font pas »Pour éviter les fausses attentes, voici ce que les NetworkPolicies standard ne peuvent pas faire :
| Fonctionnalité | NetworkPolicy | Alternative |
|---|---|---|
| Filtrer par URL/path HTTP | ❌ Non | Service mesh (Istio, Linkerd) |
| Authentification mutuelle (mTLS) | ❌ Non | Service mesh |
| Filtrer par méthode HTTP (GET, POST) | ❌ Non | Service mesh, API Gateway |
| Inspection de payload | ❌ Non | WAF |
| Logging des connexions bloquées | ❌ Non | CNI spécifique (Cilium, Calico) |
| Policies inter-clusters | ❌ Non | Solutions multi-cluster |
Les NetworkPolicies sont un premier niveau de segmentation réseau, pas une solution de sécurité applicative complète.
Débugger une NetworkPolicy
Section intitulée « Débugger une NetworkPolicy »Quand un flux est bloqué (ou ne l’est pas alors qu’il devrait), suivez cette méthode :
-
Lister les policies du namespace
Fenêtre de terminal kubectl get networkpolicy -n production -
Examiner une policy en détail
Fenêtre de terminal kubectl describe networkpolicy allow-frontend-to-backend -n productionVérifiez :
PodSelector: quels Pods sont ciblés ?Allowing ingress traffic: quelles sources sont autorisées ?Allowing egress traffic: quelles destinations sont autorisées ?
-
Vérifier les labels des Pods
Fenêtre de terminal kubectl get pods -n production --show-labelskubectl get pods -n production -l app=backendUn Pod sans le bon label ne sera pas sélectionné par la policy.
-
Tester la connectivité
Fenêtre de terminal # Depuis le Pod sourcekubectl exec -it deploy/frontend -n production -- nc -vz backend 8080# Test DNSkubectl exec -it deploy/frontend -n production -- nslookup backend -
Vérifier les deux côtés
Si l’egress du source ET l’ingress de la destination sont restreints, vérifiez que les deux autorisent le flux.
Fenêtre de terminal # Policies qui sélectionnent le Pod source (egress)kubectl get networkpolicy -n production -o json | \jq '.items[] | select(.spec.podSelector.matchLabels.app=="frontend")'# Policies qui sélectionnent le Pod destination (ingress)kubectl get networkpolicy -n production -o json | \jq '.items[] | select(.spec.podSelector.matchLabels.app=="backend")'
Outils de debug avancés
Section intitulée « Outils de debug avancés »# Pod de debug avec outils réseaukubectl run netshoot --rm -it --image=nicolaka/netshoot -- bash
# Dans le pod netshootnslookup backend.production.svc.cluster.localcurl -v backend.production:8080nc -vz backend.production 8080
# Vérifier si le CNI loggue les drops (Cilium)kubectl logs -n kube-system -l k8s-app=cilium -c cilium-agent | grep -i dropProblèmes courants
Section intitulée « Problèmes courants »| Symptôme | Cause probable | Solution |
|---|---|---|
| Timeout vers un service | Policy ingress manquante côté destination | Ajouter une règle from |
| DNS ne résout plus | Egress deny sans exception DNS | Autoriser le port 53 |
| Policy ignorée | CNI incompatible | Vérifier le support NetworkPolicy |
| Pod non sélectionné | Labels incorrects | Vérifier --show-labels |
| Flux autorisé inattendu | Union de plusieurs policies | Lister toutes les policies applicables |
Documenter vos NetworkPolicies
Section intitulée « Documenter vos NetworkPolicies »Pour maintenir des policies lisibles dans le temps :
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: allow-frontend-to-backend namespace: production annotations: description: "Autorise le frontend à accéder au backend sur le port API" owner: "team-platform" last-review: "2026-03-22"spec: # ...Contrôle de connaissances
Section intitulée « Contrôle de connaissances »Contrôle de connaissances
Validez vos connaissances avec ce quiz interactif
Informations
- Le chronomètre démarre au clic sur Démarrer
- Questions à choix multiples, vrai/faux et réponses courtes
- Vous pouvez naviguer entre les questions
- Les résultats détaillés sont affichés à la fin
Lance le quiz et démarre le chronomètre
Vérification
(0/0)Profil de compétences
Quoi faire maintenant
Ressources pour progresser
Des indices pour retenter votre chance ?
Nouveau quiz complet avec des questions aléatoires
Retravailler uniquement les questions ratées
Retour à la liste des certifications
Ce qu’il faut savoir pour la CKAD
Section intitulée « Ce qu’il faut savoir pour la CKAD »-
Lire une policy existante
Identifiez rapidement : quels Pods sont sélectionnés (
podSelector), quel trafic est contrôlé (policyTypes), quelles règles s’appliquent. -
Créer un default deny ingress
podSelector: {}policyTypes: [Ingress]# Pas de section ingress -
Autoriser un flux spécifique
Frontend vers backend, port 8080 :
ingress:- from:- podSelector:matchLabels:app: frontendports:- port: 8080 -
Autoriser le DNS en egress
Dès que vous restreignez l’egress, autorisez UDP/TCP 53.
-
Diagnostiquer un blocage
kubectl get networkpolicy -n <ns>kubectl describe networkpolicy <name>kubectl get pods --show-labelskubectl exec ... -- nc -vz <service> <port>
À retenir
Section intitulée « À retenir »- Les NetworkPolicies opèrent au niveau L3/L4 (IP/port), pas HTTP
- Le CNI doit supporter l’enforcement des policies, sinon elles sont ignorées
- Un Pod devient isolé (ingress ou egress) dès qu’une policy le sélectionne
- Les règles autorisées sont l’union des policies applicables
- Une connexion doit être autorisée des deux côtés (source egress + destination ingress)
- Dès que l’egress est restreint, pensez au DNS (port 53)
ipBlockest pour les IP externes stables, pas pour cibler des Pods- Déclarez explicitement
policyTypespour éviter les ambiguïtés