jeudi 27 octobre 2011

Failover IP sur une VM en proxy-arp

Le proxy-arp est une technique intéressante qui permet de se passer d'un bridge lorsqu'on héberge des machines virtuelles. Elle empêche également l'admin de la VM de voler des addresses dans le subnet local comme c'est le cas avec un bridge. Cepandant, attention à cette intéraction néfaste avec le failover IP...

Avec une VM bridgée classique, l'hôte établit un pont entre l'interface réseau physique et les interfaces réseau virtuelles. Les requêtes ARP sur le subnet local sont transmises à toutes les VM, et chaque VM décide ou non d'y répondre, sans contrôle de l'hôte (bien sur on peut utiliser ebtables pour filtrer)

Au lieu d'utiliser des interfaces virtuelles de type ethernet, on peut également utiliser des liens point-à-point virtuels. Côté VM, l'interface a donc une addresse unique /32, et une addresse p2p fixe (typiquement 10.64.64.64) qui sert de passerelle par défaut. Côté hôte, pas de problème pour avoir une addresse unique sur plusieurs interfaces, parce que les interfaces sont point-à-point, il n'y a donc pas d'ambiguité sur la source. Mais dans cette configuration, comment le routeur du subnet local sait-il qu'il doit addresser les paquets a destination des VM sur l'addresse de l'hôte ?

En activant le proxy-arp sur l'interface physique de l'hôte, l'hôte répondra en arp pour toutes les addresses qu'il est capable de router. Il suffit donc d'ajouter une route statique vers le bon tunnel point-a-point pour chaque VM. C'est ce que fait, d'ailleurs, le script fourni avec openvz pour la gestion des addresses des VMs.

Mais que se passe-il si, par mégarde, une VM vient a déconfigurer une addresse qui lui a été allouée, sans en avertir l'hôte ?

La route statique étant en place, l'hôte va continuer a router les paquets à destination de cette addresse vers le tunnel. Et si le guest a le forwarding activé, il va joyeusement transmettre les même paquets à sa passerelle par défaut, dans le même tunnel, dans l'autre sens.

Chez moi, ça se traduit par un load average de 12, ksoftirqd qui prend 60% du cpu, et 5 secondes de latence entre chaque caractère tapé en ssh.

En bridge, ça marche mieux...

Aucun commentaire: