Puppet 3 et PuppetDB
Je viens de mettre à jour mon environnement de test vers Puppet 3 (depuis une version 2.7.19). Pas de grosses difficultés, pas de grosses surprises… Je vais vous décrire dans cet article la méthode utilisée. Le principal point bloquant que j’ai rencontré lors de cette mise à jour s’est trouvé être mon serveur MySQL (utilisé pour la partie storeconfigs/inventory). J’ai eu toute une série de bugs que je n’ai pas réussi à résoudre et le fait que cette méthode sera bientôt obsolète m’a encouragé à passer à PuppetDB. J’ai eu également 2⁄3 erreurs plus simples liées à certains de mes manifests…
Un état des lieux de votre environnement Puppet
Avant d’attaquer la mise à jour, faites un état des lieux de votre environnement pour vous éviter de grosses surprises une fois passé à Puppet 3. Le 1er pré-requis est d’être en version 2.7 (je dirais même dans la dernière version 2.7) : si vous êtes en 2.6, faites d’abord une mise à jour en 2.7. Vérifiez également sur la documentation officielle qu’aucunes des incompatibilités ne vous impacte : je ne vais pas traiter tous les points ici (attention aux paramètres de vos classes/defines, paramètres et commandes qui disparaissent et changements dans les ressources). Pour moi, le plus gros du travail a été de vérifier que mes manifests/templates étaient correctement écris au niveau de :
- La déclaration des variables : j’avais déjà effectué cette étape. J’en parlais dans cet article. Si vous ne faites pas les modifications, ça ne fonctionnera plus avec Puppet 3.
L’utilisation des templates : l’appel doit être de cette forme :
content => template('common/puppet/puppet.conf')
pour un fichier puppet.conf qui se trouve dans le module common et le répertoire templates/puppet du module.
L’utilisation de fichiers “statiques” avec source doit être formaté de cette façon :
source => 'puppet:///modules/common/puppet/auth.conf'
pour un fichier auth.conf qui se trouve dans le module common et le répertoire files/puppet du module.
C’est en gros les modifications que j’ai dû apporter dans certains de mes manifests. Pour vous aider à avoir une idée de l’ampleur du travail, vous pouvez lancer votre PuppetMaster en mode --no-daemonize
pour rechercher tous les “warning” et autres “deprecated”. Si vous utilisez Passenger, coupez d’abord Apache ou Nginx et lancez votre Puppet Master avec cette commande :
puppet master --no-daemonize --debug
Vous pouvez vous aider de Puppet-lint pour vérifier la conformité de vos manifests. Bon courage 😉
Mettre à jour votre PuppetMaster
La première chose à faire est de mettre à jour votre PuppetMaster. La façon de faire dépendra du nombre de vos PuppetMaster, de la façon dont vous avez installé Puppet etc… J’avais utilisé des paquets Debian maison pour des besoins spécifiques qui n’existent plus aujourd’hui. J’en ai profité pour passer sur les paquets de PuppetLabs. J’ai simplement conservé mon /etc/puppet et mon /var/lib/puppet. Si je détaille un peu, ça donne :
- Mes PuppetMaster sont derrière un HAProxy (voir la série d’article sur la scalabilité, j’ai donc désactivé un nœud sur lequel j’ai pu travailler tranquillement. Si vous n’avez pas un système identique, vos agents utiliseront le catalogue local le temps de la coupure du service.
- J’ai supprimé tous mes paquets Debian perso liés à Puppet, nettoyé mes gems installés (j’ai tout supprimé).
Installez la version Debian de PuppetLabs :
wget http://apt.puppetlabs.com/puppetlabs-release-squeeze.deb dpkg -i puppetlabs-release-squeeze.deb apt-get update
Utilisez ensuite la commande
apt-get policy puppet-common
pour vérifier que la version installée sera bien une 3.0.x :apt-cache policy puppet-common puppet-common: Installé : 2.7.19-1puppetlabs2 Candidat : 3.0.1-1puppetlabs1
Si ce n’est pas le cas, il faudra adapter le fichier /etc/apt/preferences avec par exemple le contenu suivant :
Package: *
Pin: release a=stable
Pin-Priority: 700
Package: *
Pin: origin "apt.puppetlabs.com"
Pin-Priority: 700
Package: *
Pin: release a=testing
Pin-Priority: 650
Package: *
Pin: release a=unstable
Pin-Priority: 600
Installez ensuite Puppet : j’utilise Puppet avec Passenger, j’ai installé Puppet via :
apt-get install puppetmaster-passenger
J’ai conservé mon puppet.conf et j’ai écrasé les autres fichier de configuration. Je vous donne ces fichiers plus bas pour information.
Puppet 3 est installé. Il est à lancer avec
/etc/init.d/apache2 start
mais j’ai fait quelques vérifications avant (et j’ai rencontré des problèmes avec MySQL, je vous propose donc d’installer PuppetDB dès maintenant).
PuppetDB
PuppetDB permet de récupérer les données collectées par Puppet comme les facts et d’utiliser entre autres les ressources exportées. Ces données pourront ensuite être utilisées par d’autres programmes, comme le dashboard, ou vos propres outils grâce à une API. Vous pouvez installer le serveur PuppetDB sur votre PuppetMaster ou sur un serveur à part. Pour mes besoins, j’ai choisi un serveur dédié et j’ai fait le choix d’utiliser un backend PostgreSQL (il n’y a pas à ce jour de support MySQL).
Pour vous aider à faire votre choix, jetez un œil aux différents goulots d’étranglement présentés dans la doc de PuppetLabs. En gros et pour résumer : si vous avez plus de 100 clients, il vous faudra une base de données PostgreSQL, gonfler votre JVM, augmenter le nombre de cpu/coeurs. Une bonne piste également (si vous avez beaucoup de clients) est d’utiliser une terminaison SSL Nginx par exemple au niveau de votre reverse proxy (j’en reparlerais dans un autre article).
Sur le serveur PuppetDB
Rien de particulier, j’ai suivi la doc de PuppetLabs. Voici les actions réalisées sur une Debian Squeeze fraichement installée. J’ai donc choisi un backend PostgreSQL (sur le même serveur pour commencer).
Comme pour le serveur PuppetMaster, j’active le repo PuppetLabs (adaptez votre /etc/apt/preferences si besoin) :
wget http://apt.puppetlabs.com/puppetlabs-release-squeeze.deb dpkg -i puppetlabs-release-squeeze.deb apt-get update
Installez et configurez un agent Puppet sur ce serveur : PuppetDB utilise les certificats SSL générés et signés par Puppet.
apt-get install puppet
Après avoir configuré votre client via le fichier /etc/puppet/puppet.conf, lancez l’agent :
puppet agent -t
Signez ce serveur avec la commande suivante sur votre PuppetMaster :
puppet cert sign monclient.fqdn
Puis relancez l’agent. Votre agent Puppet est prêt.
Pour installer PuppetDB vous pouvez le faire à la Puppet :
puppet resource package puppetdb ensure=latest
ou de façon classique sur une Debian :
apt-get install puppetdb
Si vous avez moins de 100 clients Puppet, adaptez seulement la heap size de votre JVM dans le fichier /etc/default/puppetdb. Si vous avez plus de 100 clients, il faut installer un backend PostgreSQL :
apt-get install postgresql
Puis on passe à la création d’un utilisateur PostgreSQL (je reviendrais plus tard sur l’optimisation de la base de données) :
sudo -u postgres sh
createuser -DRSP puppetdb
createdb -O puppetdb puppetdb
exit
Modifiez le fichier de configuration de PuppetDB /etc/puppetdb/conf.d/database.ini pour utiliser ce backend. Sur mon installation en local, j’ai :
classname = org.postgresql.Driver subprotocol = postgresql subname = //localhost:5432/puppetdb username = USERNAME password = PASSWORD
Modifiez le fichier /etc/puppetdb/conf.d/config.ini pour modifier la valeur de
threads
.Adaptez la configuration SSL dans /etc/puppetdb/conf.d/jetty.ini. Si vous souhaitez accéder au dashboard de PuppetDB depuis votre machine par ex., il faudra remplacer
host = localhost
par le hostname de votre serveur. Par ex :host = puppetdb.fqdn
Attention à votre /etc/hosts qui doit être correct pour que la résolution de votre serveur fonctionne (sinon vous n’aurez pas accès au dashboard).Lancez PuppetDB et activez-le au démarrage de votre serveur :
puppet resource service puppetdb ensure=running enable=true
PuppetDB est démarré : contrôlez les logs /var/log/puppetdb/puppetdb.log.
- J’ai eu ces erreurs (certainement liées à une précédente installation) :
[io.nio] javax.net.ssl.SSLException: Received fatal alert: certificate_revoked
Pour résoudre ce problème j’ai dû refaire la certification SSL. Sur mon PuppetMaster, j’ai supprimé le certificat de mon serveur PuppetDB :
puppet cert clean puppetdb
Puis sur le serveur PuppetDB :
rm -fr /var/lib/puppet/ssl
puppet agent -t
Signez le certificat sur votre PuppetMaster et relancez l’agent. Il faut ré-importer les clés SSL pour PuppetDB :
/usr/sbin/puppetdb-ssl-setup
Vérifiez que le key-password
et le trust-password
soit bien équivalent au contenu du fichier /etc/puppetdb/ssl/puppetdb_keystore_pw.txt. Relancez PuppetDB.
- Vous pouvez accéder à l’IHM de PuppetDB sur le port 8080 de votre serveur PuppetDB. Vous aurez ce genre d’informations quand vous aurez terminé votre migration.
Sur le(s) PuppetMaster
Pour connecter votre PuppetMaster à votre PuppetDB, voici les étapes à réaliser :
- Activez le repo PuppetLabs.
Installez le plugin PuppetDB via :
puppet resource package puppetdb-terminus ensure=latest
ou
apt-get install puppetdb-terminus
Rajoutez dans la section
[master]
du fichier de configuration Puppet /etc/puppet/puppet.conf les lignes suivantes :storeconfigs = true storeconfigs_backend = puppetdb
Supprimez les paramètres
thin_storeconfigs
etasync_storeconfigs
(si vous les utilisiez) de votre configuration.Rajoutez le fichier /etc/puppet/puppetdb.conf avec :
[main] server = puppetdb.fqdn port = 8081
Puis le fichier /etc/puppet/routes.yaml :
--- master: facts: terminus: puppetdb cache: yaml
Puppet 3 sur les clients
C’est très simple :
Installez le repo PuppetLabs :
wget http://apt.puppetlabs.com/puppetlabs-release-squeeze.deb pkg -i puppetlabs-release-squeeze.deb apt-get update
Ajustez le fichier /etc/apt/preferences.
apt-get update && apt-get install puppet
Résumé / 1er lancement
Tout est configuré… Je vous donne mes fichiers de configuration pour information.
pluginsync = true
est maintenant activée par défaut.
Il faut rajouter les lignes suivantes sur votre PuppetMaster dans la section [master]
de votre /etc/puppet/puppet.conf pour que Passenger fonctionne correctement :
ssl_client_header = SSL_CLIENT_S_DN
ssl_client_verify_header = SSL_CLIENT_VERIFY
- Le puppet.conf du serveur.
- Le fichier auth.conf du serveur.
Au premier lancement, pour vérifier que tout était ok, j’ai lancé mon PuppetMaster sans Passenger avec
puppet master --no-daemonize --debug
. Le dernier petit problème rencontré est lié à une librairie Ruby d’un module Puppet (un parser) : la fonction attend un tableau de paramètre. L’erreur en question :
For example, function_example([1]) instead of function_example(1)
Votre PuppetMaster doit stocker les catalogues, facts, ressources exportées sur votre PuppetDB. Vous devez voir ce genre de logs sur votre PuppetDB :
2012-05-17 13:08:41,664 INFO [command-proc-67] [puppetdb.command] [85beb105-5f4a-4257-a5ed-cdf0d07aa1a5] [replace facts] screech.example.com
2012-05-17 13:08:45,993 INFO [command-proc-67] [puppetdb.command] [3a910863-6b33-4717-95d2-39edf92c8610] [replace catalog] screech.example.com
Vous pouvez relancer le PuppetMaster via /etc/init.d/apache2 start
. Migration terminée !
J’ai fait cette migration la semaine dernière. Depuis, rien à signaler, pas de problème, bugs… L’ensemble de mes articles sur Puppet, notamment ceux sur la scalabilité restent valables modulo les versions de Puppet/Nginx/Apache/Passenger… J’espère que cet article sera utile à ceux qui veulent faire la mise à jour. Bon courage 😉