Puppet, installation et première configuration

Date: 3/09/2012 | Catégories: Open-source,Planet-libre,Systeme | Tags: ,,,,

Il s'est écoulé quelques mois depuis mon premier billet sur les logiciels libres de gestionnaires de configurations de machines. Ce laps de temps m'a permis de consulter un nombre important d'articles, de forum et de littérature. Il est donc maintenant temps de partager cela avec vous.

J'avais initialement prévu de faire un seul gros article, mais devant le nombre important de choses à dire et la complexité du sujet, j'ai préféré le découper en plusieurs parties.

La première, que vous êtes en train de lire est une introduction à Puppet ou l'on va détailler l'installation (serveur et cliente) et la configuration initiale du système. Viendront ensuite des billets spécifiques sur la définition des sites et noeuds puis un ou plusieurs autres sur les modules.

Introduction

Puppet est donc un "gestionnaire de configurations de machines". Derrière ce terme un peu barbare se cache la possibilité de centraliser la configuration système de vos machines au sein d'un référentiel unique. Le procédé peut très bien s'appliquer à une seule machine ou à un parc important et hétérogènes.

Puppet fonctionne sur le principe de clients (installé sur les machines de votre parc) et d'un serveur (installer sur un ou plusieurs serveurs de votre réseau). Puppet permet ainsi de s'assurer qu'à un instant t, toutes les machines clients sont dans un état de configuration défini sur le serveur.

Pour des besoins de tests il est tout à fait envisageable d'héberger à la fois le client et le serveur sur une seule et même machine. J'ai choisi, pour illustrer cet article, d'une architecture un peu plus proche de la réalité:

Puppet "testbed"

Pourquoi Puppet et non pas Chef ou CfEngine ?

Tout simplement la solution qui m'a semblé la mieux documentée et avec un nombre important de ressources (blog / forum) sur le sujet. Chaque solution a ses avantages, je vous laisse chercher sur votre moteur de recherche préféré les différents articles permettant de les comparer et de choisir celle qui s'adaptera le mieux à vos besoins et surtout avec votre manière de fonctionner.

Installation du serveur Puppet (aka PuppetMaster)

La version 2.6.6 est disponible dans les dépôts officiels de la Debian 6 (Squeeze) au moment de la rédaction de ce billet. Afin de permettre une utilisation avec les clients en 2.7 (version actuellement packagée sous Ubuntu 12.04), il est nécessaire de passer par le dépôt backports que l'on installe de la manière suivante:

# sudo vi /etc/apt/sources.list.d/backports.list

deb http://backports.debian.org/debian-backports squeeze-backports main

L'installation du serveur (module PuppetMaster) et de ses dépendances se fait sur une distribution GNU/Linux Debian 6 via les commandes suivantes (en root ou précédée de sudo):

sudo apt-get update
sudo apt-get -t squeeze-backports install puppetmaster

Une commande permet de s'assurer que le serveur est bien lancé:

$ sudo service puppetmaster status
master is running.

Attention: Si votre serveur est protégé par un Firewall alors il faut penser à ouvrir le port TCP/8140 qui est le port par défaut, sinon les clients n'arriveront pas à le joindre. Si votre serveur est hébergé derrière un réseau NAT, il faudra également rediriger le port TCP/8140 vers votre machine.

Installation d'un client Puppet (Debian ou Ubuntu)

Encore plus simple est l'installation d'un client Debian (sur laquelle le dépôt backport a été ajouté):

sudo apt-get -t squeeze-backports install puppet
 ou Ubuntu en utilisant la commande suivante (en root ou précédée de sudo):
sudo apt-get install puppet

Pour fonctionner, le client Puppet a besoin de connaitre l'adresse du serveur (PuppetMaster). On doit donc éditer, sur la machine cliente, le fichier /etc/puppet/puppet.conf et y ajouter la ligne suivante dans la section [main]:

server=<@IP ou NOM du serveur>

Attention: si vous utilisez un nom, ce qui est conseillé, il faut bien s'assurer que la résolution s'effectue correctement à la fois sur le serveur et sur les clients.

Pour sécuriser la connexion entre les clients et le serveur, Puppet utilise des tunnels SSL. Ces derniers nécessitent une phase d'initialisation à faire seulement une fois lors de la configuration du client. On commence par lancer la commande suivante sur le client (en root ou précédée de sudo):

client$ sudo puppetd -t -v -w 60

info: Caching certificate for ca
info: Creating a new SSL certificate request for optiplex790
info: Certificate Request fingerprint (md5): E2:D6:FB:1C:7C:36:96:D8:45:92:84:E3:71:F4:C6:BD
info: Caching certificate for optiplex790

On demande ensuite, sur le serveur, la liste des certificats SSL en attente de validation (en root ou précédée de sudo):

serveur$ sudo puppetca --list
  "optiplex790" (E2:D6:FB:1C:7C:36:96:D8:45:92:84:E3:71:F4:C6:BD)
Nous avons donc une machine identifié par le nom "optiplex790" (le nom de ma machine cliente) qui nécessite d'être autorisé par le serveur. Pour effectuer cette tache d'autorisation, on doit valider son certificat (en root ou précédée de sudo):
serveur$ sudo puppetca --sign optiplex790      

notice: Signed certificate request for optiplex790
notice: Removing file Puppet::SSL::CertificateRequest optiplex790 at '/var/lib/puppet/ssl/ca/requests/optiplex790.pem'

Remarque: il est également possible de forcer l'authentification pour une plage d'adresses IP donnée. Cela représente tout de même une faille de sécurité qui est difficilement acceptable sur une réseau en production.

Il ne reste plus, sur le client, qu'à éditer le fichier /etc/default/puppet pour automatiser le lancement de Puppet au démarrage de la machine:

# Start puppet on boot?
START=yes

Et enfin à relancer le daemon du client en tache de fond:

sudo /etc/init.d/puppet start

Pour les phases de tests (par exemple lors de la mise en place de nouveaux modules), il est conseillé de désactiver le demon sur les clients...:

sudo /etc/init.d/puppet stop
... et de le lancer à la main et en mode "verbeux":
sudo puppetd -t -v

Et sous Windows ?

Puppet propose un client open-source sous Windows.

La procédure d'installation se trouve ici. Sous Winddows 7, le fichier de configuration puppet.conf ou il faudra configurer l'adresse du PuppetMaster se trouve dans le répertoire C:\ProgramData\PuppetLabs\puppet\etc.

Pour lancer Puppet client, il suffit ensuite de lancer une premier fois Puppet à partir du menu Démarrer > Programmes > Puppet > Run Puppet Agent. Ce dernier va afficher un message comme quoi le serveur n'arrive pas à l'identifier. On doit, comme pour les client GNU/Linux forcer l'authentification avec la commande suivante sur le serveur:

sudo puppetca --sign win7

Le prochain lancement de Puppet (menu Démarrer > Programmes > Puppet > Run Puppet Agent) devrait se faire sans problème.

Et hop passons aux choses sérieuses...

Configuration de votre référence: le serveur Puppet

Toute la configuration (référentiel) de Puppet est centralisé dans l'arborescence /etc/puppet de votre serveur fraichement installé. Dans le "best practice" de Puppet, il est fortement conseillé de gérer ce répertoire (et ce qu'il contient) en configuration (sous CVS, SVN ou GIT). C'est dans ce répertoire que nous allons définir notre site (réseau), nos noeuds (machines) et les modules (actions) à appliquer lors de la mise en configuration.

Commençons par une rapide description des fichiers contenus dans ce répertoire:

  • /etc/puppet/manifests/site.pp: C'est le premier fichier analysé par PuppetMaster pour définir son référentiel. Il permet de définir des variables globales et d'importer des modules (ensembles de classes) ainsi que des fichiers templates et noeuds de votre réseau. Attention de ne pas définir directement les templates et les noeuds dans ce fichier... C'est techniquement faisable mais pas très propre à maintenir.
  • /etc/puppet/manifests/template.pp: (optionnel) Permet de définir ou d'étendre (notion d'héritage comme en POO) des classes spécifiques à votre réseau.
  • /etc/puppet/manifests/node.pp: Permet de définir les noeuds (machines) de votre réseau. Il est conseillé de défini le nom d'un noeud par le nom FQDN de la machine. Si votre réseau est important (plusieurs centaines de machines à gérer), il est tout à fait possible de créer une arborescence dédié avec un fichier node.pp par sous-réseau.
  • /etc/puppet/modules/<module>/: Sous répertoire contenant la définition du module (action). Un fichier <module>/manifests/init.pp contient la définition du module (en clair c'est ici que l'on va définir ce que l'on doit faire sur la machine cliente) et le répertoire <module>/files/l'ensemble des fichiers nécessaires à l’exécution de ce module. Voyons maintenant le détail de ces fichiers.

Définition de votre site (réseau Puppet)

Idéalement, le fichier site.pp ne doit contenir que des lignes import (permettant d'importer les autres fichiers de configuration) et la définition des variables globales (nécessaire à plusieurs modules).

filebucket { 'main': server => 'puppet.nicolargo.com' }
File { backup => 'main' }

import "node"

Les deux premières lignes définissent les paramètres permettant aux client d'accéder au serveur de fichier PuppetMastert en indiquant notamment le nom FQDN du serveur Puppet (à adapter à votre configuration). Attention de bien vérifier que les machines clients arrive bien à résoudre le nom FQDN en question. La troisième ligne demande au serveur de prendre en compte tous les noeuds disponibles dans le fichier node.pp.

Définition de vos noeuds (machines clientes Puppet)

Nous allons utiliser le fichier node.pp pour définir les configurations à appliquer sur les machines clientes de notre réseau. Par exemple pour définir le noeud nommé optiplex790 (machine dont nous avons validés l'authentification dans le chapitre précédant) et y appliquer le module dummy, il faut éditer le fichier /etc/puppet/manifests/node.pp en y ajoutant les lignes suivantes:

node 'optiplex790' {
	include dummy
}

Le module dummy va être défini dans le paragraphe suivant.

Définition des modules (actions à appliquer sur les machines clientes Puppet)

Chaque module dispose de son propre répertoire sous /etc/puppet/modules/<module>. Ainsi on commence par créer l'arborescence du module dummy:

mkdir -p /etc/puppet/modules/dummy/manifests
mkdir -p /etc/puppet/modules/dummy/files

Le premier répertoire (manifests) va contenir la définition de l'action. Le second (files), les optionnels fichiers permettant d'effectuer cette action. On défini l'action dummy en créant le fichier /etc/puppet/modules/dummy/manifests/init.pp avec le contenu suivant:

class dummy {
        file { "/etc/puppet.txt":
                owner => root,
                group => root,
                mode => 644,
                source => "puppet:///dummy/puppet.txt"
        }
}

Le module dummy va donc vérifier:

  • l'existence sur la machine cliente d'un fichier /etc/puppet.txt
  • appartenant à l'utilisateur root
  • appartenant au groupe root
  • avec les droits 644
  • et dont le contenu doit être égal au fichier /etc/puppet/modules/dummy/files/puppet.txt disponible sur le serveur

Prise en compte de la nouvelle référence par le serveur

Pour que PuppetMaster prenne en compte al nouvelle référence que nous venons de définir, il faut relancer le démon avec la commande (en root ou avec sudo):

sudo service puppetmaster restart

Forcer la mise en configuration sur vos clients Puppet

Pour tester la configuration, nous allons lancer la commande suivante sur le noeud optiplex790 (machine sous Ubuntu 12.04):

sudo puppetd -t -v

Si vous rencontrez l'erreur suivante sur votre client:

err: Could not retrieve catalog from remote server: Error 400 on SERVER: No support for http method POST
warning: Not using cache on failed catalog
err: Could not retrieve catalog; skipping run

C'est probablement que vous utilisez une version du client Puppet supérieure à PuppetMaster (par exemple un Puppet client 2.7 avec un PuppetMaster 2.6). Un bug report est disponible ici. Avec la même version des deux cotés et si tout ce passe bien le message suivant devrait s'afficher:

info: Caching catalog for optiplex790
info: Applying configuration version '1346169168'
notice: /Stage[main]/Dummy/File[/etc/puppet.txt]/ensure: defined content as '{md5}1425249a5cbdea520b7a1a23f7bc2153'
info: Creating state file /var/lib/puppet/state/state.yaml
notice: Finished catalog run in 0.64 seconds

Dans le cas ou tout se passe correctement, vous devriez alors trouver un nouveau fichier puppet.txt  dans votre répertoire /etc:

$ ll /etc/puppet.txt
-rw-r--r-- 1 root root 35 août  29 15:02 /etc/puppet.txt

Ne pas réinventer la roue...

Maintenant que vous avez les bases permettant d'associer des actions à des machines, seule votre imagination vous posera des limites. Cependant, avant de partir bille en tête dans le développement de nouveaux modules, je vous conseille de regarder du coté de la Forge Puppet qui est un site communautaire permettant de partager, rechercher et récupérer des modules pour un nombre très important de cas. C'est également un très bon moyen d'apprendre le langage utilisé par Puppet en récupérant et lisant le code des modules.

 

Pensez également à partager vos modules !

En cas de problèmes...

Si vous rencontrez un problème lors de la configuration de votre Puppet Master, le plus simple est d'ouvrir une console et de surveiller la log des demons en filtrant un peu la sortie:

serveur$ tail -f /var/log/daemon.log | grep puppet

et de lancer la commande coté client en mode debug:

client$ sudo puppetd -t -v -d

Conclusion

Nous venons donc de faire nos premiers pas dans le très compl[et|exe] monde de Puppet. L'investissement nécessaire à l'administrateur est à la hauteur du gain de temps, de traçabilité et d'efficacité qu'il obtiendra en fin de projet.

A très vite pour la suite des billets sur Puppet !

Partager ce billet