Configurer plusieurs interfaces réseau pour des pods

Ce document explique comment configurer Google Distributed Cloud pour fournir plusieurs interfaces réseau à plusieurs cartes d'interface réseau pour vos pods. La fonctionnalité de cartes d'interface réseau multiples pour les pods peut aider à distinguer le trafic du plan de contrôle de celui du plan de données, créant ainsi une isolation entre les plans. Des interfaces réseau supplémentaires permettent également d'utiliser la fonctionnalité de multidiffusion pour vos pods. La fonctionnalité de cartes d'interface réseau multiples pour les pods n'est disponible que dans les clusters d'utilisateur, les clusters hybrides et les clusters autonomes. Elle n'est pas autorisée dans les clusters de type administrateur.

L'isolation du plan réseau est importante pour les systèmes qui utilisent la virtualisation des fonctions réseau (NFV), telles les réseaux définis par logiciel dans un réseau étendu (SD-WAN), un agent de sécurité des accès au cloud (CASB) ou les pare-feu nouvelle génération (NG-FW). Ces types de NFV reposent sur l'accès à plusieurs interfaces pour séparer la gestion et les plans de gestion de données, tout en s'exécutant en tant que conteneurs.

La configuration de plusieurs interfaces réseau permet d'associer des interfaces réseau à des pools de nœuds, ce qui peut offrir des performances accrues. Les clusters peuvent contenir différents types de nœuds combinés. Lorsque vous regroupez des machines hautes performances dans un pool de nœuds, vous pouvez ajouter des interfaces supplémentaires au pool de nœuds pour améliorer le flux de trafic.

Configurer plusieurs interfaces réseau

En règle générale, la configuration de plusieurs interfaces réseau dans vos pods comporte trois étapes :

  1. Activez la fonctionnalité de cartes d'interface réseau multiples dans votre cluster avec le champ multipleNetworkInterfaces défini dans la ressource personnalisée du cluster.

  2. Spécifiez les interfaces réseau avec des ressources personnalisées NetworkAttachmentDefinition.

  3. Attribuez des interfaces réseau aux pods avec l'annotation k8s.v1.cni.cncf.io/networks.

Des informations supplémentaires sont fournies pour vous aider à configurer et à utiliser la fonctionnalité de cartes d'interface réseau multiples de façon à répondre au mieux à vos exigences de mise en réseau.

Activer plusieurs cartes d'interface réseau

Activez plusieurs cartes d'interface réseau dans vos pods en ajoutant le champ multipleNetworkInterfaces à la section clusterNetwork de la ressource personnalisée du cluster et en le définissant sur true.

  ...
  clusterNetwork:
    multipleNetworkInterfaces: true
    pods:
      cidrBlocks:
      - 192.168.0.0/16
    services:
      cidrBlocks:
      - 10.96.0.0/20
  ...

Spécifier des interfaces réseau

Utilisez les ressources personnalisées NetworkAttachmentDefinition pour spécifier des interfaces réseau supplémentaires. Les ressources personnalisées NetworkAttachmentDefinition correspondent aux réseaux disponibles pour vos pods. Vous pouvez spécifier les ressources personnalisées dans la configuration du cluster, comme indiqué dans l'exemple suivant, ou créer les ressources personnalisées NetworkAttachmentDefinition directement.

---
apiVersion: baremetal.cluster.gke.io/v1
kind: Cluster
metadata:
  name: my-cluster
  namespace: cluster-my-cluster
spec:
    type: user
    clusterNetwork:
      multipleNetworkInterfaces: true
...
---
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: gke-network-1
  namespace: cluster-my-cluster
spec:
  config: '{
  "cniVersion":"0.3.0",
  "type": "ipvlan",
  "master": "enp2342",  # defines the node interface that this pod interface would
                         map to.
  "mode": "l2",
  "ipam": {
    "type": "whereabouts",
    "range": "172.120.0.0/24"
  }
}'
---
apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  name: gke-network-2
  namespace: cluster-my-cluster
spec:
  config: '{
  "cniVersion":"0.3.0",
  "type": "macvlan",
  "mode": "bridge",
  "master": "vlan102",
  "ipam": {
    "type": "static",
    "addresses": [
      {
        "address": "10.10.0.1/24",
        "gateway": "10.10.0.254"
      }
    ],
    "routes": [
      { "dst": "192.168.0.0/16", "gw": "10.10.5.1" }
    ]
  }
}'

Lorsque vous spécifiez la ressource personnalisée NetworkAttachmentDefinition dans le fichier de configuration de votre cluster, Google Distributed Cloud utilise ce nom pour contrôler la ressource personnalisée NetworkAttachmentDefinition après la création du cluster. Google Distributed Cloud traite cette ressource personnalisée dans l'espace de noms du cluster comme source de référence et la rapproche de l'espace de noms default du cluster cible.

Le schéma suivant montre comment Google Distributed Cloud rapproche les ressources personnalisées NetworkAttachmentDefinition de l'espace de noms spécifique au cluster avec l'espace de noms default.

Rapprochement de NetworkAttachmentDefinition

Bien que cette option soit facultative, nous vous recommandons de spécifier les ressources personnalisées NetworkAttachmentDefinition de cette manière lors de la création du cluster. L'avantage de spécifier les ressources personnalisées lors de la création de votre cluster concerne surtout les clusters d'utilisateur, car vous pouvez contrôler ces ressources NetworkAttachmentDefinition à partir du cluster d'administrateur.

Si vous choisissez de ne pas spécifier de ressources personnalisées NetworkAttachmentDefinition lors de la création du cluster, vous pouvez ajouter les ressources personnalisées NetworkAttachmentDefinition directement à un cluster cible existant. Google Distributed Cloud rapproche les ressources personnalisées NetworkAttachmentDefinition définies dans l'espace de noms du cluster. Le rattachement se produit également lors de la suppression. Lorsqu'une ressource personnalisée NetworkAttachmentDefinition est supprimée d'un espace de noms de cluster, Google Distributed Cloud la supprime du cluster cible.

Attribuer des interfaces réseau à un pod

Utilisez l'annotation k8s.v1.cni.cncf.io/networks pour attribuer une ou plusieurs interfaces réseau à un pod. Chaque interface réseau est spécifiée avec un espace de noms et le nom d'une ressource personnalisée NetworkAttachmentDefinition, séparés par une barre oblique (/).

---
apiVersion: v1
kind: Pod
metadata:
  name: samplepod
  annotations:
    k8s.v1.cni.cncf.io/networks: NAMESPACE/NAD_NAME
spec:
  containers:
  ...

Remplacez les éléments suivants :

  • NAMESPACE : espace de noms. Utilisez default comme espace de noms par défaut, qui est standard. Pour en savoir plus sur les exceptions, consultez la section Enjeux de sécurité.
  • NAD_NAME : nom de la ressource personnalisée NetworkAttachmentDefinition.

Utilisez une liste d'éléments séparés par une virgule pour spécifier plusieurs interfaces réseau.

Dans l'exemple suivant, deux interfaces réseau sont attribuées au pod samplepod. Les interfaces réseau sont spécifiées par les noms de deux ressources personnalisées NetworkAttachmentDefinition, gke-network-1 et gke-network-2, dans l'espace de noms par défaut du cluster cible

---
apiVersion: v1
kind: Pod
metadata:
  name: samplepod
  annotations:
    k8s.v1.cni.cncf.io/networks: default/gke-network-1,default/gke-network-2
spec:
  containers:
  ...

Limiter les interfaces réseau à un pool de nœuds

Utilisez l'annotation k8s.v1.cni.cncf.io/nodeSelector pour spécifier le pool de nœuds pour lequel une ressource personnalisée NetworkAttachmentDefinition est valide. Google Distributed Cloud force le déploiement de tous les pods faisant référence à cette ressource personnalisée sur ces nœuds spécifiques. Dans l'exemple suivant, Google Distributed Cloud force le déploiement de tous les pods auxquels l'interface réseau gke-network-1 est attribuée au pool de nœuds multinicNP. Google Distributed Cloud attribue le libellé baremetal.cluster.gke.io/node-pool à un pool de nœuds en conséquence.

apiVersion: "k8s.cni.cncf.io/v1"
kind: NetworkAttachmentDefinition
metadata:
  annotations:
    k8s.v1.cni.cncf.io/nodeSelector: baremetal.cluster.gke.io/node-pool=multinicNP
  name: gke-network-1
spec:
...

Vous n'êtes pas limité à l'utilisation des libellés standards. Vous pouvez créer vos propres pools personnalisés à partir des nœuds du cluster en appliquant un libellé personnalisé à ces nœuds. Exécutez la commande kubectl label nodes pour appliquer un libellé personnalisé :

kubectl label nodes NODE_NAME LABEL_KEY=LABEL_VALUE

Remplacez les éléments suivants :

  • NODE_NAME : nom du nœud auquel vous ajoutez un libellé.
  • LABEL_KEY : clé à utiliser pour le libellé.
  • LABEL_VALUE : nom du libellé.

Une fois le nœud étiqueté, appliquez l'annotation baremetal.cluster.gke.io/label-taint-no-sync sur ce nœud pour empêcher Google Distributed Cloud de rapprocher les libellés. Utilisez la commande kubectl get nodes --show-labels pour vérifier si un nœud est étiqueté.

Enjeux de sécurité

Une ressource personnalisée NetworkAttachmentDefinition fournit un accès complet à un réseau. Par conséquent, les administrateurs de cluster doivent faire preuve de prudence lorsqu'ils fournissent un accès de création, de mise à jour ou de suppression à d'autres utilisateurs. Si une ressource personnalisée NetworkAttachmentDefinition doit être isolée, elle peut être placée dans un espace de noms autre que celui par défaut, auquel seuls les pods de cet espace de noms peuvent accéder. Pour que les ressources personnalisées NetworkAttachmentDefinition spécifiées dans le fichier de configuration du cluster soient rattachées, elles sont toujours placées dans l'espace de noms par défaut.

Dans le schéma suivant, les pods de l'espace de noms default ne peuvent pas accéder à l'interface réseau de l'espace de noms privileged.

Utilisation des espaces de noms pour isoler le trafic réseau

Plug-ins CNI acceptés

Cette section répertorie les plug-ins CNI compatibles avec la fonctionnalité à plusieurs cartes d'interface réseau pour Google Distributed Cloud. Utilisez uniquement les plug-ins suivants lorsque vous spécifiez une ressource personnalisée NetworkAttachmentDefinition.

Création d'interfaces :

  • ipvlan
  • macvlan
  • bridge
  • sriov

Plug-ins meta :

  • portmap
  • sbr
  • tuning

Plug-ins IPAM :

  • host-local
  • static
  • whereabouts

Configuration de la route

Un pod auquel une ou plusieurs ressources personnalisées NetworkAttachmentDefinition sont attribuées possède plusieurs interfaces réseau. Par défaut, la table de routage de cette situation est étendue avec les interfaces supplémentaires disponibles localement à partir des ressources personnalisées NetworkAttachmentDefinition uniquement. La passerelle par défaut est toujours configurée pour utiliser l'interface principale/par défaut du pod, eth0.

Vous pouvez modifier ce comportement à l'aide des plug-ins CNI suivants :

  • sbr
  • static
  • whereabouts

Par exemple, vous souhaiterez peut-être que tout le trafic passe par la passerelle par défaut (à savoir l'interface par défaut), mais que le trafic spécifique passe par l'une des interfaces autres que celle par défaut. Le trafic peut être difficile à distinguer en fonction de l'adresse IP de destination (routage normal), car le même point de terminaison est disponible sur les deux types d'interfaces. Dans ce cas, le routage basé sur la source (SBR, source based routing) peut s'avérer utile.

Plug-in SBR

Le plug-in sbr permet à l'application de contrôler les décisions de routage. L'application contrôle l'élément utilisé en tant qu'adresse IP source de la connexion qu'elle établit. Lorsque l'application choisit d'utiliser l'adresse IP de la ressource personnalisée NetworkAttachmentDefinition comme adresse IP source, les paquets parviennent à l'autre table de routage sbr configurée. La table de routage sbr établit l'interface de la ressource personnalisée NetworkAttachmentDefinition comme passerelle par défaut. L'adresse IP de la passerelle par défaut dans cette table est contrôlée avec le champ gateway dans les plug-ins whereabouts ou static. Fournissez le plug-in sbr en tant que plug-in en chaîne. Pour en savoir plus sur le plug-in sbr, y compris sur son utilisation, consultez la page Plug-in de routage basé sur la source.

L'exemple suivant montre "gateway":"21.0.111.254" défini dans whereabouts et sbr défini en tant que plug-in en chaîne après ipvlan :

# ip route
default via 192.168.0.64 dev eth0  mtu 1500
192.168.0.64 dev eth0 scope link
# ip route list table 100
default via 21.0.111.254 dev net1
21.0.104.0/21 dev net1 proto kernel scope link src 21.0.111.1

Plug-ins de gestion des adresses IP statiques et relatifs à l'emplacement

Le plug-in whereabouts est en fait une extension du plug-in static. Tous deux partagent la même configuration de routage. Pour obtenir un exemple de configuration, consultez la page Plug-in de gestion des adresses IP statiques. Vous pouvez définir une passerelle et une route à ajouter à la table de routage du pod. Vous ne pouvez pas modifier la passerelle par défaut du pod de cette manière.

L'exemple suivant montre l'ajout de "routes": [{ "dst": "172.31.0.0/16" }] à la ressource personnalisée NetworkAttachmentDefinition :

# ip route
default via 192.168.0.64 dev eth0  mtu 1500
172.31.0.0/16 via 21.0.111.254 dev net1
21.0.104.0/21 dev net1 proto kernel scope link src 21.0.111.1
192.168.0.64 dev eth0 scope link

Exemples de configuration

Cette section présente quelques configurations réseau courantes compatibles avec la fonctionnalité de cartes d'interface réseau multiples.

Un seul rattachement de réseau utilisé par plusieurs pods

Un seul rattachement de réseau utilisé par plusieurs pods

Plusieurs rattachements de réseau utilisés par un même pod

Plusieurs rattachements de réseau utilisés par un même pod

Plusieurs rattachements de réseau pointant vers la même interface utilisée par un seul pod

Plusieurs rattachements de réseau pointant vers la même interface utilisée par un seul pod

Même rattachement de réseau utilisé plusieurs fois par un seul pod

Même rattachement de réseau utilisé plusieurs fois par un seul pod

Résoudre les problèmes

Si des interfaces réseau supplémentaires sont mal configurées, les pods auxquels elles sont attribuées ne démarrent pas. Cette section explique comment trouver des informations pour résoudre les problèmes liés à la fonctionnalité de cartes d'interface réseau multiples.

Vérifier les événements du pod

Multus signale les échecs via des événements de pod Kubernetes. Exécutez la commande kubectl describe suivante pour afficher les événements d'un pod donné :

kubectl describe pod POD_NAME

Vérifier les journaux

Vous pouvez accéder aux journaux Whereabouts et Multus de chaque nœud aux emplacements suivants :

  • /var/log/whereabouts.log
  • /var/log/multus.log

Examiner les interfaces du pod

Exécutez la commande kubectl exec pour vérifier les interfaces de votre pod. Une fois les ressources personnalisées NetworkAttachmentDefinition appliquées, les interfaces du pod se présentent comme suit :

$ kubectl exec samplepod-5c6df74f66-5jgxs -- ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: net1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default
    link/ether 00:50:56:82:3e:f0 brd ff:ff:ff:ff:ff:ff
    inet 21.0.103.112/21 scope global net1
       valid_lft forever preferred_lft forever
38: eth0@if39: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 36:23:79:a9:26:b3 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 192.168.2.191/32 scope global eth0
       valid_lft forever preferred_lft forever

Obtenir l'état du pod

Exécutez la commande kubectl get pour récupérer l'état du réseau d'un pod donné :

kubectl get pods POD_NAME -oyaml

Voici un exemple de résultat indiquant l'état d'un pod comportant plusieurs réseaux :

apiVersion: v1
kind: Pod
metadata:
  annotations:
    k8s.v1.cni.cncf.io/network-status: |-
      [{
          "name": "",
          "interface": "eth0",
          "ips": [
              "192.168.1.88"
          ],
          "mac": "36:0e:29:e7:42:ad",
          "default": true,
          "dns": {}
      },{
          "name": "default/gke-network-1",
          "interface": "net1",
          "ips": [
              "21.0.111.1"
          ],
          "mac": "00:50:56:82:a7:ab",
          "dns": {}
      }]
    k8s.v1.cni.cncf.io/networks: gke-network-1