NetworkPolicy (Firewall interne des pods kubernetes)

Dans ce chapitre, nous comprendrons le fonctionnement des NetworkPolicies dans k8s. Nous continuerons ensuite par un exercice pratique.

Introduction

Un NetworkPolicy est une spécification de la façon dont les pods sont autorisés à communiquer entre eux, c'est en quelque sorte un Firewall interne au pod qui autorise ou interdit les connexions entrantes ou/et sortantes. Le NetworkPolicy utilise des labels pour sélectionner les pods et définir des règles qui spécifient le trafic autorisé vers les pods sélectionnés.

Les stratégies réseau sont implémentées par le plugin réseau (CNI, rappel ici), vous devez donc utiliser une solution réseau qui prend en charge les NetworkPolicies. Par exemple, au jour ou j'écris cet article, le CNI flannel ne supporte pas les NetworkPolicies.

Information

Par défaut, les pods ne sont pas isolés, c'est-à-dire qu'ils acceptent le trafic de toute source. Les pods deviennent isolés en ayant un NetworkPolicy.

NetworkPolicy

Ingress et Egress

Avant de commencer par la création d'un NetworkPolicy, il est important au préalable de définir le mot Ingress et Egress :

  • Ingress: traffic entrant sur le pod
  • Egress: traffic sortant sur le pod

Si vous souhaitez limiter les communications entrantes de votre pod, alors vous utiliserez alors une règle Ingress, dans le cas ou vous souhaitez contrôler les communications sortantes de notre pod on utilisera des règles Egress.

Exemple

Dans cet exemple, on souhaite protéger les communications des pods de notre cluster. Dans ce cluster, nous disposons d'un pod de base de données mysql avec comme label role: db écoutant sur le port 3306, et un second pod web nginx écoutant sur le port 80 avec comme label role: web.

Dans un plan de sécurité continue, nous ambitionnons de sécuriser la communication entre nos deux pods, en n'autorisant que le traffic provenant de notre pod web nginx avec le role role: web vers notre pod mysql. Nous allons pour notre exemple, créer un NetworkPolicy avec une règle Ingress sur notre pod mysql. Ce qui nous donne le schéma suivant :

exemple d'un NetworkPolicy kubernetes

Afin de réaliser notre exemple, nous commencerons par créer nos deux pods. Débutons avec le pod de base de données mysql ayant le label role: db :

apiVersion: v1
kind: Pod
metadata:
  labels:
    role: db
  name: mysql
spec:
  containers:  
  - image: mysql
    name: mysql

Lançons la commande de création :

kubectl create -f mysql.yaml

Ensuite, nous créons un pod de notre serveur web avec le label role: web :

apiVersion: v1
kind: Pod
metadata:
  labels:
    role: web
  name: nginx
spec:
  containers:  
  - image: nginx
    name: nginx

Exécutons la commande de création :

kubectl create -f web.yaml

Maintenant, nous passerons à la partie la plus intéressante, à savoir la création de notre NetworkPolicy. Comme dit précédemment, nous créerons une règle Ingress sur notre pod mysql n'autorisant que le traffic provenant de notre pod nginx. Pour ce faire, nous nous baserons sur les labels de chaque pod :

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      role: db
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          role: web
    ports:
    - protocol: TCP
      port: 3306
  • podSelector : chaque NetworkPolicy inclut un podSelector qui sélectionne le groupe de pods auquel la politique s'applique. L'exemple ci-dessus sélectionne des modules avec la label role = db. Si le champ est vide alors le podSelector sélectionne tous les pods de le namespace.
  • policyTypes : chaque NetworkPolicy comprend une policyTypes qui peut inclure soit la valeur Ingress, Egress ou les deux. Ce champ indique si la stratégie donnée s'applique ou non au trafic entrant vers le pod sélectionné, au trafic sortant des pods sélectionnés, ou les deux. Si aucun policyTypes n'est spécifié sur un NetworkPolicy, par défaut, l'Ingress sera toujours défini.
  • Ingress : chaque NetworkPolicy peut inclure une liste de règles ingress. Chaque règle autorise un trafic qui correspond à la fois aux sections from et ports. L'exemple de stratégie contient une règle unique sur le port 3306, autorisant tous les pods avec le label role: db sur le namespace default. (Vous pouvez aussi autoriser des plages d'ip avec le champ ipBlock, ou par namespace namespaceSelector)

Il suffit maintenant de créer votre NetworkPolicy avec la commande kubectl apply ou create :

kubectl create -f mysql.yaml

Conclusion

Dans ce chapitre, nous avons pu comprendre le fonctionnement des NetworkPolicies dans kubernetes. Vous l'aurez compris, les NetworkPolicies sont un bon moyen pour protéger vos pods contre les communications inutiles voire dangereuses. Par la suite, nous nous sommes consacrés à un exemple pratique, mais si jamais vous souhaitez vous exercer davantage, essayez alors de créer une règle Egress en plus de la règle Ingress, n'autorisant que du traffic sortant vers vos pods nginx depuis votre pod mysql.

Espace commentaire

Écrire un commentaire

Rejoignez la discussion

Vous devez être connecté pour poster un message.

28 commentaires

ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Bien joué, c'est comme ça qu'on apprend. Pense à bien tester tes règles en staging avant de les balancer en prod.

14/01/2020 à 21:25
etienne-allard
Membre Actif
Avatar de etienne-allard
etienne-allard
Membre Actif

J'ai testé l'exercice de la fin sur le trafic sortant, ça fonctionne bien.

14/01/2020 à 16:22
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Il faut autoriser le port 53 en UDP/TCP vers le namespace kube-system.

14/01/2020 à 11:16

Peut-on autoriser tout le trafic Egress vers le DNS du cluster ?

14/01/2020 à 05:36
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Supprime la policy temporairement avec kubectl delete netpol pour isoler le problème.

13/01/2020 à 23:43
wgay
Membre Actif
Avatar de wgay
wgay
Membre Actif

Comment on debug une règle qui bloque trop ?

13/01/2020 à 19:01
amelie-marin
Membre Actif
Avatar de amelie-marin
amelie-marin
Membre Actif

Merci pour l'exemple, ça fonctionne nickel après avoir switché sur Calico.

13/01/2020 à 14:50
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

C'est négligeable, c'est géré au niveau des iptables ou eBPF selon ton CNI.

13/01/2020 à 07:25
valette-suzanne
Membre Actif
Avatar de valette-suzanne
valette-suzanne
Membre Actif

Est-ce que ça impacte les performances réseau au niveau du cluster ?

13/01/2020 à 02:27
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Vérifie la syntaxe du except dans ton bloc ipBlock.

12/01/2020 à 19:28
josephine-lesage
Membre Actif
Avatar de josephine-lesage
josephine-lesage
Membre Actif

J'ai un souci avec mon ipBlock, il semble ignorer les plages exclues. Une piste ?

12/01/2020 à 13:50
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Non, le kubectl exec passe par le kubelet et l'API server, ça ne devrait pas être bloqué par les NetworkPolicies.

12/01/2020 à 07:26
aurore-martineau
Membre Actif
Avatar de aurore-martineau
aurore-martineau
Membre Actif

J'ai mis en place la règle, mais je n'arrive plus à me connecter en kubectl exec sur mon pod mysql. C'est normal ?

11/01/2020 à 23:38
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

C'est simple : Ingress c'est ce qui arrive sur ton pod, Egress c'est ce qui en sort.

11/01/2020 à 16:04
dominique-gauthier
Membre Actif
Avatar de dominique-gauthier
dominique-gauthier
Membre Actif

C'est quoi la différence entre Ingress et Egress au juste ?

11/01/2020 à 09:07
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Oui, si ton pod a un containerPort nommé dans son manifest, tu peux utiliser ce nom.

11/01/2020 à 04:06
adelaide-hamel
Membre Actif
Avatar de adelaide-hamel
adelaide-hamel
Membre Actif

J'ai une erreur sur port: 3306. Est-ce qu'on peut mettre un nom de port au lieu du numéro ?

10/01/2020 à 20:35
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Oui, tu peux mixer podSelector et namespaceSelector dans la même règle from.

10/01/2020 à 14:24
xcaron
Membre Actif
Avatar de xcaron
xcaron
Membre Actif

Est-ce qu'on peut filtrer par namespace avec le namespaceSelector ?

10/01/2020 à 08:13
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Utilise kubectl describe netpol test-network-policy pour voir si elle est bien appliquée au sélecteur.

10/01/2020 à 02:30
mhamon
Membre Actif
Avatar de mhamon
mhamon
Membre Actif

Même problème que le voisin, mon kubectl create ne produit aucun effet visible sur le trafic. Comment vérifier que la policy est active ?

09/01/2020 à 19:13
moulin-julie
Membre Actif
Avatar de moulin-julie
moulin-julie
Membre Actif

Comment je peux autoriser tout le trafic sortant sauf vers une IP spécifique ?

09/01/2020 à 12:10
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Par défaut, ils sont totalement ouverts. C'est en appliquant une première NetworkPolicy que tu les isoles.

09/01/2020 à 06:31
elise57
Membre Actif
Avatar de elise57
elise57
Membre Actif

Question bête : si je ne définis rien, mes pods sont isolés ou ouverts ?

09/01/2020 à 01:03
ajdaini-hatim
Auteur Rédacteur Secouriste Actif
Avatar de ajdaini-hatim
ajdaini-hatim
Auteur Rédacteur Secouriste Actif

Vérifie ton indentation dans le fichier, c'est souvent là que ça coince. Voici le format correct :

spec:
  podSelector:
    matchLabels:
      role: db
  policyTypes:
  - Ingress
08/01/2020 à 18:53

Rejoindre la communauté

Recevoir les derniers articles gratuitement en créant un compte !

S'inscrire