L'une des exigences de base du modèle de mise en réseau Kubernetes est que chaque pod doit avoir sa propre adresse IP et que tous les autres pod du cluster doivent pouvoir le contacter à cette adresse. Il existe de nombreux "fournisseurs" de réseau (Flannel, Calico, Canal, etc.) qui aident à mettre en œuvre ce modèle de réseau.
Lorsque j'ai commencé à travailler avec Kubernetes, je ne savais pas exactement comment les pods obtenaient leurs adresses IP. Même avec une compréhension du fonctionnement des composants individuels, il était difficile de les imaginer travailler ensemble. Par exemple, je savais à quoi servaient les plugins CNI, mais je ne savais pas comment ils étaient appelés. Par conséquent, j'ai décidé d'écrire cet article pour partager mes connaissances sur les différents composants réseau et comment ils fonctionnent ensemble dans un cluster Kubernetes, ce qui permet à chaque pod d'obtenir sa propre adresse IP unique.
Il existe différentes manières d'organiser la mise en réseau dans Kubernetes, tout comme il existe différentes options d'exécution pour les conteneurs. Cet article utilisera Flannel pour mettre en réseau le cluster et utiliser Containerd comme runtime . Je part également de l'hypothèse que vous savez comment fonctionne la mise en réseau entre les conteneurs, donc je ne vais y toucher que brièvement, uniquement pour le contexte.
Quelques concepts de base
Conteneurs et mise en réseau: un aperçu
Il existe de nombreuses excellentes publications sur Internet expliquant comment les conteneurs communiquent entre eux sur le réseau. Par conséquent, je ne donnerai qu'un aperçu général des concepts de base et me limiterai à une approche, qui consiste à créer un pont Linux et à encapsuler des paquets. Les détails sont omis, car le sujet même de la mise en réseau de conteneurs mérite un article séparé. Des liens vers des publications particulièrement informatives et informatives seront donnés ci-dessous.
Conteneurs sur un seul hôte
Une façon d'établir une communication d'adresse IP entre des conteneurs exécutés sur le même hôte consiste à créer un pont Linux. Pour cela, des périphériques virtuels veth (ethernet virtuel) sont créés dans Kubernetes (et Docker ) . Une extrémité du périphérique veth se connecte à l'espace de noms réseau du conteneur, l'autre se connecte au pont Linux sur le réseau de l'hôte.
Tous les conteneurs sur le même hôte ont une extrémité du veth connectée à un pont par lequel ils peuvent communiquer entre eux en utilisant des adresses IP. Le pont Linux a également une adresse IP et agit comme une passerelle pour le trafic de sortie des pods vers d'autres nœuds.
Conteneurs sur différents hôtes
L'encapsulation de paquets est l'un des moyens par lesquels les conteneurs sur différents hôtes peuvent communiquer entre eux à l'aide d'adresses IP. Dans Flannel , la technologie vxlan est responsable de cette fonctionnalité , qui «emballe» le paquet d'origine dans un paquet UDP et l'envoie ensuite à sa destination.
Dans un cluster Kubernetes, Flannel crée un périphérique vxlan et augmente la table de routage sur chaque nœud en conséquence. Chaque paquet destiné à un conteneur sur un hôte différent passe par le périphérique vxlan et est encapsulé dans un paquet UDP. À la destination, le package imbriqué est extrait et redirigé vers le pod souhaité.
Remarque: il ne s'agit que d'une manière d'organiser la mise en réseau entre les conteneurs.
Qu'est-ce que le CRI?
CRI (Container Runtime Interface) est un plugin qui permet à kubelet d'utiliser différents environnements d'exécution de conteneurs. L'API CRI est intégrée à divers environnements d'exécution, de sorte que les utilisateurs peuvent choisir l'environnement d'exécution de leur choix.
Qu'est-ce que CNI?
Le projet CNI est une spécification pour l'organisation d'une solution de mise en réseau universelle pour les conteneurs Linux. De plus, il inclut des plugins responsables de diverses fonctions lors de la configuration du réseau d'un pod. Le plugin CNI est un fichier exécutable conforme à la spécification (nous discuterons de certains des plugins ci-dessous).
Sous-réseau d'hôtes pour attribuer des adresses IP aux pods
Étant donné que chaque pod du cluster doit avoir une adresse IP, il est important de s'assurer que cette adresse est unique. Pour ce faire, il attribue à chaque hôte un sous-réseau unique, à partir duquel les adresses IP sont ensuite attribuées aux pods de cet hôte.
Contrôleur IPAM hôte
Lorsqu'il est
nodeipam
transmis en tant que paramètre à l' --controllers
indicateur kube-controller-manager , il alloue un sous-réseau distinct (podCIDR) pour chaque nœud du cluster CIDR (c'est-à-dire la plage d'adresses IP pour le réseau du cluster). Étant donné que ces podCIDR ne se chevauchent pas, il devient possible pour chaque pod d'attribuer une adresse IP unique.
Un nœud Kubernetes se voit attribuer un podCIDR lors de son premier enregistrement auprès du cluster. Pour modifier le podCIDR des nœuds, vous devez les désenregistrer, puis les réenregistrer, en apportant entre-temps les modifications appropriées à la configuration de la couche de contrôle Kubernetes. Vous pouvez afficher le podCIDR d'un nœud à l'aide de la commande suivante:
$ kubectl get no <nodeName> -o json | jq '.spec.podCIDR'
10.244.0.0/24
Kubelet, lanceur de conteneurs et plugins CNI: comment tout fonctionne
La planification d'un pod par nœud implique de nombreuses étapes préparatoires. Dans cette section, je me concentrerai uniquement sur ceux qui sont directement liés à la mise en réseau des pods.
La planification d'un pod sur un nœud déclenche la chaîne d'événements suivante:
Aide: Containerd CRI Plugin Architecture .
Interaction entre le lanceur de conteneurs et les plugins CNI
Chaque fournisseur de réseau a son propre plugin CNI. Le moteur d'exécution du conteneur le démarre pour configurer le réseau du pod lors de son démarrage. Dans le cas de containerd, le plugin Containerd CRI est responsable du lancement du plugin CNI .
De plus, chaque fournisseur a son propre agent. Il est installé sur tous les nœuds Kubernetes et est responsable de la mise en réseau des pods. Cet agent est soit livré avec la configuration CNI, soit le crée seul sur le nœud. La configuration aide le plugin CRI à déterminer quel plugin CNI appeler.
L'emplacement de la configuration CNI peut être personnalisé; par défaut, il se trouve dans
/etc/cni/net.d/<config-file>
. Les administrateurs de cluster sont également responsables de l'installation des plug-ins CNI sur chaque nœud de cluster. Leur emplacement est également personnalisable; le répertoire par défaut est /opt/cni/bin
.
Lorsque vous utilisez containerd, les chemins pour la configuration et les fichiers binaires plug - ins peuvent être définis dans une section
[plugins.«io.containerd.grpc.v1.cri».cni]
dans le fichier de configuration de containerd .
Puisque nous utilisons Flannel comme fournisseur de réseau, parlons un peu de sa configuration:
- Flanneld (démon Flannel'a) est généralement installé dans le cluster comme avec DaemonSet
install-cni
comme conteneur d' initialisation . Install-cni
crée un fichier de configuration CNI (/etc/cni/net.d/10-flannel.conflist
) sur chaque nœud.- Flanneld crée un périphérique vxlan, récupère les métadonnées réseau du serveur API et surveille les mises à jour des pods. Au fur et à mesure de leur création, il distribue les itinéraires pour tous les pods du cluster.
- Ces routes permettent aux pods de communiquer entre eux à l'aide d'adresses IP.
Pour plus d'informations sur le fonctionnement de Flannel, je vous recommande d'utiliser les liens à la fin de l'article.
Voici un diagramme de l'interaction entre le plugin Containerd CRI et les plugins CNI:
Comme vous pouvez le voir ci-dessus, kubelet appelle le plugin Containerd CRI pour créer un pod, qui appelle déjà le plugin CNI pour configurer le réseau de pod. Ce faisant, le plugin CNI du fournisseur de réseau invoque d'autres plugins CNI de base pour configurer divers aspects du réseau.
Interaction entre les plugins CNI
Il existe divers plugins CNI conçus pour aider à configurer la mise en réseau entre les conteneurs sur un hôte. Cet article se concentrera sur trois d'entre eux.
Plugin CNI Flannel
Lorsque vous utilisez Flannel comme fournisseur de réseau, le composant Containerd CRI appelle le plug-in Flannel CNI à l'aide du fichier de configuration CNI
/etc/cni/net.d/10-flannel.conflist
.
$ cat /etc/cni/net.d/10-flannel.conflist
{
"name": "cni0",
"plugins": [
{
"type": "flannel",
"delegate": {
"ipMasq": false,
"hairpinMode": true,
"isDefaultGateway": true
}
}
]
}
Le plugin Flannel CNI fonctionne en conjonction avec Flanneld. Au démarrage, Flanneld extrait le podCIDR et d'autres détails liés au réseau du serveur API et les enregistre dans un fichier
/run/flannel/subnet.env
.
FLANNEL_NETWORK=10.244.0.0/16
FLANNEL_SUBNET=10.244.0.1/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=false
Le plugin Flannel CNI utilise les données de
/run/flannel/subnet.env
pour configurer et appeler le plugin bridge CNI.
Pont du plugin CNI
Ce plugin est appelé avec la configuration suivante:
{
"name": "cni0",
"type": "bridge",
"mtu": 1450,
"ipMasq": false,
"isGateway": true,
"ipam": {
"type": "host-local",
"subnet": "10.244.0.0/24"
}
}
Au premier appel, il crée un pont Linux avec
«name»: «cni0»
, ce qui est indiqué dans la configuration. Ensuite, une paire de veth est créée pour chaque pod. Une extrémité se connecte à l'espace de noms réseau du conteneur, l'autre va dans le pont Linux sur le réseau de l'hôte. Le plugin CNI Bridge connecte tous les conteneurs hôtes à un pont Linux sur le réseau hôte.
Une fois la configuration de la paire veth terminée, le plug-in Bridge invoque le plug-in IPAM CNI local hôte. Le type de plugin IPAM peut être configuré dans la configuration CNI, que le plugin CRI utilise pour appeler le plugin Flannel CNI.
Plugins CNI IPAM locaux
Bridge CNI appelle le plug-in IPAM CNI local hôte avec la configuration suivante:
{
"name": "cni0",
"ipam": {
"type": "host-local",
"subnet": "10.244.0.0/24",
"dataDir": "/var/lib/cni/networks"
}
}
IPAM-bouchon hôte local ( IP A DRESSE M estion - Gestion adresse IP) renvoie l'adresse IP du sous - réseau du conteneur et stocke l'IP sélectionnée dans l'hôte dans un répertoire spécifié dans la section
dataDir
- /var/lib/cni/networks/<network-name=cni0>/<ip>
. Ce fichier contient l'ID du conteneur auquel cette adresse IP est attribuée.
Lorsque le plug-in IPAM local de l'hôte est appelé, il renvoie les données suivantes:
{
"ip4": {
"ip": "10.244.4.2",
"gateway": "10.244.4.3"
},
"dns": {}
}
Résumé
Kube-controller-manager attribue podCIDR à chaque nœud. Les pods de chaque nœud obtiennent des adresses IP à partir de l'espace d'adressage dans la plage podCIDR allouée. Étant donné que les podCIDR des nœuds ne se chevauchent pas, tous les pods reçoivent des adresses IP uniques.
L'administrateur du cluster Kubernetes configure et installe kubelet, le lanceur de conteneur, l'agent du fournisseur de réseau et copie les plug-ins CNI sur chaque nœud. Au démarrage, l'agent du fournisseur de réseau génère la configuration CNI. Lorsqu'un pod est planifié pour un nœud, kubelet appelle le plugin CRI pour le créer. De plus, si containerd est utilisé, le plugin Containerd CRI appelle le plugin CNI spécifié dans la configuration CNI pour configurer le réseau de pod. Cela donne au pod une adresse IP.
Il m'a fallu un certain temps pour comprendre toutes les subtilités et nuances de toutes ces interactions. J'espère que l'expérience acquise vous aidera à mieux comprendre le fonctionnement de Kubernetes. Si je me trompe, contactez-moi sur Twitter ou à hello@ronaknathani.com . N'hésitez pas à contacter si vous souhaitez discuter d'aspects de cet article ou de toute autre chose. Je serai ravi de vous parler!
Liens
Conteneurs et réseau
Comment fonctionne Flannel
CRI et CNI
PS du traducteur
Lisez aussi sur notre blog: