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 <a href=“http://docs.puppetlabs.com/puppetdb/1/install.html” title=“http://docs.puppetlabs.com/puppetdb/1/install.html” >la doc de PuppetLabs</a>. 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.

    0_1522747207446_PuppetDB_dashboard.png

    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 et async_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.

    A savoir :
    L’option 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 😉