Rationalisation de l'exploitation de serveurs Zope/Plone avec Xen
Philippe Daubias
Institut National de Recherche Pédagogique
19 allée de Fontenay, BP 17424
69347 Lyon cedex 07
Résumé
Dans cet article, nous effectuons un retour d’expérience sur l’utilisation de Zope/Plone pour une trentaine de sites web collaboratifs et présentons la solution entièrement basée sur des outils libres standards mise en place pour gérer efficacement des instances Zope sur lesquelles reposent les sites Plone. Plus précisément, nous décrivons comment, à partir d'un ensemble hétérogène construit progressivement au cours de trois années, nous avons obtenu après rationalisation, une architecture unifiée, avec une gestion pérenne et répartie entre plusieurs serveurs virtualisés avec Xen. L’architecture mise en place est le fruit de l'expérience de quatre années d'exploitation de ces plateformes. Elle améliore la disponibilité des serveurs, réduit considérablement la gestion courante et simplifie les évolutions par une automatisation massive des tâches d’exploitation et de déploiement, le tout en intégrant bien les tâches de développement.
Mots clefs
Virtualisation, LVM, snapshot, industrialisation, open source, CMS, Zope, Plone, Apache, Awstats, Logrotate, Rsync.
Le web dynamique et les plateformes de travail collaboratif (CMS : Content Management System) ont connu un essor rapide ces dernières années. Parmi les nombreuses solutions logicielles libres disponibles, Zope et Plone codés en Python, font partie des plus stables et des moins sujettes aux failles de sécurité1. Pourtant, si le choix de cette plateforme se justifie, elle nécessite un fort investissement, pour ne pas se laisser déborder par l'exploitation de ses instances. Dans cet article, nous exposons la situation initiale à l'INRP, héritée d'une mise en place fortement contrainte par le temps (§ 2), pour en déduire un cahier des charge d'une architecture plus rationnelle (§ 3). Nous exposons dans un second temps, l'architecture mise en place, d'un point de vue technique (§ 4), puis du point de vue du développement (§ 5). Enfin, nous exposons les principales améliorations obtenues (§ 6) et les perspectives de ce travail (§ 7).
Pour expliquer le besoin de ce travail de rationalisation, il est intéressant de disposer de quelques éléments de contexte.
L'Institut National de Recherche Pédagogique (INRP) met en relation les mondes de la recherche et de l'éducation. Il produit notamment des ressources et les diffuse aux enseignants au travers de portails web. Suite au déplacement de son siège de Paris à Lyon, de nouvelles équipes se sont constituées, tant pour le service commun informatique (SCI) que pour ses utilisateurs. Dans ce contexte, les équipes avaient un besoin urgent d'une vitrine et d'outils pour travailler et, dans un soucis d'unification, le SCI s'est orienté vers Plone comme CMS unique pour permettre la création puis la diffusion de ressources. Avec le temps, les sites Plone se sont multipliés et leur nombre avoisine actuellement 30.
L'installation des CMS s'est faite rapidement, sans historique ni visibilité de la volumétrie cible. Le SCI a répondu au plus vite aux demandes, quitte à donner parfois des droits supérieurs à ceux nécessaires. Conséquence de cette construction précipitée, les serveurs web ont été installés dans une configuration de base (utilisateur www:www pour Apache, zope:zope pour Zope), avec des droits insuffisants pour que les développeurs puissent travailler avec des logins personnels. En développement comme en production, les développeurs partageaient le compte d'utilisateur zope et passaient root pour les modifications de configuration d'Apache et de l'arborescence qu'il servait.
Les premières instances Zope (version 2.7.3) ont été placées dans /htdocs/zope, dans des sous-dossiers nommés en fonction du site Plone hébergé (acces, cas, praxis, etc.). Ceci posait problème pour héberger plusieurs sites Plone sur la même instance, ou en cas d'évolution, car le nom de l'instance était lié au site (prévu pour être unique). Dans un second temps, les instances (version 2.8.5) ont été placées dans /htdocs/zope-2.8.5, dans des dossiers dénommés instance_1, instance_2, etc. Le nom des instances n'était plus lié aux sites, ce qui permettait d'en faire coexister plusieurs sur une même instance et d'en déplacer entre instances. Le défaut de cette deuxième solution est l'absence de lien entre la numérotation des instances, les ports sur lesquels les serveurs répondent et les sites hébergées. Comme le port sur lequel elles répondent caractérise bien les instances, les suivantes (version 2.9.5) ont été placées dans l'arborescence /htdocs/instances/2.x.y où x est le numéro de branche et y le numéro de version Zope dans des sous-dossiers nommés d'après le port, inst_8080, inst_8180, etc.
Après trois années d'exploitation, une quinzaine d'instances Zope de versions différentes étaient déployées avec des produits différents sur un serveur Linux surchargé par ce grand nombre d'instances. Des sites Plone en développement côtoyaient des sites de production sur les mêmes instances et seule une sauvegarde à chaud du système de fichiers était effectuée. En cas de problème, la seule restauration possible était de rétablir la base de données de Zope dans un état antérieur.
Après cet aperçu de la situation initiale, nous donnons maintenant des éléments de cahier des charges pour l'architecture cible : nous détaillons les tâches d'exploitation à effectuer [2][3] puis les propriétés souhaitables pour la cible.
Nous avons repéré neuf tâches d'administration indispensables pour une exploitation rationnelle des instances.
Pour chaque instance, un contrôleur zopectl permet de la démarrer (start), l'arrêter (stop), la redémarrer (restart) et tester son état (status). Cependant, ce contrôleur n'est pas lié au système Linux qui l'héberge. Pour ce faire, plutôt que de mettre des liens vers les différentes instances au niveau du système (dossier /etc/init.d/), il nous a paru plus judicieux de créer un lien unique vers un shell central zopectl.sh qui lui-même contrôle les différentes instances en production.
Zope fonctionne par défaut avec sa base de données interne (ZoDB, dans le fichier Data.fs) en mode transactionnel, c'est-à-dire qu'aucun objet n'est effacé et que chaque modification provoque l'écriture d'une transaction dans la base. Ceci permet l'annulation d'actions en repartant de l'état précédent de la base, mais la taille du fichier Data.fs augmente indéfiniment. Pour éviter de saturer les espaces de stockage, Zope prévoit via la ZMI (Zope Management Interface), son interface graphique d'administration, une fonctionnalité de nettoyage ou « packing ». On fixe un nombre n de jours d'ancienneté au delà duquel on va tout supprimer (objets supprimés et transactions anciennes). Pour ce faire, Zope renomme sa base en Data.fs.old, crée une nouvelle base en partant de l'état au jour j-n (où j est la date courante) et recopie les transactions plus récentes. À l'aide de Curl, un outil similaire à Wget, gérant bien les paramètres POST, nous avons simulé le lancement de la commande de packing sur la ZMI avec n=7 et automatisé l'ensemble dans un script pack1Zope.sh, en incorporant cet appel à Curl et la suppression du Data.fs.old. Il suffit d'exécuter de façon hebdomadaire le script pour chaque instance.
Les instances Zope produisent deux fichiers de log2 correspondant aux connexions sur les sites (Z2.log) et aux événements ou erreurs qui arrivent sur l'instance (event.log). Pour éviter la saturation des disques et analyser les connexions sur les sites, nous effectuons une rotation mensuelle des event.log avec conservation sur trois mois et une rotation quotidienne avec renommage avec la date du jour des Z2.log. Ces rotations sont opérées par l'outil standard Logrotate configuré pour s'exécuter peu avant minuit. La configuration (/etc/logrotate.d/plone) doit être faite pour chaque instance en production.
La fréquentation de tous les sites est observée. Un serveur Linux dédié récupère les logs de connexion des différents serveurs web (Apache pour les pages PHP, Zope pour les sites Plone) et les analyse quotidiennement à l'aide de Awstats. À chaque modification de structure des sites, il faut la répercuter sur la configuration du serveur de statistiques.
L'INRP dispose d'un robot de sauvegarde et d'archivage à long terme sur bande (sauvegardes quotidiennes sur deux semaines, archives hebdomadaires, mensuelles, annuelles conservées de façon sécurisée hors du siège). Cet outil effectue des sauvegardes complètes ou incrémentales directement à partir du système de fichiers. Il n'y a aucun paramétrage spécifique à effectuer car toute l'arborescence contenant les instances est sauvegardée. Toutefois, il faut noter que les fichiers Data.fs sont systématiquement sauvegardés même en mode incrémental, car ils sont modifiés lors du redémarrage lié au Logrotate quotidien, y compris s'il n'y a pas eu de modification sur les Plones hébergés.
En plus de celles du robot, des sauvegardes croisées quotidiennes entre serveurs ont été mises en place. Elles donnent un accès très rapide à l'état de la veille sans avoir à mobiliser une restauration à partir des bandes. Cette seconde sauvegarde présente aussi l'intérêt de palier aux pannes du robot. D'un point de vue pratique, elle est réalisée avec l'outil standard Rsync qui permet de recopier de façon efficace les fichiers du serveur de production s1 sur un autre serveur s2. L'appellation sauvegardes croisées vient du fait que nous effectuons également la sauvegarde de s2 vers s1. Initialement s2 était le serveur de développement, mais dans notre nouvelle architecture s2 est un second serveur de production.
La ZMI permet d'effectuer des importations et exportations d'arborescences d'objets dans le format zexp. Un site Plone étant une arborescence, il est possible de le sauvegarder en l'exportant. Comme pour le « packing », nous avons utilisé Curl pour simuler cette action sur la ZMI (shell sauve1Plone.sh). Les paramètres de ce shell sont la liste des sites Plone à sauvegarder et les instances qui les hébergent. Cette sauvegarde individualisée permet d'éliminer le problème d'adhérence entre sites d'une même instance Zope. En effet, restaurer un site dans un état précédent en ne disposant que des sauvegardes des Data.fs impose de restaurer toute l'instance, puis d'effectuer de longues3 manipulations pour restaurer le site.
Cette tâche est moins importante que les autres (elle n'a d'ailleurs fait l'objet que de tests, mais pas d'une mise en place automatisée sur nos serveurs), car elle ne permet que d'améliorer la tâche de sauvegarde sur le robot. En effet, comme évoqué précédemment (voir 3.1.5), en mode incrémental, le robot recopie la totalité des fichiers Data.fs, même si seules quelques transactions y ont été ajoutées depuis la sauvegarde précédente. Pour accélérer ces sauvegardes, il suffirait de substituer à la sauvegarde des Data.fs, celle de dossiers contenant les archivages incrémentaux réalisés grâce à l'outil repozo.py. Comme pour les autres tâches, il est nécessaire de traiter toutes les instances en production.
Comme pour tout serveur en production, il est important de « surveiller » que le site reste disponible. Dans le cas de l'INRP, l'outil choisi pour la supervision des serveurs est What's up sur plateforme Windows et n'a pas pu s'interfacer simplement avec notre système. Nous ne tirons donc pas bénéfice pour cette tâche de la rationalisation qui a été effectuée, mais d'autres outils de supervision comme Nagios seraient probablement plus simple à connecter à notre nouvelle architecture.
Ayant régulièrement eu des difficultés avec l'architecture précédente, nous avons établi les pré-requis pour la nouvelle : une répartition de la charge, une reprise de service rapide en cas de panne, une automatisation optimale des tâches d'administration, une séparation site par site (éliminer l'adhérence entre sites de la même instance), une standardisation des installations, un repérage facile des versions de Zope, une montée en version simple dans la même branche, un déploiement simple de nouvelles instances (proche de l'installation de base) et le lien facile de la ZMI au système de fichiers.
L'ensemble de l'industrialisation du fonctionnement repose sur une architecture distribuée entre plusieurs serveurs installés de façon cohérente (section 4.1) et d'autre part sur l'utilisation de deux fichiers de configuration centralisés (section 4.2).
L'ancien serveur étant surchargé, il était possible d'avoir un nouveau serveur plus puissant et/ou de distribuer le trafic entre plusieurs serveurs. Pour des raisons de flexibilité, nous avons opté pour la distribution de la charge sur des serveurs virtuels (notamment pour le clonage). Plus précisément, nous avons choisi la para-virtualisation de Xen pour ses performances. Nous avons mis en place une architecture répartie entre trois serveurs virtuels, un pour le développement et deux pour la production (pouvant être étendue de façon automatique à n serveurs). Ces trois serveurs sont hébergés par deux hyperviseurs, chaque hyperviseur n'hébergeant qu'un seul serveur de production (voir Figure 1).
Figure 1 - Architecture des serveurs Zope
Le premier hyperviseur héberge deux machines virtuelles : le premier serveur de production Zope et un serveur pour une base de données eXist. Le second hyperviseur héberge le second serveur de production et le serveur de développement. Le premier serveur de production a été construit puis cloné pour produire les autres serveurs. Si le serveur de développement a subi plusieurs modifications de configuration par rapport au résultat du clonage (masque de création des fichiers, création de comptes pour les développeurs, ajout de shells utilisateurs, etc.), le second serveur de production est quasi-identique au premier. Les seules différences sont le nom de la machine (dans /etc/hostname et /etc/ssmtp/ssmpt.conf) et les paramètres réseau (/etc/network/interfaces).
Les deux serveurs virtuels de production portent la totalité des instances Zope sur leur système de fichiers, mais une partie seulement est active sur le premier serveur, les autres instances étant dormantes (briques respectivement jaune clair et vert sombre sur Figure 1). Le second serveur de production est complémentaire : les instances actives sur le premier serveur y sont dormantes et réciproquement. Pour rester synchronisés, les serveurs sont quotidiennement répliqués l’un sur l’autre, ce qui permet également une redondance en cas de panne. Afin de ne pas trop charger les serveurs de production, cette synchronisation est effectuée depuis les hyperviseurs (flèches roses sur Figure 1) en utilisant un snapshot du volume LVM contenant les données des instances Zope. La synchronisation des bases ZoDB représentant pourtant plusieurs dizaines de Gigaoctets est faite en quelques minutes seulement avec Rsync grâce à l'utilisation de l'option --append.
Le serveur de développement dispose pour sa part de shells permettant de récupérer les instances en production pour les modifier localement. Il permet aussi de pousser vers la production le résultat du travail sur la plateforme de développement.
En ce qui concerne l'installation, toutes les instances Zope sont stockées sur un disque séparé (monté en /var/data/) en utilisant comme premier niveau d'arborescence les numéros de branches Zope (2.7, 2.8, 2.9, etc.) et non les numéros complets de versions. Ceci permet d'assurer les montées en version au sein d'une même branche (de 2.8.5 à 2.8.9 par exemple) sans modifier la structure, simplement en installant la nouvelle version et en re-configurant les instances pour utiliser ce nouveau moteur Zope. Le second niveau de l'arborescence sert à désigner l'instance par le numéro de port sur lequel elle répond (inst_8080, inst_9180, etc.). L'installation de toutes les instances est ainsi uniforme, ce qui permet le fonctionnement de tous les shells automatiques sans gestion de cas particuliers.
Le premier fichier Instances-Zope.txt liste des triplets (numéros de port, nom de serveur, mot de passe). Les numéros de port sont ceux des instances en production, le second élément est le nom du serveur Linux de production qui porte l'instance et le mot de passe est celui d'accès à la ZMI. Le second fichier Sites-Plone.txt liste des couples (numéro de port, nom site Plone), où le numéro de port est celui de l'instance Zope qui porte le site Plone.
Grâce à un ensemble de shells reposant uniquement sur des outils standard (sed, grep, awk, curl, rsync), ce qui assure un déploiement simple sans installation de paquets supplémentaires, nous avons automatisé et rendu paramétrable l’ensemble des tâches d’exploitation vues précédemment (section 3.1). Les deux fichiers de configuration précédents sont lus par les shells qui, en fonction des tâches à réaliser, s'adaptent au serveur sur lequel ils s'exécutent. Ces fichiers sont stockés sur le serveur de développement et un shell spécifique permet de propager la configuration vers les serveurs de production. Les hyperviseurs qui ont également besoin des informations de ces fichiers, effectuent avant toute action un snapshot LVM du système du serveur de production qu'ils hébergent pour mettre à jour leur configuration.
Pour l'exemple, la Figure 2 présente la partie centrale du code (les tests ont été supprimés) de /exploit/zopectl.sh qui peut prendre comme paramètre start, stop, restart, status et la Figure 3 le fichier de configuration de logrotate pour Plone.
SERVEUR=`uname -n`
PORTS=`grep $SERVEUR /exploit/config/Instances-Zope.txt | awk '{print $2}'`
for i in $PORTS
do
echo "instance /var/data/zope/2.X/inst_$i :"
su -m zope -c "/var/data/zope/2.*/inst_$i/bin/zopectl $1"
done
Figure 2 - Portion de code du shell /exploit/zopectl.sh
/var/data/zope/2.*/inst_*/log/Z2.log {
daily
missingok
rotate 10
compress
delaycompress
notifempty
create 0640 zope sci
lastaction
DATE=`date '+%Y%m%d'`
SERVEUR=`uname -n`
PORTS=`grep $SERVEUR /exploit/config/Instances-Zope.txt | awk '{print $2}'`
/exploit/zopectl.sh restart > /tmp/cron_zopectl_reboot.log 2>&1
for i in $PORTS
do
cd /var/data/zope/2.*/inst_$i/log/
mv Z2.log.1 Z2-$i.log.$DATE
done
endscript
}
Figure 3 - Fichier de configuration de logrotate pour Plone (/etc/logrotate.d/plone)
Pour modifier la configuration (ajout d’une instance Zope ou d’un site Plone, suppression d’une instance, migration de Plone), il faut adapter la configuration des tâches précédentes. Contrairement à la situation initiale où chaque modification nécessitait l'édition de nombreux fichiers, un changement est maintenant très simple. Prenons par exemple le déploiement d'un nouveau site Plone sur une nouvelle instance Zope. Avec l'ancienne architecture, cela nécessitait de modifier le contrôleur Zope zopectl.sh, les fichiers /etc/logrotate.d/plone, sauvePlones.sh, packZopes.sh du serveur de production et les fichiers prepareLogs.sh et updateStats.sh du serveur de statistiques qui gèrent respectivement la récupération des fichiers de logs et la correspondance entre instances et sites Plone (ainsi que le fichier de configuration de repozo si cet outil était déployé). Soit un total de six (voire sept) fichiers où les interventions diffèrent à chaque fois et étaient sujettes à oublis et erreurs. Avec la nouvelle architecture, une telle modification n'implique que d'ajouter d'une part dans le fichier Instance-Zope.txt le triplet (nouveau port, serveur de production, mot de passe d'administration de l'instance) et d'autre part, le nom du nouveau site Plone dans le fichier Sites-Plone.txt. Pour valider ces modifications, on utilise le shell push_config.sh qui va répercuter ces modifications sur les serveurs de production. Cette modification nécessite environ une minute et évite tout oubli. L'amélioration est particulièrement notable car il y a plusieurs serveurs de production dans la nouvelle architecture et malgré cette complexification de l'architecture, nous avons considérablement facilité la gestion.
L'architecture initiale était peu tolérante aux pannes. Un simple redémarrage du serveur (physique) nécessitait au minimum 5 à 10 minutes de blocage de tous les serveurs, durée qui pouvait être beaucoup plus importante en cas de reconstruction des disques RAID. Par ailleurs, si les données étaient sauvegardées sur bande, il n'y avait pas de serveur équivalent pour remettre en production les sites. Le serveur de développement a été utilisé dans ce but à quelques reprises, mais une demie-journée était nécessaire pour remettre seulement deux sites en ligne. Avec la nouvelle architecture, un redémarrage du serveur (virtuel) dure environ 30 secondes. Un redémarrage de l'hyperviseur (machine physique) reste relativement long. Toutefois, l'hyperviseur est un système léger avec très peu de services et en configurant Xen pour effectuer un shutdown sur les hôtes au lieu d'une sauvegarde (hibernation), nous avons réussi à diminuer significativement ce temps de redémarrage qui est maintenant de l'ordre de 2 minutes.
En cas de problème sur l'un des serveurs de production (attaque, panne physique de l'hyperviseur), étant donné que les données dans l'état de la veille sont présentes sur l'autre serveur, il est possible de rendre actives les instances Zope du second serveur et de modifier le DNS pour rediriger le trafic sur ce serveur au lieu de l'autre pour prendre le relai. En effet, au niveau d’Apache qui redirige les flux web vers les instances Zope, nous avons créé des virtualhosts indépendants du serveur sur lequel ils se trouvent et qui sont donc prêts à fonctionner. Si le problème concerne les deux serveurs, des images tar du système de la machine virtuelle étant sauvegardées à chaque modification significative, il suffit de redéployer la dernière archive tar avec xen-create-image qui permet de générer rapidement un serveur virtuel sur un nouvel hyperviseur et d'effectuer une recopie complète des données qui sont sauvegardées sur bande.
Si la charge augmente sur l'un des serveurs de production, la simplicité de modification vue précédemment (§ 4.3) permet également de ré-équilibrer manuellement la répartition de la charge via un shell en transférant rapidement des instances entre les serveurs de production. Il faut alors modifier la configuration d'Apache dans un premier temps pour pointer sur le bon serveur puis celle du DNS ce qui permet d'assurer dans de bonnes conditions le temps de propagation du DNS. Si la charge globale devient trop importante, il est possible de cloner l'un des serveurs de production pour passer à trois serveurs.
Contrairement aux sites Plone, les statistiques de connexion sur ces sites ne nécessitent pas une haute disponibilité et il n'y a pas de plan de reprise d'activité rapide pour ce service. En revanche, par rapport à un fonctionnement initial qui n'analysait qu'une partie des sites de l'institut et nécessitait des réparations manuelles à chaque panne, nous avons tout refondu fin 2007. La collecte automatique des logs a été généralisée, en la rendant robuste aux éventuelles interruptions des serveurs (pannes et maintenance) et en permettant des recalculs en cas de modification des filtres. Le résultat est entièrement paramétrable à partir de deux fichiers de configuration principaux. Ces fichiers de configuration reprenaient globalement les mêmes informations que les fichiers mis en place pour Zope et il a semblé naturel de profiter de l'automatisation de la gestion des Zope pour y connecter le système automatique d'analyse des connexions. Par rapport aux autres tâches automatisées, les pré-requis sont les mêmes (repérage des serveurs où les instances sont actives et association des sites avec les instances) avec une difficulté supplémentaire, puisqu'il faut en plus mémoriser l'historique des modifications pour les éventuels recalculs.
Jusqu'ici, nous avons présenté une architecture rationalisée en montrant comment le nouveau système simplifiait le travail des administrateurs lors des changements de configuration. Cependant, nous n'avons que peu abordé le point de vue des développeurs ni exploré leurs différentes activités. Dans cette section nous rappelons quelques éléments clés du fonctionnement de Zope, puis nous listons les shells créés pour répondre aux besoins des développeurs.
Zope/Plone permettent de bien séparer le contenu de la présentation [1], ce qui permet de faire facilement évoluer l’aspect graphique du site ou ses fonctionnalités sans interférer sur les contenus. Cependant, l’ensemble contenu et présentation est physiquement solidaire, stocké ensemble dans la base de données Zope (fichier Data.fs). En principe, on sépare toujours l’environnement de développement qui sert à effectuer les tests, du site de production où sont déployées les versions validées et stabilisées de l’application. Pourtant, avec Zope, sauf à créer des produits d’extension [4], solution trop lourde pour de petits paramétrages (« customisations ») de Plone, les développeurs sont obligés de travailler sur la production pour certaines tâches si l’on ne veut pas interrompre l’utilisation du CMS. Dans ce contexte, les développeurs peuvent prendre l’habitude de faire toutes leurs modifications en production avec des désagréments directs pour les utilisateurs en cas d'erreur.
Nous avons développé un ensemble de procédures automatiques de recopie permettant aux développeurs de travailler sur l’environnement de développement, pratiquement comme s’ils le faisaient sur la production. Des shells permettent de rapatrier un site de la production vers le développement (pull_instance.sh), mais aussi de mettre à jour la production avec les modifications effectuées en développement (push_instance.sh), le tout rapidement, sans que les développeurs n’aient accès au système de fichiers du serveur de production. D'autres shells permettent d'assurer des tâches de déploiement comme l'ajout d'une instance (add_instance.sh) ou le déplacement d'une instance d'un serveur de production à un autre (mv_instance.sh). Les développeurs disposent ainsi d’un environnement de test identique à la production, où ils peuvent préparer des correctifs (exportés ensuite en archive Zexp puis importés sur la production) ou tester des modifications (de droits, de workflows, de skin, de produits, etc.) avant de les reproduire en production si les tests s’avèrent concluants.
Par ailleurs, pour soulager les développeurs de ces tâches de vérification, les shells mis en place déduisent le paramétrage nécessaire aux actions à effectuer. Par exemple, push_instance.sh peut servir à une mise en production initiale d'une instance ou à des mises à jour sur l'un ou l'autre des serveurs de production. Le shell ne prend comme paramètre que le numéro de port de l'instance, il recherche le serveur de production correspondant, la version de Zope, vérifie l'existence ou non d'une instance en production, adapte son comportement et arrête temporairement l'instance pendant la copie si nécessaire. Ainsi, le résultat de notre travail est un ensemble de shells prenant peu de paramètres et gérant eux-mêmes les différents cas de figure.
Après avoir analysé l'existant et déterminé l'ensemble des tâches à effectuer avec leurs pré-requis, nous avons proposé et réalisé une refonte complète de l’architecture des serveurs Zope avec une virtualisation sur Xen, en conservant la possibilité de gérer en parallèle plusieurs versions de Zope. La nouvelle architecture est en place depuis début 2009 et s'est révélée très fiable avec une seule interruption de la production (en raison d'une coupure électrique) au lieu d'une environ toutes les trois semaines précédemment. Durant cette période, l'administration système s'est limitée à des mises à jour par aptitude update et à deux ou trois allumages d'instances éteintes accidentellement par des développeurs via la ZMI. En dehors de ces erreurs de manipulation liées aux noms trop similaires de nos serveurs virtuels (xen-zope, xen-acces-zope, xen-zope-devel), nous n'avons rencontré de problème ni au niveau de l'exploitation, ni sur les activités des développeurs.
La solution mise en place est donc performante, robuste, cohérente, très automatisée et facilement reconfigurable : la charge des instances Zope est distribuée entre deux serveurs Linux et le flux web entrant se répartit entre 3 serveurs Apache frontaux. Une montée de charge se gère simplement et la reprise d'activité est extrêmement rapide. Les deux fichiers de configuration centralisé sont nécessairement toujours à jour et le fichier Sites-Plone.txt donne de façon directe la correspondance entre sites Plone, instances Zope et système de fichiers du serveur. La gestion des serveurs engendre considérablement moins d'erreurs qu'avant et la charge d'exploitation des serveurs est réduite à son minimum.
Il y a une séparation complète entre le développement et la production, et les développeurs n'ont plus d'accès direct aux plateformes de production. Ceci limite considérablement les problèmes sur la production, mais il y a eu une diminution de l'autonomie des développeurs qui cherchent parfois comment procéder avec la nouvelle architecture dont le fonctionnement est plus complexe. Ceci peut être considéré comme le seul point négatif liée à la rationalisation.
La virtualisation a permis d’améliorer la disponibilité du service avec une reprise rapide en cas de panne ou d'arrêt du serveur, mais aussi de soulager les serveurs de production de certaines tâches effectuées par les hyperviseurs grâce à des snapshots LVM. La virtualisation facilite aussi le déploiement de nouveaux serveurs par clonage d’un serveur de production.
Par ailleurs, cet article étant centré sur les serveurs Zope, nous n'avons pas détaillé l'automatisation similaire qui a été effectuée au niveau d'Apache : la machine de développement centralise la configuration qui est ainsi accessible aux développeurs et peut la propager automatiquement sur les serveurs de production. Nous utilisons pour ce faire le fonctionnement d'Apache 2 avec des fichiers de configuration disponibles (sites-available) et des liens pour ceux qui sont actifs (sites-enabled). Ceci permet d'avoir la configuration disponible répliquée et seule la configuration active diffère.
Même si le travail déjà réalisé a permis de rationaliser fortement l'architecture par rapport à l'existant, il reste encore des voies d'amélioration notables : l'utilisation de repozo.py pour limiter le volume des sauvegardes incrémentales du robot, l'externalisation des gros fichiers statiques en dehors de la ZoDB par des produits Zope dédiés, l'uniformisation des versions de produits utilisés et une étude de faisabilité sur le regroupement des produits n'ayant pas de configuration locale. Le même travail de rationalisation a été effectué sur les applications PHP/mysql de l'établissement qui ont toutes été transférées (sauf le webmail) sur une nouvelle plateforme virtualisée avec Xen. À la date de rédaction de cet article, les serveurs web de l'INRP sont encore dans une phase de transition (passage en Lenny et amélioration des shells pour les développeurs).
L'auteur remercie Thomas Bellembois d'avoir introduit Xen et LVM à l'INRP et le SCI : le pôle système pour l'autonomie accordée sur la refonte des serveurs web, et le pôle développement : à son responsable pour son soutien et aux développeurs, en particulier Philippe Federici pour avoir accepté des changements profonds dans leur façon de travailler.
Frédéric Saint-Marcel et Philippe Lecler, Plone, un outil de gestion de contenu web. Dans Actes du congrès JRES2005, pages 131-139, Marseille, Décembre 2005.
Maurizio Delmonte, Davide Moro, Alice Narduzzo, Fabrizio Reale and Andy McKay. The Definitive Guide to Plone second edition. Apress, 2009.
Martin Aspeli. Professional Plone Development. Packt Publishing, 2007.
1Dans les bulletins hebdomadaires CERT-Renater:2008/STAT42 à 2009/STAT42, qui rapportent des failles de sécurité, sur cette période d'une année, Zope/Plone et les produits associés ne sont cités que deux fois, contre 14 citations du moteur de SPIP, près de 70 pour Joomla et ses composants et près de 80 pour Drupal et ses modules. Ce bulletin ne mesure pas la fiabilité des CMS, mais on peut quand même le considérer comme un indicateur signifiant.
2Un troisième fichier trace.log ne sert qu'à des fins de débogage. Il n'est pas utile sur une machine de production et est désactivé par défaut.
3Les étapes ne sont pas complexes (restauration instance, exportation site, suppression site de production, importation site restauré sur la production), mais le temps de réalisation s'avère dans la pratique très long, surtout pour des sites de travail collaboratif volumineux et dans un contexte de production.