Août 19 2009
Cluster de serveurs de fichiers sur Windows 2003 Server Standard Edition
Ceux qui se sont penchés sur la question savent déjà qu’il n’est pas possible de réaliser un cluster sur Windows 2003 server Standard Edition.
Or, vous possédez un espace de stockage partagé mais ne pouvez pas (ou voulez pas) vous permettre de vous offrir 2 licences Enterprise juste pour un serveur de fichiers.
Il y a bien DFS mais c’est dommage de redonder les données sur un support de stockage déjà sécurisé.
Je propose ici de créer une bascule de quelques secondes semi-automatique à défaut de cluster (qui n’est en fait qu’en mode failover également). Un fichier ouvert avant bascule peut être enregistré après sans que le client ne s’en apercoive.
Pour éviter aux stations clientes de modifier leurs montages, scripts, etc…, nous n’utilisons ni l’adresse IP du serveur ni son nom mais un alias DNS (CNAME) pointant sur le serveur principal par défaut. Pour basculer, il suffit de pointer cet alias vers le secondaire.
Concrètement, le client XP (ou autre) fait une requête DNS pour résoudre \\fichiers, et l’entrée DNS du serveur actif est retournée. Le client se connecte alors au serveur adéquate.
Nom de partage
Les serveurs n’acceptent pas un nom de partage différent de leur nom d’hôte. En accédant au partage \\fichiers, une erreur est retournée.
Pour contourner ce problème, il faut forcer le serveur à accepter un nom différent en créant la clé DWORD DisableStrictNameChecking dans [HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanServer\Parameters], initialisé à la valeur 1 (Décimale).
Plus d’infos à ce sujet sur http://support.microsoft.com/kb/281308
Vous devrez aussi ajouter la valeur DWORD DisableLoopbackCheck dans [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa] pour pouvoir atteindre \\fichiers depuis le serveur vers lequel l’alias pointe. Une erreur d’accès refusé est générée si ce n’est pas le cas. Voir KB926642 pour plus d’informations.
Cache DNS
Chaque machine XP possède un cache DNS qui enregistre les entrées pour une durée de 24 heures. Cela pose problème puisque la bascule sera effective jusqu’à une journée plus tard pour les clients.
Chaque entrée DNS possède un time to live (TTL) par défaut qui représente le délai d’expiration dans le cache DNS. Celle-ci peut être changée si l’on crée l’entrée en ligne de commande:
dnscmd /RecordAdd mondomaine.com fichiers 60 CNAME serveur1.mondomaine.com
C’est le 60 qui est important ici: l’entrée expirera du cache DNS au bout de 60 secondes, durée après laquelle le client fera une nouvelle requête DNS.
De cette façon, le cache global n’est pas affecté, puisqu’il joue son rôle pour les autres requêtes DNS, limitant le trafic sur le réseau, et l’entrée fichier se met à jour très rapidement en cas de failover.
Configuration SAN
Important: Les lecteurs doivent être visibles depuis le serveur live uniquement! S’il existe un LUN vers le serveur de standby, Windows pourrait corrompre le système de fichiers même si le disque n’a pas de lettre de lecteur affecté.
Puisque le volume n’est visible que depuis le serveur live, une étape manuelle est nécessaire pour supprimer les LUN et les recréer vers le serveur en standby. J’ai automatisé ce processus avec un script Perl qui fait un telnet vers le SAN et efface/recrée les LUNs (La plupart des SANs supportent l’accès en telnet).
Copie des informations de partage
Les données de partage sont stockées dans la base de registre Windows sous [HKLM\SYSTEM\CurrentControlSet\Services\lanmanserver\Shares], et non sur le système de fichiers. On perd donc tous les partages existants après le failover.
Pour récupérer les partages après bascule, il faut copier en amont les partages déclarés sur le serveur primaire et les importer sur le secondaire. Seuls les partages des lecteurs qui vont migrer doivent être copiés. Les partages du lecteur C:\ par exemple, ne doivent pas être pris en compte.
Avant migration, il faut toutefois s’assurer que les lettres de lecteurs sont disponibles sur le serveur de destination. Par mesure de sécurité, nous prenons les lettres de lecteur X: et Y: pour éviter qu’elles ne soient prises par un disque amovible. Il est possible de désactiver l’automontage avec la commande mountvol.
Ce script DOS (à mettre sur le serveur primaire) copie les informations de partages du serveur principal vers le secondaire. Fervent Linuxien, je me suis vite rendu compte que DOS était très très limité, allongeant le code pour traiter les partages contenant des espaces.
SETLOCAL ENABLEDELAYEDEXPANSION
rem Variables a editer
rem Ne pas oublier le fichier RemoveDrives.txt
set DOMAIN=mondomaine.com
set DSTSRV=serveur2
set DNSSRV=monserveurdns
rem alias des serveurs de fichiers
set CNAME=fichiers
rem Volumes sur disques partages a migrer
set DRIVES=X,Y
set KEYPATH=HKLM\SYSTEM\CurrentControlSet\Services\lanmanserver\Shares
set SHARESRC=%KEYPATH%
set SHAREDST=\\%DSTSRV%\%KEYPATH%
set SECURITYSRC=%KEYPATH%\Security
set SECURITYDST=\\%DSTSRV%\%KEYPATH%\Security
rem Verifie que les lecteurs sont disponibles sur la cible
for /D %%D in (%DRIVES%) DO (
reg query \\%DSTSRV%\HKLM\SYSTEM\MountedDevices /v \DosDevices\%%D: 2>NUL 1>NUL
if not !ERRORLEVEL!==1 (
echo %%D non disponible sur la cible
echo ARRET DE LA BASCULE
goto end
)
)
rem Suppression des anciens noms de partages sur la destination
for /D %%D in (%DRIVES%) DO (
rem Parcourt des partages
for /F "tokens=1 delims=" %%K in ('reg query %SHAREDST%^|findstr %%D:') do (
rem reg query produit des sorties sur 3 champs: Valeur - Type - Donnee
rem On remplace le type par # car 1 seul caractère ne peut servir de delimiteur
rem Necessaire pour les noms de partages contenant des espaces!
set SHAREKEY=%%K
set SHAREKEY=!SHAREKEY:REG_MULTI_SZ=#!
rem On recupere la valeur (nom du partage) et la donnee (chemin)
for /F "tokens=1,2 delims=#" %%S in ("!SHAREKEY!") do (
rem Supprime les espaces en debut et fin de chaine
rem Et ajoute les guillemets pour les noms contenant des espaces
set SHARE=%%S
set SHARE="!SHARE:~4,-4!"
rem Suppression des partages et de leur securite
reg delete %SHAREDST% /v !SHARE! /f
reg delete %SECURITYDST% /v !SHARE! /f
)
)
)
rem Copie des partages dans la base de registre du serveur secondaire
rem Parcourt les lecteurs
for /D %%D in (%DRIVES%) DO (
rem Parcourt des partages
for /F "tokens=1 delims=" %%K in ('reg query %SHARESRC%^|findstr %%D:') do (
rem reg query produit des sorties sur 3 champs: Valeur - Type - Donnee
rem On remplace le type par # car 1 seul caractère ne peut servir de delimiteur
rem Necessaire pour les noms de partages contenant des espaces!
set SHAREKEY=%%K
set SHAREKEY=!SHAREKEY:REG_MULTI_SZ=#!
rem On recupere la valeur (nom du partage) et la donnee (chemin)
for /F "tokens=1,2 delims=#" %%S in ("!SHAREKEY!") do (
rem Supprime les espaces en debut et fin de chaine
rem Et ajoute les guillemets pour les noms contenant des espaces
set SHARE=%%S
set SHARE="!SHARE:~4,-4!"
set DATA=%%T
set DATA="!DATA:~4!"
rem Restauration des partages et de leur securite
reg add %SHAREDST% /v !SHARE! /t REG_MULTI_SZ /d !DATA! /f
rem Meme methode que ci-dessus
for /F "tokens=1 delims=" %%L in ('reg query %SECURITYSRC% /v !SHARE! ') do (
set SECURITYKEY=%%L
set SECURITYKEY=!SECURITYKEY:REG_BINARY =#!
for /F "tokens=2 delims=#" %%S in ("!SECURITYKEY!") do (
REG ADD %SECURITYDST% /v !SHARE! /t REG_BINARY /d %%S /f
)
)
)
)
)
Deux cas peuvent se présenter lors d’un failover:
– Soit on fait une maintenance et serveur1 est toujours en ligne
– Soit serveur1 a subi un crash et n’est plus disponible
Dans ce second cas, il ne sera plus possible de copier les informations de partage. C’est pourquoi il peut être judicieux d’exécuter cette partie du script tous les jours pour que serveur2 soit à jour autant que possible.
Déconnexion des lecteurs
C’est maintenant que la bascule devient effective. Pensez à vérifier que les lecteurs ont été supprimés. Il ne faut surtout pas que la partition soit montée sur les 2 serveurs en même temps! Peu d’actions sont requises maintenant:
– Stopper les applications accédant au volume
– Supprimer la lettre du lecteur (pas le volume :-))
– Modifier le DNS
– Redémarrer les applications
Il est important de ne mettre que les données du serveur de fichiers, et non applicatives. Dans le cas contraire, il faut inclure l’arrêt de ces applications dans la démarche.
Par défaut, il ne faut arrêter que le service ‘serveur de fichiers’ et ses dépendances qui sont ‘Net Logon’, ‘Computer browser’ et ‘DFS’. Vérifier si d’autres services dépendants n’ont pas été ajoutés par la suite (exemple: Backup exec dans mon cas).
Tout ceci peut se faire par script DOS également:
rem Arret des services pour supprimer la lettre du lecteur
net session /delete /y
net stop "Server" /y
rem Suppression des lettres de lecteur
set diskfile=disk.txt
copy NUL %diskfile%
for /D %%D in (%DRIVES%) DO (
echo select volume %%D: >> %diskfile%
echo remove >> %diskfile%
)
diskpart /s %diskfile%
rem Changement du DNS
dnscmd %DNSSRV% /recorddelete %DOMAIN% %CNAME% CNAME /f
dnscmd %DNSSRV% /RecordAdd %DOMAIN% %CNAME% 60 CNAME %DSTSRV%.%DOMAIN%
rem Redemarrage des services
rem Le service "Server" sera demarre en meme temps
rem que les autres puisqu'ils en dependent
net start "Net Logon"
net start "Computer Browser"
net start "Distributed File System"
Réactivation sur la cible
Avant de réactiver la cible, il faut basculer les LUNs manuellement ou à l’aide du script mentionné plus haut.
Ne reste plus qu’à remonter le service sur la cible. Pour cela, il suffit d’aller dans le gestionnaire de disques, réaffecter les lettres de lecteurs et redémarrer le service ‘Server’ et ses dépendances. Cette partie peut aussi être automatisée. La commande mountvol permet de remonter les lecteurs en identifiant les volumes par leur ID.
Veiller à exécuter un checkdisk pour rejouer le journal NTFS puisqu’il ne semble pas possible de flusher le cache. Pour mon installation:
mountvol X: \\?\Volume{3e0cfc97-a6c5-11de-84f1-00237de94c0e}\
chkdsk /F /X X:
rem Redemarrage du service de partage
net stop "Server" /y
net start "Net Logon"
net start "Computer Browser"
net start "Distributed File System"
Les disques risquent de ne pas être détectés immédiatement par Windows. Microsoft fournissent l’utilitaire devcon permettant de rafraîchir la configuration matérielle. Il suffit donc de lancer la commande
devcon rescan
juste avant d’assigner une lettre de lecteur avec mountvol.
Retour arrière
Même procédure mais sans copier les partages du registre puisqu’ils y sont déjà bien sûr.
Cache Netbios
Lorsque l’utilisateur accède à un partage, le nom Netbios du serveur et l’adresse IP associée sont ajoutées dans la table Netbios qui joue le rôle de cache. Par défaut, les entrées sont stockées 10 minutes.
Le contenu de la table de noms est visible avec la commande nbtstat:
C:\>nbtstat -c
Connexion au réseau local:
Adresse IP du noeud : [192.168.0.10] ID d'étendue : []
Table de nom de cache distant NetBIOS
Nom Type Adresse d'hôte Vie [sec]
------------------------------------------------------------
SERVER1 <20> UNIQUE 192.168.0.200 50
SERVER2 <20> UNIQUE 192.168.0.201 40
Si un utilisateur accède au partage \\fichiers juste avant la bascule, il devra attendre un délai allant jusqu’à 10mn. 2 solutions s’offrent à nous:
– Désactiver ce cache en ajoutant la valeur DWORD EnableProxy sous la clé de registre [HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netbt\Parameters], initialisée à 0.
– Diminuer le timeout sur le cache de 600 à 60 secondes. C’est ce que nous faisons, le timeout correspond ainsi au TTL de l’entrée DNS. Editer la valeur CacheTimeout sous [HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Netbt\Parameters]
Remplacer:
927c0 (600000 en décimal) par
ea60 (60000 en décimal)
Cette clé peut être modifiée sur tous les postes via les GPO.
Cache d’écriture disque
En ayant affaire à un cluster se connectant un stockage partagé, il est préférable de désactiver le cache d’écriture sur disque pour retrouver toutes les données sur le serveur en standby au cas où le primaire subit un crash ou bascule.
Dans le gestionnaire de périphériques, décocher Activer le cache d’écriture sur le disque dans les propriétés du disque (labellisé Multi-path Disk Device sur mon serveur).
Voilà, nous avons de la redondance sur du Windows 2003 server standard edition pour un failover qui prend moins d’une minute, sans débourser un sous de plus.
Voici les scripts pour désactiver le serveur principal et activer le serveur secondaire. A renommer avec une extension .bat bien entendu. Les scripts pour la bascule arrière sont quasiment identiques. Ils incluent une vérification pour ne pas monter les lecteurs en même temps des 2 côtés.
Notes:
Ne pas créer de nouveaux partages quand on est sur le serveur de backup puisque le script réplique de serveur 1 vers serveur 2, dans ce sens uniquement.