Au fil des évolutions d’une entreprise et de ses besoins grandissants, il arrive un moment où il n’est plus acceptable de laisser certains services être gérés par un seul serveur.
Que ce soit pour le service DNS, LDAP ou encore ceux de partage de fichiers, il devient un jour ou l’autre nécessaire de fournir des solutions d’infrastructure permettant de garantir haute disponibilité et performance.
Dans le cadre du DNS ou du LDAP, c’est simple, les services sont ainsi faits pour permettre la réplication de leur base. Pour les partages de fichiers, c’est différent…
En effet, quiconque a déjà mis en œuvre une réplication de partage de fichiers entre sites sait qu’il est impossible d’envisager de travailler sur les fichiers de chaque côté de la réplique, les accès concurrents ne seraient pas gérés et la fusion d’un document modifié des deux côtés impossible à faire automatiquement.
La question se pose donc : comment sur un seul site être capable de mettre à disposition depuis plusieurs serveurs un seul point de partage ? Et comment permettre la bascule automatique d’un serveur à l’autre en cas de panne ?
La réponse est simple : Xsan, et un répartiteur de charge.
Xsan est un sujet déjà traité sur ce blog, la mise en œuvre n’ayant que très peu changé avec OS X Server 3, je ne reviendrais pas dessus. Rappelez-vous simplement que c’est la technologie qui permet à un espace de stockage d’être disponible en accès direct à plusieurs serveurs en même temps. L’espace de stockage ainsi mis à disposition est accessible en SCSI à l’ensemble des serveurs relié à la fabrique SAN (nom donné à l’ensemble formé des serveurs, des baies RAID et des switchs Fibre Channel).
Le répartiteur de charge (Load Balancer) est quelque chose de peu utilisé dans les PME, à fortiori lorsqu’il est question de partage de fichiers. Il est plus courant de le retrouver utilisé sur des serveurs HTTP ou e-mail. Le principe de ce service est de recevoir une communication sur une adresse IP virtuelle et de la rediriger vers un serveur réel qui traitera la demande. La redirection est faite vers un serveur appartenant à un groupe de serveurs capable de traiter la demande, en fonction de paramètres de charge ou d’équidistribution.
Fonctionnement d’un répartiteur de charge
Avant d’aller plus loin, il est nécessaire de connaitre le fonctionnement des répartiteurs de charge pour comprendre l’impact sur les communications.
Si l’on regarde l’information qui transite sur un câble réseau, nous avons (de manière simplifiée) comme élément de base une frame Ethernet. Cette entité est constituée d’une adresse MAC source et d’une adresse MAC de destination en plus de quelques attributs et d’une charge utile. Ce sont ces adresses MAC qui permettent sur un LAN de savoir à quelle carte physique est destinée la communication.
La charge utile d’une frame Ethernet, c’est le paquet IP qu’elle transporte. Ce paquet IP contient l’adresse IP source, l’adresse IP de destination, quelques attributs qui ne nous intéressent pas ainsi que la charge utile.
Pour fonctionner, un répartiteur de charge à deux options : réécrire uniquement l’adresse MAC de destination ; ou réécrire en plus les adresses IP de source et de destination. Regardons cela plus en détail.
Fonctionnement basé sur du NAT
La solution la plus évidente pour un répartiteur de charge, c’est d’utiliser du NAT. Le répartiteur va remplacer les adresses IP source et destination en se plaçant comme émetteur de la communication et en plaçant le serveur cible comme récepteur.
Le serveur cible recevant la communication ne verra que l’IP du répartiteur, il ne verra jamais l’IP du client d’origine. Lorsque la réponse sera envoyée au répartiteur, celui-ci regardera dans sa table de correspondance d’adresse NAT qui était le client d’origine et retransmettra la réponse en prenant soin de reformer le paquet IP avec l’adresse IP source comme étant l’adresse IP virtuelle du service (et non celle du serveur réel) et l’IP de destination comme étant celle du client.
On comprend aisément que le répartiteur tel que configuré ici peut devenir un goulot d’étranglement : l’ensemble des communications passe par lui et un traitement lourd doit être fait (mise en base des demandes et recherche en base des réponses).
Pour autant, ce système à un avantage, une certaine intelligence peut-être mise au niveau du répartiteur. Il peut permettre de tenir un journal centralisé, imposer une conformité des communications, etc. Remplir le rôle de pare-feu applicatif en somme.
De plus, cette configuration fonctionne que le répartiteur et le serveur soient ou non dans le même sous-réseau.
Dans un objectif de répartition de charge sur un service tel que l’AFP ou le SMB, on peut sans risque dire qu’il semble assez peu probable de trouver un répartiteur de charge ayant des capacités d’inspection spécifiques. Tout ce que peuvent faire ces outils sur ces protocoles de partages de fichiers, c’est regarder le nombre de sessions ouvertes. De fait, le fonctionnement en mode NAT est assez peu intéressant ici, nous subirons l’ensemble des inconvénients sans avoir de réels avantages.
Fonctionnement dit de « Direct Server Return »
L’autre option est celle qui nous intéressera dans le cadre du partage de fichiers, elle permet de s’affranchir du NAT et offre au serveur la possibilité de répondre directement au client sans avoir à passer par le répartiteur en chemin retour.
À l’aller, le répartiteur n’aura qu’à remplacer l’adresse MAC de destination sans chercher à archiver la communication.
Ce système n’est possible que si le répartiteur et les serveurs réels sont sur le même sous-réseau. De plus, cela demande une configuration spécifique sur les serveurs réels pour qu’ils soient capables de reconnaitre l’adresse IP virtuelle sans pour autant s’annoncer sur le réseau comme disposant de cette adresse (seul le répartiteur le fera).
Retournons au niveau du réseau pour mieux comprendre la chose.
Lorsqu’une machine (client, serveur, routeur…) cherche à communiquer avec une adresse IP faisant partie de son sous-réseau, une requête ARP est émise demandant l’adresse MAC associée à l’adresse IP en question. Une fois l’adresse MAC identifiée le paquet IP est encapsulé dans une frame Ethernet ayant comme destinataire l’adresse MAC nouvellement découverte.
L’idée derrière le « DSR » est de permettre aux serveurs de répondre directement au client, sans passer par le répartiteur. Pour cela, le répartiteur et les serveurs disposeront tous d’une interface réseau avec l’adresse IP virtuelle du groupe. Cependant, seul le répartiteur répondra aux requêtes ARP correspondantes à cette adresse, les serveurs ne devront pas y répondre. Si d’aventure ils le faisaient, l’équilibrage de charge et la tolérance de panne ne fonctionneraient plus : il n’y aurait aucun moyen de contrôler qui sera le destinataire des communications.
Pour que les serveurs disposent de cette adresse VIP (et répondent dessus) sans pour autant répondre aux requêtes ARP, une configuration spécifique est nécessaire. Nous verrons dans la suite de l’article comment effectuer cette configuration sur OS X (et donc sur la plupart des systèmes UNIX).
Du côté du serveur, la réponse est envoyée à l’adresse source mentionnée dans le paquet IP depuis l’interface de réception de la communication. C’est à dire depuis l’adresse VIP vers le client d’origine, directement, sans passer par le répartiteur.
Cette configuration à l’avantage d’un travail simplifié sur le répartiteur, il n’y a qu’à réécrire l’adresse MAC de destination en fonction des règles d’équilibrage, sans avoir à maintenir de table de traduction d’adresse comme pour le NAT. De plus, les serveurs répondent au client naturellement, sans besoin de passer par le répartiteur.
Du point de vue du réseau, le fonctionnement est également plus neutre, la communication se fait de bout en bout sans réécriture de la partie IP.
Cependant, les fonctions avancées au niveau du répartiteur ne sont pas possibles, l’absence de capacité d’inspection des réponses des serveurs bloquant une analyse complète de la communication.
De plus, il est impératif dans cette configuration que le répartiteur ainsi que les serveurs soient sur le même sous-réseau.
Ce genre de configuration est assez peu utile pour des serveurs web ou e-mail qui n’ont pas de gros débit. Pour autant, lorsqu’il est question de flux temps réel (audio, vidéo…), cela devient nécessaire.
Un autre cas où cela est utile, dans le cadre du partage de fichier, cela permet d’éviter le goulot d’étranglement du répartiteur qui ne devra gérer que les communications allant du client vers le serveur.
Configuration d’une interface virtuelle sous OS X
La configuration d’une interface virtuelle sur OS X se fait très simplement, comme sur tout UNIX, via une interface de « loopback ». Ces interfaces préfixées « lo » sur OS X ne servent pas qu’à recevoir l’adresse 127.0.0.1. Elles peuvent également être utilisées pour configurer d’autres adresses IP comme les adresses IP virtuelles. Pour que cela puisse fonctionner, il faut également que les serveurs soient configurés pour agir comme passerelle, de sorte qu’une communication reçue par une interface et pouvant être routée par une autre puisse effectivement fonctionner.
Lorsqu’un paquet va arriver sur l’interface Ethernet du serveur, avec l’adresse MAC de cette carte, mais l’adresse IP d’une autre interface, ce que va faire le système si ses fonctions de routages sont actives, c’est prendre le paquet reçu et le renvoyer sur l’autre interface.
Dans le cadre de mise en place d’une VIP, l’autre interface est une interface de boucle locale, l’ensemble des communications émises vers cette interface sera en réalité reçue par le serveur lui même (et donc ses services en écoute).
Lors de la communication retour, la connexion TCP ouverte sur la VIP va sortir par l’interface de boucle et donc revenir sur le serveur. L’adresse de destination étant le client, le système fera son travail de routage et enverra donc la communication à qui de droit.
Dans le cas d’une connexion UDP, c’est un peu plus particulier. L’UDP est un protocole de diffusion et non de question/réponse comme le TCP. Pour qu’un service fonctionne avec une VIP en tant qu’adresse source, vous devrez l’attacher spécifiquement à cette adresse et non à l’ensemble des adresses disponibles comme il est souvent fait. C’est un réglage que vous pouvez voir dans les réglages du serveur VPN L2TP d’OS X Server, avec les outils officiels jusqu’à 10.6 et depuis avec mon outil VPN Admin Tool.
Si, par hasard, vous oubliez d’activer les fonctions de routage du serveur, la communication ne fonctionnera tout simplement pas. Le serveur recevant la communication sur son interface externe verra que l’IP cible ne correspond pas à l’IP de son interface et jettera tout simplement le paquet.
Configuration du routage sous OS X
Pour configurer les fonctions de routage sous OS X, il faut que l’option net.inet.ip.forwarding du système soit à 1.
Pour accéder à la configuration actuelle des options du système, il faut utiliser la commande sysctl :
yoanngini@office ~ % sysctl net.inet.ip.forwarding net.inet.ip.forwarding : 0 |
Et pour modifier cette valeur à l’exécution :
yoanngini@office ~ % sudo sysctl -w net.inet.ip.forwarding=0 Password : net.inet.ip.forwarding : 1 > 0 |
L’effet de cette dernière commande est éphémère, au prochain redémarrage du système la valeur par défaut sera de retour. Pour configurer cette clef de manière permanente, il suffit de rajouter une ligne dans le fichier /etc/sysctl.conf (à créer s’il n’existe pas) :
net.inet.ip.forwarding=1 |
Configuration de l’adresse IP virtuelle sous OS X
Pour ajouter une adresse supplémentaire à l’interface lo0 du système, il faut passer par la commande suivante :
yoanngini@office ~ % sudo ifconfig lo0 alias 192.168.42.30 netmask 255.255.255.255 |
Où 192.168.42.30 est l’adresse IP virtuelle. La présence du masque de sous-réseau 255.255.255.255 indique que seule cette adresse est disponible via l’interface.
L’effet de cette ligne de commande est également éphémère. Pour rendre la chose permanente, il n’y a rien de prévu dans le système OS X. Les préférences systèmes ne sont pas capables d’éditer la configuration des interfaces de boucle locale. Certains proposent de modifier directement le fichier /Library/Preferences/SystemConfiguration/NetworkInterfaces.plist, je ne le recommande pas. Ce fichier est trop peu documenté pour envisager une édition sur un système en production.
À l’heure actuelle, la seule solution de contournement que je connaisse est l’usage de script de démarrage launchd.
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>Label</key> <string>com.inig-services.config.loopback.alias.plist</string> <key>ProgramArguments</key> <array> <string>/sbin/ifconfig</string> <string>lo0</string> <string>alias</string> <string>192.168.42.30</string> <string>netmask</string> <string>255.255.255.255</string> </array> <key>RunAtLoad</key> <true/> </dict> </plist> |
Configuration d’un répartiteur de charge pour l’AFP
Du coté du répartiteur de charge, la configuration d’un service comme l’AFP est des plus simple. L’exemple suivant est fait avec le produit LoadMaster de Kemp Technologies ici mis en œuvre depuis une machine virtuelle. Vous pouvez vous même obtenir une version de démo de 30 jours si vous souhaitez tester ce genre de configuration dans votre laboratoire.
La configuration avec un produit d’un autre fabricant serait du même ordre.
La configuration initiale demande l’adresse IP virtuelle, le port d’écoute ainsi que le protocole utilisés par le service. Dans le cas de l’AFP, nous sommes sur le port TCP 548.
Vient ensuite la configuration en détail du service où seront demandées les informations sur le type de répartition (avec ou sans inspection applicative, quel type d’ordonnancement, quelle durée éventuelle pour la persistance de connexion d’un client à un serveur, etc.).
Et en tout dernier, il reste à spécifier les adresses IP des serveurs réels assurant le travail pour le service indiqué.
La configuration du type de communication (« NAT » ou « Direct Return ») avec le produit de Kemp se fait par serveur réel. Rien n’interdit un autre fabriquant de gérer cette configuration de manière globale au service.
Dès maintenant, le serveur est fonctionnel, vous pouvez vous connecter depuis votre client en AFP sur l’adresse IP virtuelle choisie (ici 192.168.42.30) et constater que cela fonctionne.
Configuration de l’AFP pour un répartiteur de charge
Aussi étonnant que cela puisse paraître, AFP dispose de réglages avancés permettant de mieux gérer les situations de répartition de charge. Entre autres, l’identifiant unique du serveur envoyé aux clients durant l’identification peut être partagé entre chaque serveur pour que la reconnexion se fasse de la manière la plus naturelle possible.
Pour cela, il faut en ligne de commande arrêter les serveurs AFP, changer la valeur de clef reconnectKeyLocation pour le service et enfin redémarrer AFP.
root@office ~ % serveradmin stop afp afp:state = "STOPPED" afp:status = 0 afp:timeStamp = "2013-12-31 15:48:19 +0000" root@office ~ % serveradmin settings afp:reconnectKeyLocation = "/Volumes/SAN/Library/Server/AFP.conf" afp:reconnectKeyLocation = "/Volumes/SAN/Library/Server/AFP.conf" root@office ~ % serveradmin start afp afp:state = "RUNNING" afp:status = 0 |
D’autre part, la liste des points de partage est propre à la machine. C’est à vous de synchroniser la chose manuellement entre chaque serveur. Vous pouvez envisager un processus manuel si vous ne créez pas souvent des points de partage, sinon vous devriez réfléchir à la création d’un script personnalisé créant le dossier sur votre volume SAN tout en le rajoutant aux partages de l’ensemble des serveurs AFP via la ligne de commande sharing.
Toujours concernant l’authentification, la mise en place d’un royaume Kerberos fonctionnel serait une bonne chose ici. Cela permettrait d’éviter les situations d’authentification multiple en cas de bascule.
Si l’on regarde une trace de connexion sur un réseau à plan (un seul sous-réseau) depuis le client en n’affichant que les adresses MAC et les noms de domaines des machines en dialogue nous pouvons constater que les communications sortantes du client sont à destination d’une adresse MAC et les communications entrantes sont bien en provenance d’une autre adresse MAC, prouvant effectivement que l’équipement destinataire de la communication n’est pas l’équipement de réponse. Dans le cas d’un réseau routé (VLAN client et VLAN serveur distinct) la chose ne se verrait pas (la seule adresse MAC vue serait celle du routeur).
root@macpro.office.inig-services.com ~ % tcpdump -e -i en0 host 192.168.42.30 | awk '{print $2,$5,$6,$14,$15,$16}' tcpdump : verbose output suppressed, use -v or -vv for full protocol decode listening on en0, link-type EN10MB (Ethernet), capture size 65535 bytes 00:1d:4f:4b:a5:04 > 00:0c:29:7a:d3:4d macpro.office.inig-services.com.60372 > vip-osx.office.inig-services.com.afpovertcp: 40:6c:8f:0c:fd:63 > 00:1d:4f:4b:a5:04 vip-osx.office.inig-services.com.afpovertcp > macpro.office.inig-services.com.60372: 00:1d:4f:4b:a5:04 > 00:0c:29:7a:d3:4d macpro.office.inig-services.com.60372 > vip-osx.office.inig-services.com.afpovertcp: 00:1d:4f:4b:a5:04 > 00:0c:29:7a:d3:4d macpro.office.inig-services.com.60372 > vip-osx.office.inig-services.com.afpovertcp: 40:6c:8f:0c:fd:63 > 00:1d:4f:4b:a5:04 vip-osx.office.inig-services.com.afpovertcp > macpro.office.inig-services.com.60372: 40:6c:8f:0c:fd:63 > 00:1d:4f:4b:a5:04 vip-osx.office.inig-services.com.afpovertcp > macpro.office.inig-services.com.60372: 40:6c:8f:0c:fd:63 > 00:1d:4f:4b:a5:04 vip-osx.office.inig-services.com.afpovertcp > macpro.office.inig-services.com.60372: 40:6c:8f:0c:fd:63 > 00:1d:4f:4b:a5:04 vip-osx.office.inig-services.com.afpovertcp > macpro.office.inig-services.com.60372: 00:1d:4f:4b:a5:04 > 00:0c:29:7a:d3:4d macpro.office.inig-services.com.60372 > vip-osx.office.inig-services.com.afpovertcp: 00:1d:4f:4b:a5:04 > 00:0c:29:7a:d3:4d macpro.office.inig-services.com.60372 > vip-osx.office.inig-services.com.afpovertcp: 00:1d:4f:4b:a5:04 > 00:0c:29:7a:d3:4d macpro.office.inig-services.com.60372 > vip-osx.office.inig-services.com.afpovertcp: |
Ici, 00:1d:4f:4b:a5:04 est l’adresse de mon client, 00:0 c:29:7a:d3:4d l’adresse du répartiteur et 40:6c:8f:0c:fd:63 l’adresse du serveur ayant répondu.
Dernière chose, lors de l’utilisation d’une telle configuration, il peut y avoir une chose déroutante pour les utilisateurs, le fait que sur la gauche du Finder se trouvera le nom réel du serveur ayant été choisi pour traiter la demande. De fait, si d’une connexion à l’autre le serveur change, le nom changera. Ce qui peut éventuellement perdre les utilisateurs. De plus, si le délai d’assignation d’un utilisateur à un serveur est court, vous verrez que certaines fois vous pouvez vous retrouver avec plusieurs serveurs connectés dans le Finder, c’est dû au fait que le client a été basculé suite à une trop grande inactivité (ou une panne). Veillez à configurer les différents compteurs du service AFP et du répartiteur de manière cohérente (que le délai de déconnexion automatique des clients inactifs du service AFP soit plus faible que le bail d’assignation des clients à un serveur sur le répartiteur).