HowTo Puppet : Administration et industrialisation de masse

1 June 2011 | par | tuto, unix

Jun
01

puppet

Il y a quelques semaines,  j’ai étais confronté à une problématique assez basique et pourtant ignoré jusque là. On m’a demandé d’exécuter un script sur quelque 300 machines *nix et de parser deux fichiers HTML générés. Jusqu’ici, c’est un travail d’admin système de base. Or voilà, moi, j’ai 300 machines réparties sur des réseaux qui sont HERMETIQUEMENT fermés de ma station d’administration. Il a donc fallu scripter une partie et traiter l’autre manuellement en urgence.

 

Tout cela m’a fait me pencher sur des solutions de gestion de configurations et d’administration de masse. Parmi toutes ces solutions, j’ai retenu celles proposées par PuppetLabs (http ://www.puppetlabs.com/). La suite de trois outils est infaillible :

  1. Puppet permettant la gestion centralisée des services et configurations
  2. MCollective qui permet l’administration et l’exécution de commandes centralisé
  3. Facter qui permet de dresser une véritable fiche d’identité du server

 

Aujourd’hui je vous propose une petite initiation à Puppet et quelques tips qui vous feront gagner du temps.

Prérequis :

  • Deux machines (OSEF de l’unix, ici il y aura une Debian 6 et une FreeBSD 8.2)
  • Une liaison sur le port 8140 (port de communication Puppet) entre les deux

 

Installation du Server (Puppet Master) :

Le serveur  tournera ici sous Debian 6. Pour installer, le très habituel :

aptitude install puppetmaster

Une fois installer, il faut éditer le fichier fileserver.conf qui permet d’autoriser l’accès aux dépôt de fichier Puppet. Pour cela, voici la syntaxe :

[files]
  #Chemin du partage
  path /etc/puppet/files
  #Machines autorisés
  allow *.madeinsyria.fr
  #Ici tout les réseau en 192.168.X.X sont autorisés.
  allow 192.168.0.0/16

 

Il faut aussi créer le fichier /etc/puppet/puppet.conf et y ajouter :

[master]
  certname=puppet.madeinsyria.fr

La valeur de certname est celle du hostname de la machine (obtenu via la commande « hostname »).

Pour finir, il faut éditer le fichier /etc/hosts/ afin de spécifier les noms et IP des machines clientes (à supposer que leur noms ne peut être résolu via DNS).

A ce niveau, je préconise un bon reboot de la machine. En effet, un simple restart ne prend pas très bien en compte le certname. Or cela peut devenir un gros problème, car comme nous allons le voir, les certificats permettant de communiquer ne pourront pas être transmis.

Installation du client (Puppet Agent) :

A ce niveau rien d’extraordinaire. On déploie l’agent Puppet avec un classique (oui, mon client est une FreeBSD) :

pkg_add –r puppet

Le paquet est installé et un fichier de configuration /usr/local/etc/puppet/puppet.conf est généré. Je conseil de le vider entièrement et de remplacer son contenu par :

[puppetd]
  server=FQDN-DU-SERVER-PUPPET
 
[main]
  logdir = /var/puppet/log
  vardir = /var/puppet
  ssldir = /var/puppet/ssl
  rundir = /var/run/puppet
  factpath = /var/puppet/lib/facter:/var/puppet/facts
  templatedir = /var/puppet/templates

En effet, par défaut le fichier contient TOUS les éléments de configuration aussi bien pour la partie cliente que serveur. Et comme je suis gentil comme tout, voici la même chose pour Debian :

[puppetd]
  server=FQDN-DU-SERVER-PUPPET
 
[main]
  logdir=/var/log/puppet
  vardir=/var/lib/puppet
  ssldir=/var/lib/puppet/ssl
  rundir=/var/run/puppet
  factpath=$vardir/lib/facter
  templatedir=$confdir/templates

Initialisation de la relation entre le maitre et l’agent :

Puppet utilise le chiffrement SSL pour ses communications sur le port 8140. Or qui dit SSL, dit certificats. Le server maitre sera en fait une autorité de certification et permettra de délivrer des certificats aux agents. Ce processus se déroule en deux parties :

  1. L’agent demande un certificat via un CSR
  2. Le maitre signe le client

Pour faire la demande du coté de l’agent, il suffit de taper la commande :

root@OAF-PRJ-SYSLOG:~# puppet agent --test
info: Creating a new SSL key for oaf-prj-syslog.madiensyria.fr
warning: peer certificate won't be verified in this SSL session
info: Caching certificate for ca
warning: peer certificate won't be verified in this SSL session
warning: peer certificate won't be verified in this SSL session
info: Creating a new SSL certificate request for oaf-prj-syslog.madiensyria.fr
info: Certificate Request fingerprint (md5): 8A:03:E3:57:53:8B:91:FC:89:61:B8:A0:E0:F4:F0:EC
warning: peer certificate won't be verified in this SSL session
warning: peer certificate won't be verified in this SSL session
warning: peer certificate won't be verified in this SSL session
Exiting; no certificate found and waitforcert is disabled

Cette commande est celle que vous utiliserez le plus. Elle permet de demander un update manuel coté serveur. Si le client n’a pas de certificat, il demandera par la même son certificat.

Coté maitre, il ne reste plus qu’à signer le client. Pour visualiser les demandes en cours, il faut faire :

root@puppet:~# puppetca --list
oaf-prj-syslog.madiensyria.fr

Puis pour signer le client :

root@puppet:~# puppetca --sign --all
notice: Signed certificate request for oaf-prj-syslog.madiensyria.fr
notice: Removing file Puppet::SSL::CertificateRequest oaf-prj-syslog.madiensyria.fr at '/etc/puppet/ssl/ca/requests/oaf-prj-syslog.madiensyria.fr.pem'

Pour finir, l’agent va récupérer son certificat :

root@OAF-PRJ-SYSLOG:~# puppet agent --test
warning: peer certificate won't be verified in this SSL session
info: Caching certificate for oaf-prj-syslog.madiensyria.fr
info: Caching certificate_revocation_list for ca
info: Caching catalog for oaf-prj-syslog.madiensyria.fr
info: Applying configuration version '1306778426'
notice: Finished catalog run in 0.23 seconds

Après la configuration, un petit déploiement test :

Un exemple Puppet, est le déploiement NTP. Ce service si simple et pourtant crucial est l’exemple parfait du service à industrialiser et maitriser. Nous allons donc voir comment configurer tout ça.

Création du module :

D’un point de vu Puppet, le NTP ne sera qu’un simple module. Je ne vais pas entrer dans le détail de la structure des modules Puppet, c’est assez complexe d’un point de vu hiérarchique (mais simple fonctionnellement parlant). Pour plus d information sur le sujet, il existe : http://docs.puppetlabs.com/learning/modules1.html.

Dans un premier temps j’ajoute la commande suivante qui me permettra de créer toute l’arborescence d’un module en une commande à mon .bashrc :

mkmod() {     
     mkdir "$1"     mkdir "$1/files" "$1/lib" "$1/manifests" "$1/templates" "$1/tests" 
               }

Je me rends par la suite dans /etc/puppet/modules/ ou je crée ma hiérarchie de module avec ma nouvelle commande :

root@puppet:/etc/puppet/modules# mkmod ntp

Puis je crée le fichier de module en lui-même (une class Puppet) dans le sous répertoire manifests avec un nom de fichier init.pp :

root@puppet:/etc/puppet/modules# cd ntp/manifests
root@puppet:/etc/puppet/modules/ntp/manifests # vim init.pp
class ntp {
    #En fonction de l’OS, je defini des paramètres spécifiques
    case $operatingsystem {
        freebsd: {
            $service_name = 'ntpd'
            $conf_file = 'ntp.conf.bsd'
            $ntppath = '/etc/ntp/ntp.conf'
        }
        debian: {
            $service_name = 'ntp'
            $conf_file = 'ntp.conf.debian'
            $ntppath = '/etc/ntp.conf'
       }
    }
    #Je m’assure que le service NTP est installé sur la machine
    package { 'ntp':
        ensure => installed,
    }
    #Je m’assure que le service tourne, mais uniquement si le fichier ntp.conf est dispo
    service { 'ntp':
        name => $service_name,
        ensure => running,
        enable => true,
        subscribe => File['ntp.conf'],
     }
     #Je m’assure que ntp.conf existe, mais seulement si le service NTP est installé
     file { 'ntp.conf': 
         path => $ntppath,
         ensure => file,
         require => Package['ntp'],
         #Le fichier est récupérable dans : /etc/puppet/modules/ntp/files/
         source => "puppet:///modules/ntp/${conf_file}",
      }
}

En cadeau, mon fichier NTP de démo à placer dans /etc/puppet/modules/ntp/files/ :

root@puppet:~# cat /etc/puppet/modules/ntp/files/ntp.conf.bsd
serveur time.intrinsec.com
driftfile /var/db/ntp.drift

Il ne reste plus qu’à utiliser cette classe en l’appelant dans les fichiers de base de Puppet à savoir :

  1. /etc/puppet/manifests/modules.pp qui contient tout les modules utilisables
  2. /etc/puppet/manifests/nodes.pp qui contient tout les agents et leur configuration
  3. /etc/puppet/manifests/site.pp qui fait appel à nodes.pp et modules.pp

 
Voici donc le contenu de modules.pp :

root@puppet:/etc/puppet/manifests# cat modules.pp
import "ntp"

Celui de nodes.pp :

root@puppet:/etc/puppet/manifests# cat nodes.pp
#n défini un ensemble de service de base
node basenode {
    include ntp
}
 
#Et on fait hérité mon agent de cet configuration
node 'oaf-prj-syslog.madeinsyria.fr' inherits basenode {
}
 
#Tout les agents non cité auront la configuration du default
node default inherits basenode {
}

Pour finir, on appel tout le monde dans site.pp :

root@puppet:/etc/puppet/manifests# cat site.pp
import "modules.pp"
import "nodes.pp"

Déploiement :

Tout ce beau monde est prêt à déployer, alors testons tout cela ! Sur le client, executons notre commande magique :

root@OAF-PRJ-SYSLOG:~# puppet agent --server puppet.madeinsyria.fr --test
warning: peer certificate won't be verified in this SSL session
info: Caching certificate for oaf-prj-syslog.madiensyria.fr
info: Caching certificate_revocation_list for ca
info: Caching catalog for oaf-prj-syslog.madiensyria.fr
info: Applying configuration version '1306778426'
notice: /Stage[main]/Ntp/Package[ntp]/ensure: ensure changed 'purged' to 'present'
--- /etc/ntp.conf       2010-10-17 15:35:26.000000000 +0200
+++ /tmp/puppet-file20110601-1931-glkc6r-0          2011-06-01 15:28:22.000000000 +0200
@@ -1,55 +1,2 @@
-# /etc/ntp.conf, configuration for ntpd; see ntp.conf(5) for help
-
+serveur time.intrinsec.com
driftfile /var/lib/ntp/ntp.drift
-
-
-# Enable this if you want statistics to be logged.
-#statsdir /var/log/ntpstats/
-
-statistics loopstats peerstats clockstats
-filegen loopstats file loopstats type day enable
-filegen peerstats file peerstats type day enable
-filegen clockstats file clockstats type day enable
-
-
-# You do need to talk to an NTP server or two (or three).
-#server ntp.your-provider.example
-
-# pool.ntp.org maps to about 1000 low-stratum NTP servers.  Your server will
-# pick a different set every time it starts up.  Please consider joining the
-# pool: <http://www.pool.ntp.org/join.html>
-server 0.debian.pool.ntp.org iburst
-server 1.debian.pool.ntp.org iburst
-server 2.debian.pool.ntp.org iburst
-server 3.debian.pool.ntp.org iburst
-
-
-# Access control configuration; see /usr/share/doc/ntp-doc/html/accopt.html for
-# details.  The web page <http://support.ntp.org/bin/view/Support/AccessRestrictions>
-# might also be helpful.
-#
-# Note that "restrict" applies to both servers and clients, so a configuration
-# that might be intended to block requests from certain clients could also end
-# up blocking replies from your own upstream servers.
-
-# By default, exchange time with everybody, but don't allow configuration.
-restrict -4 default kod notrap nomodify nopeer noquery
-restrict -6 default kod notrap nomodify nopeer noquery
-
-# Local users may interrogate the ntp server more closely.
-restrict 127.0.0.1
-restrict ::1
-
-# Clients from this (example!) subnet have unlimited access, but only if
-# cryptographically authenticated.
-#restrict 192.168.123.0 mask 255.255.255.0 notrust
-# If you want to provide time to your local subnet, change the next line.
-# (Again, the address is an example only.)
-#broadcast 192.168.123.255
-# If you want to listen to time broadcasts on your local subnet, de-comment the
-# next lines.  Please do this only if you trust everybody on the network!
-#disable auth
-#broadcastclient
info: FileBucket adding /etc/ntp.conf as {md5}3e250ecaf470e1d3a2b68edd5de46bfd
info: /Stage[main]/Ntp/File[ntp.conf]: Filebucketed /etc/ntp.conf to puppet with sum 3e250ecaf470e1d3a2b68edd5de46bfd
notice: /Stage[main]/Ntp/File[ntp.conf]/content: content changed '{md5}3e250ecaf470e1d3a2b68edd5de46bfd' to '{md5}9b52a60a69ca6c82e9c8fdb96458e7cb'
info: /Stage[main]/Ntp/File[ntp.conf]: Scheduling refresh of Service[ntp]
notice: /Stage[main]/Ntp/Service[ntp]: Triggered 'refresh' from 1 events
notice: Finished catalog run in 1.13 seconds
 
root@OAF-PRJ-SYSLOG:~# /etc/init.d/ntp status
NTP server is running.
 
root@OAF-PRJ-SYSLOG:~# cat /etc/ntp.conf 
serveur time.intrinsec.com
driftfile /var/lib/ntp/ntp.drift

C’est gagné et en moins de 2 seccondes ! Je posterai sous peu plein de classes de base pour déployer des Apache, PHP5, MySQL (et MySQL Cluster), NTP, etc.

J’espère que vous voyez mieux le potentiel d’une telle solution ! Pour info, j’ai déployé via Puppet un LAMP configuré et optimisé en 34 secondes…

N’hésitez à poser des questions ou à commenter si vous rencontrer des problèmes

 

No related posts.

Rédigé par

IT pro et passionné d'UNIX âgé de 22 ans, je cherche à partager quelques points de vu et mon savoir faire. N'hésitez pas à laisser un commentaire ou votre avis, ça enrichira le débat !

4 réponses to “HowTo Puppet : Administration et industrialisation de masse”

Afficher / Masquer les commentaires
  1. chishy says:

    passionant c que tu viens de dire là … moi mon travail s’intitule “Administration centralisée et automatisée ” et comme application j’hésite entre puppet et cfengine mais je crois que je prefère puppet parce que j’ai pu implémenter son interface web(puppet-dashboard) mais je veux demander si tu peux m’aider à réaliser un déployement des configurations optimisées sur mes marionnettes(serveurs apache) comme tu l’a fais avec le ntp mais avec plus de details??parce que j’ai pas trop d’idées. Merci

  2. Julian says:

    Super ton HowTo !
    Dommage que j’ai pas ca à faire ca m’aurait “boté” (oui jeux de mots) en tout cas trés bonnes explications comme toujours sur ton blog ! Continue comme ca ^^

  3. [...] : les classes Puppet (le tuto puppet est déjà disponible : http://madeinsyria.fr/2011/06/howto-puppet-administration-et-industrialisation-de-masse/ [...]

Laisser un commentaire