Un guide visuel des fondamentaux du réseau Kubernetes

Passer de réseaux physiques utilisant des commutateurs, des routeurs et des câbles Ethernet à des réseaux virtuels utilisant des réseaux définis par logiciel (SDN) et des interfaces virtuelles implique une légère courbe d’apprentissage. Bien sûr, les principes restent les mêmes, mais il existe différentes spécifications et bonnes pratiques. Kubernetes a son propre ensemble de règles, et si vous avez affaire à des conteneurs et au cloud, il est utile de comprendre le fonctionnement de la mise en réseau Kubernetes.
Le modèle de réseau Kubernetes a quelques règles générales à garder à l’esprit :
- Chaque pod obtient sa propre adresse IP : il ne devrait pas être nécessaire de créer des liens entre les pods et de mapper les ports de conteneur aux ports hôtes.
- Le NAT n’est pas requis : les pods d’un nœud doivent pouvoir communiquer avec tous les pods de tous les nœuds sans NAT.
- Les agents obtiennent des laissez-passer pour tous les accès : les agents sur un nœud (démons système, Kubelet) peuvent communiquer avec tous les pods de ce nœud.
- Espaces de noms partagés : les conteneurs d’un pod partagent un espace de noms réseau (adresse IP et MAC), afin qu’ils puissent communiquer entre eux à l’aide de l’adresse de bouclage.
Contents
Ce que la mise en réseau Kubernetes résout
La mise en réseau Kubernetes est conçue pour garantir que les différents types d’entités au sein de Kubernetes peuvent communiquer. La disposition d’une infrastructure Kubernetes a, de par sa conception, beaucoup de séparation. Les espaces de noms, les conteneurs et les pods sont destinés à garder les composants distincts les uns des autres. Un plan de communication hautement structuré est donc important.
(Nived Velayudhan, CC BY-SA 4.0)
Mise en réseau de conteneur à conteneur
La mise en réseau de conteneur à conteneur s’effectue via l’espace de noms de réseau Pod. Les espaces de noms réseau vous permettent de disposer d’interfaces réseau et de tables de routage distinctes, isolées du reste du système et fonctionnant de manière indépendante. Chaque pod a son propre espace de noms réseau et les conteneurs à l’intérieur de ce pod partagent la même adresse IP et les mêmes ports. Toutes les communications entre ces conteneurs se font via localhost, car ils font tous partie du même espace de noms. (Représenté par la ligne verte dans le diagramme.)
Mise en réseau de pod à pod
Avec Kubernetes, chaque nœud dispose d’une plage d’adresses IP CIDR désignée pour les pods. Cela garantit que chaque pod reçoit une adresse IP unique que les autres pods du cluster peuvent voir. Lorsqu’un nouveau Pod est créé, les adresses IP ne se chevauchent jamais. Contrairement à la mise en réseau de conteneur à conteneur, la communication de pod à pod se fait à l’aide d’adresses IP réelles, que vous déployiez le pod sur le même nœud ou sur un nœud différent du cluster.
Le diagramme montre que pour que les pods communiquent entre eux, le trafic doit circuler entre l’espace de noms réseau des pods et l’espace de noms réseau racine. Ceci est réalisé en connectant à la fois l’espace de noms Pod et l’espace de noms racine par un périphérique Ethernet virtuel ou une paire veth (veth0 à l’espace de noms Pod 1 et veth1 à l’espace de noms Pod 2 dans le diagramme). Un pont de réseau virtuel connecte ces interfaces virtuelles, permettant au trafic de circuler entre elles à l’aide du protocole de résolution d’adresse (ARP).
Lorsque les données sont envoyées du pod 1 au pod 2, le flux d’événements est le suivant :
- Le trafic du pod 1 transite par eth0 vers l’interface virtuelle veth0 de l’espace de noms du réseau racine.
- Le trafic passe ensuite par veth0 vers le pont virtuel, qui est connecté à veth1.
- Le trafic passe par le pont virtuel vers veth1.
- Enfin, le trafic atteint l’interface eth0 du Pod 2 via veth1.
Mise en réseau Pod-to-Service
Les pods sont très dynamiques. Ils peuvent devoir augmenter ou réduire en fonction de la demande. Ils peuvent être créés à nouveau en cas de plantage de l’application ou de défaillance d’un nœud. Ces événements entraînent le changement de l’adresse IP d’un pod, ce qui compliquerait la mise en réseau.
(Nived Velayudhan, CC BY-SA 4.0)
Kubernetes résout ce problème en utilisant la fonction Service, qui effectue les opérations suivantes :
- Attribue une adresse IP virtuelle statique dans le frontend pour connecter tous les pods backend associés au service.
- Équilibre la charge de tout trafic adressé à cette adresse IP virtuelle vers l’ensemble de pods backend.
- Garde une trace de l’adresse IP d’un pod, de sorte que même si l’adresse IP du pod change, les clients n’ont aucun problème à se connecter au pod car ils ne se connectent directement qu’avec l’adresse IP virtuelle statique du service lui-même.
L’équilibrage de charge dans le cluster se produit de deux manières :
- IPTABLES : dans ce mode, kube-proxy surveille les modifications apportées au serveur d’API. Pour chaque nouveau service, il installe des règles iptables, qui capturent le trafic vers l’adresse IP et le port du cluster du service, puis redirigent le trafic vers le pod backend pour le service. Le Pod est sélectionné au hasard. Ce mode est fiable et a une charge système moindre car Linux Netfilter gère le trafic sans avoir besoin de basculer entre l’espace utilisateur et l’espace noyau.
- IPVS : IPVS est construit au-dessus de Netfilter et implémente l’équilibrage de charge de la couche de transport. IPVS utilise la fonction de crochet Netfilter, en utilisant la table de hachage comme structure de données sous-jacente, et fonctionne dans l’espace du noyau. Cela signifie que kube-proxy en mode IPVS redirige le trafic avec une latence plus faible, un débit plus élevé et de meilleures performances que kube-proxy en mode iptables.
Le diagramme ci-dessus montre le flux de package du pod 1 au pod 3 via un service vers un nœud différent (marqué en rouge). Le paquet voyageant vers le pont virtuel devrait utiliser la route par défaut (eth0) car ARP s’exécutant sur le pont ne comprendrait pas le service. Plus tard, les packages doivent être filtrés par iptables, qui utilise les règles définies dans le nœud par kube-proxy. Par conséquent, le diagramme montre le chemin tel qu’il est.
Mise en réseau Internet vers service
Jusqu’à présent, j’ai expliqué comment le trafic est acheminé au sein d’un cluster. Il y a cependant un autre aspect de la mise en réseau Kubernetes, et c’est l’exposition d’une application au réseau externe.
(Nived Velayudhan, CC BY-SA 4.0)
Vous pouvez exposer une application à un réseau externe de deux manières différentes.
- Sortie : utilisez cette option lorsque vous souhaitez acheminer le trafic de votre service Kubernetes vers Internet. Dans ce cas, iptables exécute le NAT source, de sorte que le trafic semble provenir du nœud et non du pod.
- Ingress : il s’agit du trafic entrant du monde extérieur vers les services. L’entrée autorise et bloque également des communications particulières avec les services à l’aide de règles de connexion. En règle générale, il existe deux solutions d’entrée qui fonctionnent sur différentes régions de pile réseau : l’équilibreur de charge de service et le contrôleur d’entrée.
Découvrir les services
Kubernetes découvre un service de deux manières :
- Variables d’environnement : le service kubelet s’exécutant sur le nœud où votre pod s’exécute est responsable de la configuration des variables d’environnement pour chaque service actif au format {SVCNAME}_SERVICE_HOST et {SVCNAME}_SERVICE_PORT. Vous devez créer le service avant que les pods clients n’existent. Sinon, ces pods clients n’auront pas leurs variables d’environnement renseignées.
- DNS : le service DNS est implémenté en tant que service Kubernetes qui correspond à un ou plusieurs pods de serveur DNS, qui sont planifiés comme n’importe quel autre pod. Les pods du cluster sont configurés pour utiliser le service DNS, avec une liste de recherche DNS qui inclut le propre espace de noms du pod et le domaine par défaut du cluster. Un serveur DNS compatible avec les clusters, tel que CoreDNS, surveille l’API Kubernetes pour les nouveaux services et crée un ensemble d’enregistrements DNS pour chacun. Si le DNS est activé dans votre cluster, tous les pods peuvent résoudre automatiquement les services par leur nom DNS. Le serveur DNS Kubernetes est le seul moyen d’accéder aux services ExternalName.
ServiceTypes pour la publication de services :
Les services Kubernetes vous permettent d’accéder à un groupe de pods, généralement défini à l’aide d’un sélecteur d’étiquettes. Il peut s’agir d’applications essayant d’accéder à d’autres applications au sein du cluster, ou cela peut vous permettre d’exposer une application s’exécutant dans le cluster au monde extérieur. Les types de service Kubernetes vous permettent de spécifier le type de service que vous souhaitez.
(Ahmet Alp Balkan, CC BY-SA 4.0)
Les différents ServiceTypes sont :
- ClusterIP : il s’agit du ServiceType par défaut. Il rend le service uniquement accessible depuis le cluster et permet aux applications du cluster de communiquer entre elles. Il n’y a pas d’accès extérieur.
- LoadBalancer : ce ServiceType expose les services en externe à l’aide de l’équilibreur de charge du fournisseur de cloud. Le trafic provenant de l’équilibreur de charge externe est dirigé vers les pods backend. Le fournisseur de cloud décide de la manière dont la charge est équilibrée.
- NodePort : Cela permet au trafic externe d’accéder au Service en ouvrant un port spécifique sur tous les nœuds. Tout trafic envoyé à ce port est ensuite transmis au service.
- ExternalName : ce type de service mappe un service à un nom DNS en utilisant le contenu du champ externalName en renvoyant un enregistrement CNAME avec sa valeur. Aucun proxy d’aucune sorte n’est mis en place.
Logiciel de mise en réseau
La mise en réseau au sein de Kubernetes n’est pas si différente de la mise en réseau dans le monde physique, tant que vous comprenez les technologies utilisées. Étudiez, rappelez-vous les bases de la mise en réseau et vous n’aurez aucun problème à activer la communication entre les conteneurs, les pods et les services.