Puppet

Puppet permet de centraliser et de simplifier l’administration de plusieurs serveurs. Notamment, on peut diffuser des modifications des fichiers de configuration, lister des paquets qui devront être installés sur les serveurs esclaves, …

Ce tutoriel est tenu à jour régulièrement. Dernière révision : 18 octobre 2016.

Installation du serveur maître

Configuration de base

Par défaut, les serveurs clients s’attendent à communiquer avec un hôte « puppet ». Il est donc recommandé de placer un CNAME vers le système où vous avez installé le serveur maître (que ce système soit une machine physique, une VM ou un VE). Ce CNAME doit faire partie du premier réseau mentionné dans la ligne search de vos /etc/resolv.conf. C’est-à-dire que si votre ligne search comporte plusieurs réseaux, il faut placer en premier celui par lequel maître et clients se verront. De plus, si vous avez une ligne domain, il faut la placer avant la ligne search.

Par exemple, chez moi ça donne :

# /etc/resolv.conf on MainServer.lxc
domain lxc
search lxc almin.tf domain.net
nameserver 192.168.Y.Z

Le CNAME puppet se trouvant dans le réseau lxc.

Ensuite on installe puppet :

# apt-get install puppetmaster

Dans le fichier /etc/puppet/fileserver.conf, il faut autoriser l’accès pour les systèmes de votre réseau local.

[files]
path /etc/puppet/files
allow *.lxc
allow *.almin.tf
allow Machine1.domain.net
[plugins]
allow *.lxc
allow *.almin.tf
allow Machine1.domain.net

Si vous comptez ajouter des systèmes clients qui ne sont dans le réseau local, il faut les lister (dans cet exemple, almin.tf et domain.net).

J’ai personnalisé la configuration du fichier /etc/puppet/puppet.conf.

[master]
certname=puppet
ca_server=MainServer.lxc
dns_alt_names=MainServer.lxc,puppet,puppet.lxc

Si vous faites de même, il faut signifier à Puppet qu’il doit regénérer un certificat avec les bonnes entrées DNS :

# rm -fr /var/lib/puppet/ssl
# puppet master --verbose --no-daemonize

La configuration de base du serveur maître est terminée. Il faut maintenant créer les manifestes, et aussi créer les fichiers modèles qui seront dupliqués sur les systèmes clients.

Les manifestes

Il faut commencer par éditer /etc/puppet/manifests/site.pp. Voici un exemple :

# /etc/puppet/manifests/site.pp on MainServer.lxc

Exec { path => "/usr/sbin:/sbin:/usr/bin:/bin" }

import "resolv"
import "ssh"
import "apt"
import "cron-apt"
import "local-bin"
import "zsh"
import "sudo"
import "vim"

node "MainServer.lxc" {
  include resolv-MainServer, ssh, apt-server-cacher-jessie,
  cron-apt, local-bin, zsh-server, sudo-MainServer, vim
}

class generic-ve-jessie {
  include resolv-ve, ssh-ve-jessie, apt-ve-cacher-jessie,
  cron-apt-nomail, zsh-ve, vim
}

node "DnsVE.lxc" {
  include resolv-DnsServer, ssh-ve-jessie, apt-ve-cacher-jessie,
  cron-apt-nomail, zsh-ve, vim
}
node "YetAnotherVE1.lxc" {
  include generic-ve-jessie
}
node "YetAnotherVE2.lxc" {
  include generic-ve-jessie
}

On constate plusieurs éléments :

  • on peut définir des manifestes pour chaque entité (ssh, apt, zsh, vim…) et ensuite les importer dans le fichier principal site.pp ;
  • Puppet gère les notions de classes et d’héritage ;
  • chaque système client a son nœud (node).

Dans cet exemple, je crée une classe « generic-ve-jessie », pour ne pas avoir à lister tous les manifestes nécessaires à chaque fois que je crée un nœud pour un VE. Je n’ai qu’à inclure cette classe quand je crée le nœud de YetAnotherVE1.lxc, et tous les manifestes que cette classe contient seront appliqués sur ce système.

Ensuite il faut créer les manifestes pour les différentes entités que vous souhaitez gérer via Puppet.

Voici un exemple basique pour Vim :

# /etc/puppet/manifests/vim.pp on MainServer.lxc
class vim {
  file { "/etc/vim/vimrc.local":
    owner => root,
    group => root,
    mode => 644,
    source => "puppet:///files/etc/vim/vimrc.local"
  }
}

Créez le fichier /etc/puppet/files/etc/vim/vimrc.local avec le contenu qui devra être dupliqué sur les systèmes clients. Incluez la classe vim dans les nœuds des systèmes clients concernés. Désormais, le fichier /etc/vim/vimrc.local sera créé sur les clients désignés s’il n’existait pas déjà, et le plus important, il sera automatiquement tenu à jour après chaque modification sur le maître.

Installation d’un client

On va voir comment installer Puppet sur un système client. Vous pourrez dupliquer cette procédure pour chaque système que vous voulez gérer avec Puppet.

Configuration de base sur le client

Sur les systèmes clients, /etc/resolv.conf doit être ordonné de la même façon que sur le serveur.

Ensuite éditez /etc/hosts pour rajouter, juste après l’IP via laquelle le maître verra le client, le FQDN local qui désigne ce client.

# /etc/hosts on YetAnotherVE1.lxc
127.0.0.1            localhost loopback
192.168.Y.Z          YetAnotherVE1.lxc YetAnotherVE1
::1                  localhost ip6-localhost ip6-loopback
ff02::1              ip6-allnodes
ff02::2              ip6-allrouters

Puis on installe puppet :

# apt-get install puppet

On l’active :

# puppet agent --enable

On génère le certificat du système client :

# puppet agent --test

Si tout se passe bien, alors le client puppet va trouver le serveur maître, générer son certificat et l’envoyer au maître. Et ensuite sur la console le client va nous répondre :

Exiting; no certificate found and waitforcert is disabled

On pourrait croire à une erreur, mais en fait ce message ambigu nous indique une bonne nouvelle : tout s’est bien passé, la configuration de base du client est terminée, on peut passer sur le serveur.

Configuration du nouveau client sur le serveur

Sur le serveur, la première chose à faire c’est de céer un manifeste pour le nouveau système client, de la manière qu’on a vue ci-dessus.

Puis listez les certificats en attente :

# puppet cert list

Vous devriez voir une ligne correspondant au nouveau système. Signez le certificat :

# puppet cert sign YetAnotherVE1.lxc

Retour sur le système client

Enfin, sur le système client, il ne vous reste plus qu’à faire :

# puppet agent --test -v

Et si tout s’est bien passé, vous allez voir défiler toutes les modifications requises pour ce système.

Opérations diverses

Tester des modifications de config

Sur un système client :

# puppet agent --test -v

Sur le serveur maître :

# puppet apply /etc/puppet/manifests/

Lister tous les certificats

Pour avoir la liste de tous les certificats stockés sur le serveur, faites :

# puppet cert list --all

Signer tous les certificats en attente

# puppet cert sign --all

Déterminer où est le manifeste

Si vous avez un doute sur le manifeste qui sera appliqué, faites :

# puppet config print manifest

Pour réinitialiser un système client

Sur le client :

# apt-get purge puppet-common
# rm -fr /var/lib/puppet

Sur le serveur :

# puppet cert clean YetAnotherVE1.lxc
# service puppetmaster restart

Puis suivez la procédure comme si vous ajoutiez un nouveau système client.

Bugs

Voici quelques problèmes que j’ai rencontré.

Révoquer un certificat non-signé

Si vous n’avez pas encore signé un certificat, et que pour une raison X vous décidez de le révoquer, Puppet va vous répondre :

Error: Could not find a serial number for YetAnotherVE1.lxc

Il faut signer un certificat avant de le révoquer…

# puppet cert sign YetAnotherVE1.lxc
# puppet cert clean YetAnotherVE1.lxc

Commentaires en français

Si vous décidez d’utiliser votre langue maternelle pour les commentaires dans les manifestes, et que cette langue contient des caractères qui ne font pas partie de la table ASCII, vous tomberez sur cette erreur :

Error: Could not retrieve catalog from remote server: Error 400 on SERVER: Could not parse for environment production: invalid byte sequence in US-ASCII at /etc/puppet/manifests/apt.pp:1 on node YetAnotherVE1.lxc

Après recherches et plusieurs workarounds testés sans succès, j’ai été obligé d’enlever les accents, donc de faire les commentaires en anglais.

, 10 juillet 2012. Catégorie: Système.

À propos de l’auteur, Almic