Skip to main content

Bonnes pratiques pour les politiques réseau Kubernetes

Écrit par

Peter De Tender

Kubernetes Blog

21 décembre 2022

0 minutes de lecture

Contrôler et filtrer le trafic lors de la conteneurisation d’une charge de travail au sein de Pods Kubernetes est tout aussi crucial que l’utilisation d’un pare-feu dans une configuration réseau plus traditionnelle. La différence, dans ce cas, est que ces fonctionnalités sont fournies par l’API Kubernetes NetworkPolicy.

Cet article présente Kubernetes NetworkPolicy à travers la création d’un exemple de politique réseau et l’examen de ses principaux paramètres. Nous aborderons ensuite des cas d’usage courants de NetworkPolicy et verrons comment les surveiller avec kubectl. Enfin, nous découvrirons comment mettre en œuvre l’interface réseau de conteneurs (CNI) à l’aide d’extensions Kubernetes tierces.

Pourquoi ne pas hésiter à adopter les politiques réseau Kubernetes

La mise en œuvre de politiques réseau est essentielle à l’exploitation d’un environnement Kubernetes. Sans politique réseau configurée, tous les Pods d’un cluster peuvent communiquer entre eux par défaut. Ainsi, si notre Pod contient des données sensibles, comme une base de données backend renfermant des informations confidentielles, nous devons veiller à ce que seuls certains Pods frontend puissent s’y connecter.

Autre possibilité : isoler le trafic réseau entre les Pods d’un environnement de développement et ceux qui s’exécutent dans un environnement de production. Sans politiques réseau, le trafic circule librement dans les deux sens entre tous les points du réseau.

Heureusement, configurer Kubernetes NetworkPolicy est un moyen simple, efficace et global de garantir que le trafic réseau circule uniquement comme prévu.

Définir des politiques réseau Kubernetes

Examinons un exemple de NetworkPolicy. Prenons une charge de travail exemple avec un frontend WordPress et un backend de base de données MySQL, composée d’un ensemble de Pods exécutant des services Web et de base de données, tous déployés dans l’espace de noms Kubernetes default. Les protocoles de sécurité de l’entreprise exigent que nous isolions le trafic réseau de certaines charges de travail et que nous limitions le trafic entrant et sortant autorisé au strict nécessaire.

Cette stratégie repose sur les conditions suivantes :

  • Bloquer le comportement par défaut de Kubernetes qui autorise tout le trafic.

  • Veiller à ce que seuls les Pods portant le libellé wordpress dans l’espace de noms default puissent communiquer entre eux.

  • Autoriser les connexions entrantes (ingress) depuis l’Internet public sur les ports 80/443 et depuis la plage d’adresses IP 172.16.0.0.

  • Autoriser uniquement les Pods portant le libellé wordpress à se connecter aux Pods de base de données MySQL sur le port 3306.

  • Toujours autoriser les connexions au service DNS Kubernetes (port 53).

  • Bloquer toutes les connexions sortantes vers l’extérieur du cluster.

Le schéma réseau ci-dessous illustre à quoi ces règles pourraient ressembler.

Schéma illustrant les règles par défaut de refus du trafic entrant et sortant dans un espace de noms Kubernetes, avec autorisation du trafic sur les ports 80 et 443 et du trafic DNS.

Pour cet exemple, nous pouvons répartir les politiques réseau entre plusieurs fichiers de définition ou les regrouper dans un seul fichier manifeste YAML. Comme notre exemple porte sur une seule charge de travail (webapp), il est logique d’utiliser un seul fichier de définition des règles. Toutefois, puisqu’il comprend plusieurs connexions entrantes et sortantes, nous pourrions aussi créer un fichier de configuration distinct pour chaque connexion au sein du cluster.

Passons en revue plusieurs paramètres utilisés ci-dessus pour comprendre leur lien avec la configuration et leur effet sur le comportement du trafic réseau.

API et métadonnées

À la première ligne du fichier YAML ci-dessous, nous indiquons l’API réseau (networking.k8s.io) et sa version (v1). Nous définissons également le type de fichier YAML comme étant NetworkPolicy, pour indiquer au contrôleur de l’API Kubernetes que nous configurons des politiques réseau. Les éléments name et namespace de la section metadata contiennent le nom que nous attribuons à cet ensemble de règles et l’espace de noms auquel il est associé.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: sample-network-policy
  namespace: default

La partie suivante du fichier YAML contient la section des spécifications (specs), dans laquelle nous pouvons définir les filtres auxquels la politique réseau s’appliquera.

L’extrait ci-dessous présente plusieurs paramètres essentiels :

  • podSelector — Indique quels Pods sont soumis aux politiques de trafic définies. Dans notre exemple, le paramètre matchLabels garantit que la politique réseau s’applique à tous les Pods portant le libellé app: wordpress. Il en résulte également que tous les autres Pods sont exclus de cette politique réseau.

  • policyTypes — Comprend deux catégories : Ingress et Egress

  • Ingress — Définit tout le trafic entrant vers les Pods, les espaces de noms ou les collections de Pods

  • Egress — Définit tout le trafic sortant des Pods, des espaces de noms ou des collections de Pods

spec:
  podSelector:
    matchLabels:
      app: wordpress
  policyTypes:
    - Egress
    - Ingress

Ensuite, la section ingress de la politique réseau définit les types de trafic entrant autorisés. La section ci-dessous autorise le trafic entrant sur les ports 443 et 80 depuis :

  • Tous les Pods portant le libellé wordpress

  • Tout le trafic provenant de l’Internet public (cidr: 0.0.0.0/0)

  • Toutes les adresses IP de la plage 172.16.0.0/16, qui peut correspondre à une plage d’adresses IP d’entreprise (VPN, VLAN ou sous-réseau).

L’extrait YAML qui autorise le trafic ci-dessus ressemblerait à ceci :

  ingress:
    - from:
      - podSelector:
          matchLabels:
            app: wordpress
      ports:
        - port: 443
        - port: 80  
    - from:
      - ipBlock:
          cidr: 172.16.0.0/16
      ports:
        - port: 443
        - port: 80
    - from:
      - ipBlock:
          cidr: 0.0.0.0/0
      ports:
        - port: 443
        - port: 80

Enfin, détaillons la section egress qui contient les règles de trafic sortant. Nous autorisons toutes les communications sortantes des Pods portant le libellé webapp sur les ports 1433 (SQL) et 53 (DNS).

En précisant le libellé webapp, nous veillons à ce qu’aucun autre Pod ne puisse communiquer avec les instances SQL Server, éliminant ainsi tous les risques de sécurité associés. De même, la configuration autorise le port 53 à se connecter à tous les Pods du cluster.

Cette définition de politique comporte un autre point essentiel à retenir. Lorsque nous intégrons une politique réseau pour contrôler la connectivité des Pods, nous devons configurer les paramètres d’autorisation et de refus dans les deux sens. Autoriser le trafic sortant du frontend sans autoriser le trafic entrant vers le backend empêchera toute communication.

L’extrait YAML correspondant à cette partie du trafic ressemble à l’exemple ci-dessous :

  egress: 
    - to:
        - namespaceSelector: {}
          podSelector:
            matchLabels:
              k8s-app: kube-dns
      ports:
        - port: 53
          protocol: UDP

    - to:
        - podSelector:
            matchLabels:
              app: wordpress
      ports:
        - port: 3306

Appliquer des politiques réseau Kubernetes

Nous avons terminé notre exemple de manifeste YAML Network Policy. Le voici :

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: sample-network-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: webapp
  policyTypes:
    - Egress
    - Ingress
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: webapp
      ports:
        - port: 443
        - port: 80
    - from:
        - podSelector: {}
    - from:
        - ipBlock:
            cidr: 172.16.0.0/16
      ports:
        - port: 443
        - port: 80
    - from:
        - ipBlock:
            cidr: 0.0.0.0/0
      ports:
        - port: 443
        - port: 80
  egress:
    - to:
        - namespaceSelector: {}
          podSelector:
            matchLabels:
              k8s-app: kube-dns
      ports:
        - port: 53
          protocol: UDP
    - to:
        - podSelector: {}
    - to:
        - podSelector:
            matchLabels:
              app: webapp
      ports:
        - port: 443
        - port: 80

Nous devons maintenant injecter notre fichier dans le cluster Kubernetes. Pour ce faire, enregistrez d’abord ce fichier sous le nom sample-network-policy.yaml.

Nous appliquons ensuite le fichier de définition comme la plupart des autres configurations Kubernetes, à l’aide de l’interface de ligne de commande kubectl (CLI).

Exécutez la commande suivante :

kubectl apply -f sample-network-policy.yaml
Terminal affichant l’exécution de kubectl apply pour créer l’exemple de stratégie réseau Kubernetes

Valider et surveiller les politiques réseau Kubernetes

Comme pour la gestion traditionnelle des pare-feu, la validation et la surveillance des politiques réseau Kubernetes nécessitent un suivi opérationnel. Nous devons parfois réévaluer les règles réseau existantes pour déterminer si elles s’appliquent toujours à la charge de travail concernée.

Nous pouvons également devoir valider l’ensemble de règles afin de résoudre des problèmes de trafic ou d’examiner les conflits entre différentes politiques réseau. Heureusement, nous pouvons valider les politiques réseau à l’aide de la CLI kubectl. Exécutez la commande suivante pour analyser et surveiller vos politiques réseau actuelles :

kubectl describe networkpolicy <networkpolicy name as listed in the YAML manifest>

Voici un exemple de résultat pour le type de politique ingress.

Sortie du terminal affichant une Kubernetes NetworkPolicy, avec « Autorisation du trafic entrant » en surbrillance et des règles pour les ports 443 et 80.

Cette image présente également un exemple de résultat pour le type de politique egress :

Sortie du terminal affichant le trafic sortant autorisé vers kube-dns et les pods de l’application web, avec les types de stratégies Egress et Ingress

Bonnes pratiques pour appliquer des politiques réseau Kubernetes

Comme pour toute configuration de sécurité réseau, nous devrions appliquer plusieurs bonnes pratiques à nos politiques réseau Kubernetes :

  • Utilisez la politique réseau par défaut deny-all pour garantir que seules les communications explicitement autorisées ont lieu.

  • Regroupez les Pods qui doivent communiquer entre eux à l’aide du paramètre PodSelector.

  • N’autorisez la communication entre espaces de noms qu’en cas de nécessité.

  • N’autorisez pas les communications réseau superflues, même au sein du cluster Kubernetes.

  • Faites preuve de prudence lorsque vous autorisez les Pods du cluster à recevoir du trafic réseau provenant de l’extérieur du cluster.

  • Bloquer le trafic sortant vers l’Internet public peut perturber certaines mises à jour d’applications ou certains processus de validation.

Les plugins CNI Kubernetes optimisent la gestion des politiques réseau

L’un des avantages des plugins CNI est qu’ils abstraient les détails de mise en œuvre de Network Policy. Les administrateurs de cluster peuvent ainsi choisir la solution la mieux adaptée à leurs besoins sans avoir à se confronter à la complexité des technologies sous-jacentes.

Cependant, les installations Kubernetes par défaut ne comprennent aucun plugin CNI préinstallé, sauf si votre distribution ou votre fournisseur en a ajouté un. Vous devrez donc choisir et installer le plugin qui répond le mieux à vos besoins. Même si votre distribution propose un plugin par défaut, un autre pourrait mieux satisfaire vos exigences.

Il existe de nombreux fournisseurs CNI, parmi lesquels les plus populaires sont :

Chaque plugin possède des fonctionnalités qui lui sont propres. Vous devrez peut-être en essayer plusieurs pour déterminer lequel répond le mieux à vos exigences en matière de réseau et de sécurité réseau.

Conclusion

Configurer une topologie réseau d’entreprise avec des règles de routage et de trafic complexes ainsi que des intégrations de sécurité peut être fastidieux. Heureusement, dans un environnement Kubernetes, les politiques réseau remplissent le rôle que les pare-feu jouaient au mieux dans les infrastructures traditionnelles.

Bien sûr, configurer des politiques réseau n’est que la première étape d’un processus qui nécessite des réévaluations et une maintenance régulières. Le plugin kubenet intégré fournit certaines fonctionnalités réseau pour gérer vos politiques, mais d’autres plugins CNI offrent des fonctionnalités plus avancées. Heureusement, en associant les bonnes politiques aux bons outils de gestion, vous garantissez la sécurité et l’efficacité du trafic réseau.

Ressources supplémentaires sur la sécurité Kubernetes

Sécurisez votre infrastructure dès la source

Snyk automatise la sécurité et la conformité de l’IaC dans vos workflows, et détecte les ressources dont la configuration a dérivé ou qui sont manquantes.