Affinage de la routage pour MetalLB en mode L2

Affinage de la routage pour MetalLB en mode L2
Récemment, j'ai été confronté à une tùche plutÎt atypique de configuration de routage pour MetalLB. Tout irait bien, car généralement MetalLB ne nécessite pas d'actions supplémentaires, mais dans notre cas, nous avons un cluster assez grand avec une configuration réseau plutÎt simple.

Dans cet article, je vais expliquer comment configurer le routage basé sur l'origine et le routage basé sur des politiques pour le réseau externe de votre cluster.

Je ne vais pas m'attarder sur l'installation et la configuration de MetalLB, car je suppose que vous avez déjà une certaine expérience. Passons directement à l'essentiel, à savoir la configuration du routage. Nous avons donc quatre scénarios :

Scénario 1 : Quand la configuration n'est pas nécessaire

Examinons un cas simple.

Affinage de la routage pour MetalLB en mode L2

Aucune configuration de routage supplĂ©mentaire n'est nĂ©cessaire lorsque les adresses attribuĂ©es par MetalLB se trouvent dans la mĂȘme sous-rĂ©seau que les adresses de vos nƓuds.

Par exemple, vous avez une sous-rĂ©seau 192.168.1.0/24, il y a un routeur 192.168.1.1, et vos nƓuds reçoivent les adresses : 192.168.1.10-30, alors pour MetalLB, vous pouvez configurer la plage 192.168.1.100-120 et ĂȘtre assurĂ© qu'elles fonctionneront sans aucune configuration supplĂ©mentaire.

Pourquoi cela ? Parce que vos nƓuds ont dĂ©jĂ  des routes configurĂ©es :

# ip route
default via 192.168.1.1 dev eth0 onlink 
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.10

Et les adresses de la mĂȘme plage rĂ©utiliseront celles-ci sans aucun effort supplĂ©mentaire.

Scénario 2 : Quand une configuration supplémentaire est nécessaire

Affinage de la routage pour MetalLB en mode L2

Vous devez configurer des routes supplĂ©mentaires chaque fois que vos nƓuds n'ont pas de adresses IP ou de route vers la sous-rĂ©seau pour laquelle MetalLB attribue des adresses.

Laissez-moi expliquer cela un peu plus en dĂ©tail. Chaque fois que MetalLB attribue une adresse, cela peut ĂȘtre comparĂ© Ă  une simple affectation du type :

ip addr add 10.9.8.7/32 dev lo

Notez que :

  • a) L'adresse est attribuĂ©e avec un prĂ©fixe /32 c'est-Ă -dire que la route vers la sous-rĂ©seau ne sera pas ajoutĂ©e automatiquement (c'est juste une adresse)
  • b) L'adresse est attachĂ©e Ă  n'importe quelle interface du nƓud (par exemple, la boucle de retour). Il convient de mentionner ici une caractĂ©ristique de la pile rĂ©seau Linux. Peu importe sur quelle interface vous ajoutez l'adresse, le noyau traitera toujours les requĂȘtes ARP et enverra des rĂ©ponses ARP sur n'importe laquelle d'elles, ce comportement est considĂ©rĂ© comme correct et, de plus, est assez largement utilisĂ© dans un environnement dynamique comme Kubernetes.

Ce comportement peut ĂȘtre configurĂ©, par exemple, en activant l'arp strict :

echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce

Dans ce cas, les réponses ARP seront envoyées uniquement si l'interface contient explicitement une adresse IP spécifique. Ce paramÚtre est obligatoire si vous prévoyez d'utiliser MetalLB et que votre kube-proxy fonctionne en mode IPVS.

Cependant, MetalLB ne traite pas les requĂȘtes ARP via le noyau, mais le fait lui-mĂȘme dans l'espace utilisateur, donc cette option n'affectera pas le fonctionnement de MetalLB.

Revenons Ă  notre tĂąche. Si la route pour les adresses attribuĂ©es sur vos nƓuds n'existe pas, ajoutez-la Ă  l'avance sur tous les nƓuds :

ip route add 10.9.8.0/24 dev eth1

Cas 3 : Quand un routage basé sur la source sera nécessaire

Vous devrez configurer le routage basĂ© sur la source lorsque vous recevez des paquets via une passerelle distincte de celle par dĂ©faut, par consĂ©quent, les paquets de rĂ©ponse doivent Ă©galement passer par cette mĂȘme passerelle.

Par exemple, vous avez toujours le mĂȘme sous-rĂ©seau 192.168.1.0/24 rĂ©servĂ© pour vos nƓuds, mais vous souhaitez attribuer des adresses externes Ă  l'aide de MetalLB. Supposons que vous disposiez de plusieurs adresses issues du sous-rĂ©seau 1.2.3.0/24 situĂ©es dans le VLAN 100, et que vous souhaitez les utiliser pour accĂ©der aux services Kubernetes de l'extĂ©rieur.

Affinage de la routage pour MetalLB en mode L2

Lors de l'accĂšs Ă  1.2.3.4 vous effectuerez des requĂȘtes depuis un autre sous-rĂ©seau que 1.2.3.0/24 et attendrez une rĂ©ponse. Le nƓud qui est actuellement le maĂźtre pour l'adresse attribuĂ©e par MetalLB 1.2.3.4, recevra le paquet du routeur 1.2.3.1, mais la rĂ©ponse doit obligatoirement retourner par le mĂȘme chemin, via 1.2.3.1.

Puisque notre nƓud a dĂ©jĂ  une passerelle par dĂ©faut configurĂ©e 192.168.1.1, par dĂ©faut, la rĂ©ponse ira vers celle-ci, et non vers 1.2.3.1, Ă  travers laquelle nous avons reçu le paquet.

Comment gérer cette situation ?

Dans ce cas, vous devez prĂ©parer tous vos nƓuds afin qu'ils soient prĂȘts Ă  servir des adresses externes sans configuration supplĂ©mentaire. Autrement dit, pour l'exemple ci-dessus, vous devez au prĂ©alable crĂ©er une interface VLAN sur le nƓud :

ip link add link eth0 name eth0.100 type vlan id 100
ip link set eth0.100 up

Ensuite, ajoutez les routes :

ip route add 1.2.3.0/24 dev eth0.100 table 100
ip route add default via 1.2.3.1 table 100

Notez que nous ajoutons les routes dans une table de routage distincte 100 elle contiendra uniquement deux routes nécessaires pour envoyer le paquet de réponse via la passerelle 1.2.3.1, qui se trouve derriÚre l'interface eth0.100.

Maintenant, nous devons ajouter une simple rĂšgle :

ip rule add from 1.2.3.0/24 lookup 100

qui indique explicitement : si l'adresse source du paquet se trouve dans 1.2.3.0/24, alors utilisez la table de routage 100. Nous avons déjà décrit le chemin qui l'enverra à travers 1.2.3.1

Cas 4 : Quand un routage basé sur les politiques est nécessaire

La topologie du réseau est comme dans l'exemple précédent, mais supposons que vous souhaitiez également avoir la possibilité d'accéder à des adresses externes du pool 1.2.3.0/24 depuis vos pods :

Affinage de la routage pour MetalLB en mode L2

La particularitĂ© rĂ©side dans le fait que lorsqu'on accĂšde Ă  n'importe quelle adresse dans 1.2.3.0/24, le paquet de rĂ©ponse arrivant sur le nƓud et ayant une adresse source dans la plage 1.2.3.0/24 sera obĂ©issant et envoyĂ© Ă  eth0.100, mais ce que nous voulons, c'est que Kubernetes le redirige vers notre premier pod, qui a gĂ©nĂ©rĂ© la requĂȘte initiale.

Résoudre ce problÚme s'est avéré difficile, mais cela a été possible grùce au routage basé sur les politiques :

Pour mieux comprendre le processus, je vais donner un schéma bloqué de netfilter :
Affinage de la routage pour MetalLB en mode L2

Pour commencer, comme dans l'exemple précédent, créons une table de routage supplémentaire :

ip route add 1.2.3.0/24 dev eth0.100 table 100
ip route add default via 1.2.3.1 table 100

Ajoutons maintenant quelques rĂšgles dans iptables :

iptables -t mangle -A PREROUTING -i eth0.100 -j CONNMARK --set-mark 0x100
iptables -t mangle -A PREROUTING -j CONNMARK --restore-mark
iptables -t mangle -A PREROUTING -m mark ! --mark 0 -j RETURN
iptables -t mangle -A POSTROUTING -j CONNMARK --save-mark

Ces rĂšgles vont marquer les connexions entrantes sur l'interface eth0.100, en Ă©tiquetant tous les paquets avec le tag 0x100, ce mĂȘme tag sera Ă©galement utilisĂ© pour les rĂ©ponses dans le cadre d'une mĂȘme connexion.

Nous pouvons maintenant ajouter une rĂšgle de routage :

ip rule add from 1.2.3.0/24 fwmark 0x100 lookup 100

C'est-Ă -dire que tous les paquets avec une adresse source 1.2.3.0/24 et un tag 0x100 devraient ĂȘtre routĂ©s en utilisant la table 100.

Ainsi, d'autres paquets reçus sur une autre interface ne seront pas soumis Ă  cette rĂšgle, ce qui leur permettra d'ĂȘtre routĂ©s par les moyens standard de Kubernetes.

Il y a cependant un autre mais : Linux dispose d'un filtre de chemin inverse qui gĂąte tout et effectue une simple vĂ©rification : pour tous les paquets entrants, il modifie l'adresse source du paquet avec l'adresse de l'expĂ©diteur et vĂ©rifie si le paquet peut sortir par la mĂȘme interface par laquelle il a Ă©tĂ© reçu. Sinon, il le filtre.

Le problÚme est que dans notre cas, cela ne fonctionnera pas correctement, mais nous pouvons le désactiver :

echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter
echo 0 > /proc/sys/net/ipv4/conf/eth0.100/rp_filter

Notez que la premiÚre commande contrÎle le comportement global de rp_filter ; si elle n'est pas désactivée, la deuxiÚme commande n'aura aucun effet. Cependant, les autres interfaces resteront avec rp_filter activé.

Pour ne pas restreindre complÚtement le fonctionnement du filtre, nous pouvons utiliser l'implémentation de rp_filter pour netfilter. En utilisant rpfilter en tant que module iptables, il est possible de configurer des rÚgles assez flexibles, par exemple :

iptables -t raw -A PREROUTING -i eth0.100 -d 1.2.3.0/24 -j RETURN
iptables -t raw -A PREROUTING -i eth0.100 -m rpfilter --invert -j DROP

activer rp_filter sur l'interface eth0.100 pour toutes les adresses sauf 1.2.3.0/24.

Source : habr.com

Acheter un hĂ©bergement fiable pour les sites avec protection DDoS, serveurs VPS VDS đŸ”„ Acheter un hĂ©bergement fiable pour les sites avec protection DDoS, serveurs VPS VDS | ProHoster