Par défaut, dans un cluster Kubernetes, tous les Pods peuvent parler à tous les Pods. Aucune restriction réseau. C’est comme un open space sans cloisons : pratique au début, catastrophique quand un Pod se fait compromettre et scanne tout le réseau interne.
Les NetworkPolicies sont le firewall natif de Kubernetes. Elles te permettent de définir précisément quel Pod peut communiquer avec quel autre, sur quel port et dans quel sens. C’est la segmentation réseau appliquée au monde des conteneurs.
Dans ce chapitre, tu vas apprendre à verrouiller ton cluster réseau, couche par couche.
Pourquoi les NetworkPolicies sont indispensables
🔥 Cas réel : En 2022, une entreprise fintech a subi une fuite de données parce qu’un Pod frontend compromis (via une faille XSS) a pu requêter directement la base PostgreSQL interne. Aucune NetworkPolicy n’était en place. Le frontend n’avait aucune raison légitime de parler à la base — mais personne n’avait posé la barrière.
Sans NetworkPolicies, ton cluster fonctionne en mode “confiance totale”. Chaque Pod peut :
- Scanner les autres services sur le réseau interne
- Accéder aux bases de données sans passer par l’API
- Exfiltrer des données vers n’importe quelle IP externe
- Atteindre le metadata service cloud (169.254.169.254) et voler des credentials
Les NetworkPolicies implémentent le principe du moindre privilège réseau : on bloque tout, puis on ouvre uniquement les flux documentés et nécessaires.
⚠️ Attention : Les NetworkPolicies nécessitent un CNI compatible. Calico, Cilium et Weave Net les supportent. Flannel seul ne les supporte PAS — les policies seront acceptées par l’API mais jamais appliquées. Vérifie ton CNI avant de compter dessus.
Comprendre le modèle NetworkPolicy
Une NetworkPolicy est une ressource Kubernetes qui s’applique à un ensemble de Pods (via podSelector) dans un namespace donné. Elle définit des règles ingress (trafic entrant) et egress (trafic sortant).
Voici les concepts clés :
- podSelector : cible les Pods auxquels la policy s’applique. Un sélecteur vide
{}cible tous les Pods du namespace. - policyTypes : déclare si la policy gère l’ingress, l’egress, ou les deux.
- ingress/egress rules : listes de sources/destinations autorisées avec les ports associés.
💡 Tip DevOps : Les NetworkPolicies sont additives. Si plusieurs policies ciblent le même Pod, les règles se cumulent (union). Il n’y a pas de règle “deny” explicite — c’est l’absence d’autorisation qui bloque.
🧠 À retenir : Dès qu’un Pod est ciblé par au moins une NetworkPolicy avec policyTypes: ["Ingress"], tout le trafic entrant non explicitement autorisé est bloqué. Même logique pour l’egress. C’est un modèle “default deny implicite par sélection”.
Commandes essentielles et policies de base
La première étape dans tout namespace de production : bloquer tout le trafic par défaut.
Cette policy cible tous les Pods du namespace (sélecteur vide) et déclare ingress + egress sans aucune règle d’autorisation :
# default-deny-all.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
Applique-la et vérifie l’état avec ces commandes :
# Appliquer la policy
kubectl apply -f default-deny-all.yaml
# Lister les policies d'un namespace
kubectl get networkpolicies -n production
# Voir le détail d'une policy
kubectl describe networkpolicy default-deny-all -n production
Ensuite, tu ouvres les flux un par un. Voici une policy qui autorise le frontend à parler au backend sur le port 8080, tout en laissant passer le DNS (indispensable) :
# allow-frontend-to-backend.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-backend
namespace: production
spec:
podSelector:
matchLabels:
app: backend
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
⚠️ Attention : Si tu as un deny-all egress, le DNS est bloqué aussi. Tes Pods ne pourront plus résoudre de noms de services. Il faut toujours ajouter une règle egress DNS :
# allow-dns.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns
namespace: production
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
Cas concret : micro-segmenter une application e-commerce
🔥 Cas réel : Tu gères une application e-commerce avec trois tiers — frontend, api, postgresql. Voici les règles métier :
- Le frontend reçoit le trafic externe et ne parle qu’à l’api (port 8080)
- L’api accepte le trafic du frontend et de Prometheus (monitoring cross-namespace), et parle à postgresql (port 5432)
- PostgreSQL n’accepte que l’api, ne parle à personne
Cette policy couvre le tier API, le plus complexe car il a des flux ingress et egress multi-sources :
# netpol-api-tier.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: api-tier-policy
namespace: ecommerce
spec:
podSelector:
matchLabels:
tier: api
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
tier: frontend
ports:
- protocol: TCP
port: 8080
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: monitoring
podSelector:
matchLabels:
app: prometheus
ports:
- protocol: TCP
port: 8080
egress:
- to:
- podSelector:
matchLabels:
tier: database
ports:
- protocol: TCP
port: 5432
- to:
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
💡 Tip DevOps : Note la différence entre les deux règles ingress. La première (podSelector seul) cible des Pods dans le même namespace. La seconde combine namespaceSelector + podSelector dans le même objet — c’est un AND logique : “les Pods avec label app: prometheus ET qui sont dans le namespace monitoring”. Si tu les mettais dans deux objets séparés de la liste, ce serait un OR — et tu ouvrirais beaucoup trop large.
Pour tester la segmentation, utilise kubectl exec :
# Depuis le frontend → api (doit fonctionner)
kubectl exec -n ecommerce deploy/frontend -- curl -s -o /dev/null -w "%{http_code}" http://api:8080/health
# Depuis le frontend → postgresql (doit échouer / timeout)
kubectl exec -n ecommerce deploy/frontend -- nc -zv -w3 postgresql 5432
# Depuis l'api → postgresql (doit fonctionner)
kubectl exec -n ecommerce deploy/api -- nc -zv -w3 postgresql 5432
Pièges fréquents
1. Oublier le DNS — C’est LE piège numéro un. Tu poses un deny-all egress, tes Pods ne résolvent plus rien, et tu passes 2 heures à chercher pourquoi curl api:8080 timeout alors que la policy ingress est bonne.
2. Confondre AND et OR dans les sélecteurs — Deux conditions dans le même objet from = AND. Deux objets dans la liste from = OR. Se tromper ici ouvre ou ferme des flux sans que tu t’en rendes compte.
3. Croire que Flannel applique les policies — L’API Kubernetes accepte les NetworkPolicies quel que soit le CNI. Mais sans support CNI, elles sont purement décoratives. Vérifie avec un test réel, pas juste un kubectl get.
4. Ne pas tester après déploiement — Une policy YAML qui “a l’air correcte” peut avoir un sélecteur de labels qui ne matche aucun Pod. Toujours valider avec kubectl exec + curl/nc.
⚠️ Attention : Les NetworkPolicies ne s’appliquent qu’au trafic Pod-to-Pod géré par le CNI. Le trafic qui passe par un NodePort ou un LoadBalancer entre par le nœud avant d’être routé — les règles exactes dépendent de ton CNI et de la configuration externalTrafficPolicy.
Exercice pratique
Déploie trois Pods dans un namespace segmentation-lab :
- web (label
tier: web) — écoute sur le port 80 - api (label
tier: api) — écoute sur le port 3000 - db (label
tier: db) — écoute sur le port 5432
Implémente ces règles :
- Default deny all (ingress + egress) sur le namespace
- Le web peut parler à l’api sur le port 3000
- L’api peut parler au db sur le port 5432
- Le web ne peut PAS parler directement au db
- Tous les Pods peuvent résoudre le DNS
- Le web peut recevoir du trafic depuis n’importe quel namespace (simule un ingress controller)
Teste chaque règle avec kubectl exec et nc -zv. Documente les résultats.
🧠 À retenir : L’exercice suit le pattern réel en production — default deny + ouverture sélective. Si tu sais faire ça proprement, tu sais sécuriser n’importe quel namespace.
À retenir
- Par défaut, tout est ouvert dans Kubernetes. Les NetworkPolicies sont le seul moyen natif de segmenter le réseau.
- Toujours commencer par un default deny (ingress + egress) sur chaque namespace de production.
- Ne jamais oublier le DNS dans les règles egress — sans lui, plus rien ne fonctionne.
- AND vs OR : deux conditions dans le même objet = AND, deux objets dans la liste = OR. C’est la source d’erreur la plus courante.
- Tester systématiquement avec
kubectl exec+curl/ncaprès chaque policy. - Les NetworkPolicies sont additives et namespace-scoped — pas de deny explicite, pas de policy globale sans outil tiers.
- Vérifie ton CNI : sans support (Calico, Cilium), les policies existent dans l’API mais ne sont jamais appliquées.
➡️ La suite : maintenant que ton réseau est segmenté, on passe au stockage et à la persistance — PersistentVolumes, StorageClasses et StatefulSets.
🖥️ Pratique sur ton propre serveur
Pour suivre Apprendre Kubernetes en conditions réelles, tu as besoin d'un VPS. DigitalOcean offre 200$ de crédit gratuit pour démarrer.
Contenu réservé aux abonnés
Ce chapitre fait partie de la formation complète. Abonne-toi pour débloquer tous les contenus.
Débloquer pour 29 CHF/moisLe chapitre 1 de chaque formation est gratuit.
Série pas encore débloquée
Termine la série prérequise d'abord pour accéder à ce contenu.
Aller à la série prérequiseSérie : Apprendre Kubernetes
8 / 12- Pourquoi Kubernetes ? L'orchestration expliquée
- Architecture K8s et premières commandes kubectl
- Deployments : déployer et mettre à jour
- Services : exposer tes applications
- Volumes et stockage persistant
- ConfigMaps et Secrets
- RBAC : qui a accès à quoi
- 8 Network Policies et Pod Security
- 9 CNI et networking K8s en détail
- 10 Service Mesh : Istio et Linkerd
- 11 Helm : le package manager de K8s
- 12 Créer et publier son chart Helm
Sur cette page
Articles liés
RBAC : qui a accès à quoi
Maîtrise le RBAC Kubernetes : Roles, ClusterRoles, Bindings et contrôle d'accès granulaire.
Pourquoi Kubernetes ? L'orchestration expliquée
Découvre pourquoi Kubernetes est devenu le standard de l'orchestration : architecture, concepts fondamentaux et installation locale.
Architecture K8s et premières commandes kubectl
Installe Kind, lance ton premier déploiement et maîtrise les commandes kubectl essentielles.