Configuration centralisée à l'aide de Puppet. Installation et préparation de Puppet pour le travail. Utiliser des expressions conditionnelles

  • Rubis
    • Tutoriel

    Bonjour.

    Cette rubrique ouvre une série d'articles sur l'utilisation du système de gestion de configuration Puppet.

    Qu'est-ce qu'un système de gestion de configuration ?

    Supposons que vous disposiez d'une flotte de serveurs qui effectuent diverses tâches. Même s'il existe peu de serveurs et que vous ne grandissez pas, vous pouvez facilement configurer chaque serveur manuellement. Installez le système d'exploitation (peut-être automatiquement), ajoutez des utilisateurs, installez des logiciels en entrant des commandes dans la console, configurez les services, modifiez les configurations de vos éditeurs de texte préférés (nanorc, vimrc), définissez les mêmes paramètres de serveur DNS sur eux, installez le système de surveillance. agent, configurez syslog pour une collecte centralisée des logs... Bref, il y a pas mal de travail et ce n'est pas particulièrement intéressant.

    Je crois sincèrement qu’un bon administrateur est un administrateur paresseux. Il n'aime pas faire quelque chose plusieurs fois. La première pensée est d'écrire quelques scripts dans lesquels il y aura quelque chose comme :

    Serveurs.sh
    serveurs="server00 server01 server02 server03 server04" pour le serveur dans $servers ; faire scp /path/to/job/file/job.sh $server:/tmp/job.sh ssh $server sh /tmp/job.sh done

    Job.sh
    #!/bin/bash apt-get update apt-get installer le service nginx nginx start

    Tout semblait facile et bon. Nous devons faire quelque chose - nous écrivons un nouveau script et le lançons. Les modifications arrivent sur tous les serveurs de manière séquentielle. Si le script est bien débogué, tout ira bien. Pour l'instant.

    Imaginez maintenant qu'il y ait plus de serveurs. Par exemple, une centaine. Et le changement prend beaucoup de temps - par exemple, assembler quelque chose de grand et d'effrayant (par exemple, un noyau) à partir du code source. Le scénario prendra cent ans, mais ce n’est pas si mal.

    Imaginez que vous n'ayez besoin de le faire que sur un groupe spécifique de ces centaines de serveurs. Et deux jours plus tard, vous devez effectuer une autre tâche importante sur une autre section de serveurs. Vous devrez réécrire les scripts à chaque fois et vérifier plusieurs fois s'ils contiennent des erreurs, si cela posera des problèmes au démarrage.

    Le pire, c'est que dans des scripts comme celui-ci, vous décrivez actes, qui doit être effectué pour amener le système à un certain état, et non cet état lui-même. Cela signifie que si le système n'était initialement pas dans l'état auquel vous vous attendiez, tout ira certainement mal. Les manifestes de marionnettes décrivent de manière déclarative l'état requis du système, et calculer comment y accéder à partir de l'état actuel est la tâche du système de gestion de configuration lui-même.

    A titre de comparaison : un manifeste de marionnettes qui fait le même travail que quelques scripts du début du sujet :

    Nginx.pp
    classe nginx ( package ( "nginx": assurer => dernier ) service ( "nginx": assurer => en cours d'exécution, activer => vrai, exiger => Package["nginx"] ) ) nœud /^server(\d+)$ / (inclure nginx)
    Si vous utilisez correctement vos serveurs et passez du temps à configurer initialement votre système de gestion de configuration, vous pouvez amener votre flotte de serveurs dans un état tel que vous n'avez pas besoin de vous y connecter pour effectuer le travail. Toutes les modifications nécessaires leur seront envoyées automatiquement.

    Qu’est-ce que la marionnette ?

    Puppet est un système de gestion de configuration. L'architecture est client-serveur, les configurations sont stockées sur le serveur (en termes fantoches, elles sont appelées manifestes), les clients contactent le serveur, les reçoivent et les appliquent. Puppet est écrit en langage Ruby, les manifestes eux-mêmes sont écrits dans un DSL spécial, très similaire à Ruby lui-même.

    Premiers pas

    Oublions les clients, les serveurs, leurs interactions, etc. Supposons que nous n'ayons qu'un seul serveur sur lequel un système d'exploitation nu est installé (ci-après, je travaille sous Ubuntu 12.04, pour les autres systèmes, les actions seront légèrement différentes).

    Tout d’abord, installons la dernière version de Puppet.

    Wget http://apt.puppetlabs.com/puppetlabs-release-precise.deb dpkg -i puppetlabs-release-precise.deb apt-get update apt-get install puppet puppetmaster

    Incroyable. Maintenant, nous avons installé Puppet sur notre système et nous pouvons jouer avec.

    Bonjour le monde!
    Créons le premier manifeste :

    /tmp/helloworld.pp
    fichier ( "/tmp/helloworld": assurer => présent, contenu => "Bonjour tout le monde !", mode => 0644, propriétaire => "root", groupe => "root" )
    Et appliquez-le :

    $ puppet apply helloworld.pp /Stage//File/ensure : créé Catalogue terminé exécuté en 0,06 seconde

    Un peu sur le lancement

    Les manifestes donnés dans cette rubrique peuvent être appliqués manuellement à l’aide de Puppet Apply. Cependant, dans les sujets suivants, la configuration maître-esclave (standard pour Puppet) sera utilisée pour le travail.


    Regardez maintenant le contenu du fichier /tmp/helloworld. Il contiendra (étonnamment !) la ligne « Hello, world ! », que nous avons spécifiée dans le manifeste.

    Vous pourriez dire que vous pourriez faire écho "Bonjour tout le monde !" > /tmp/helloworld , ce serait plus rapide, plus simple, vous n'auriez pas besoin de réfléchir, d'écrire des manifestes terribles et en général personne n'en a besoin, c'est en quelque sorte trop compliqué, mais réfléchissez-y plus sérieusement. En fait, vous devrez écrire touch /tmp/helloworld && echo "Hello, world!" > /tmp/helloworld && chmod 644 /tmp/helloworld && chown root /tmp/helloworld && chgrp root /tmp/helloworld pour garantir le même résultat.

    Examinons ligne par ligne ce qui est exactement contenu dans notre manifeste :

    /tmp/helloworld.pp
    file ( "/tmp/helloworld": Ensure => présent, # le fichier doit exister content => "Hello, world!", # le contenu du fichier doit être la chaîne "Hello, world!" mode => 0644, # autorisations de fichier - 0644 propriétaire => "root", # propriétaire du fichier - groupe racine => "root" # groupe de fichiers - racine )

    Décrit ici en termes de marionnettes ressource taper déposer avec titre /tmp/bonjour le monde.

    Ressources
    Une ressource est la plus petite unité d’abstraction dans Puppet. Les ressources peuvent être :
    • fichiers;
    • packages (Puppet prend en charge les systèmes de packages de nombreuses distributions) ;
    • services;
    • les utilisateurs ;
    • groupes;
    • tâches périodiques ;
    • etc.
    Vous pouvez consulter la syntaxe des ressources sans aucune restriction.

    Puppet vous permet d'ajouter vos propres ressources. Par conséquent, si vous êtes vraiment confus, vous pouvez vous retrouver avec des manifestes tels que :

    Serveur Web.pp
    inclure le serveur Web ; webserver::vhost ( "exemple.com": assurer => présent, taille => "1G", php => faux, https => vrai )
    Puppet créera un volume logique de 1 Gio sur le serveur, le montera là où il devrait être (par exemple, dans /var/www/example.com), ajoutera les entrées nécessaires à fstab, créera les hôtes virtuels nécessaires dans nginx et apache, redémarrez les deux démons, ajoutez l'utilisateur example.com à ftp et sftp avec le mot de passe mySuperSecretPassWord avec un accès en écriture à cet hôte virtuel.

    Savoureux? Mauvais mot !

    D’ailleurs, le plus délicieux, à mon avis, n’est pas l’automatisation de la routine. Si, par exemple, vous êtes un idiot et réinstallez constamment vos serveurs en production, Puppet vous permettra de récupérer l'ancien ensemble de packages et de configurations créés avec amour à partir de zéro, en mode entièrement automatique. Vous installez simplement l'agent Puppet, le connectez à votre maître Puppet et attendez. Tout viendra tout seul. Les packages apparaîtront comme par magie (non, vraiment par magie !) sur le serveur, vos clés ssh seront décomposées, un pare-feu sera installé, des paramètres bash et réseau individuels arriveront, tous les logiciels que vous avez judicieusement installés à l'aide de Puppet seront installés et configurés. .
    De plus, Puppet, avec diligence, vous permet d'obtenir un système d'auto-documentation, car la configuration (manifestes) elle-même constitue l'épine dorsale de la documentation. Ils sont toujours à jour (ils fonctionnent déjà), ils ne contiennent aucune erreur (vous vérifiez vos paramètres avant de lancer), ils sont peu détaillés (ça marche).

    Un peu plus de magie

    Un peu sur la distribution croisée

    Puppet a la capacité d'utiliser des manifestes de distribution croisée, c'est l'un des objectifs pour lesquels il a été créé. Je ne l’ai jamais utilisé intentionnellement et je ne vous le recommande pas. Le parc de serveurs doit être le plus homogène possible en termes de logiciel système ; cela permet de ne pas penser aux moments critiques : « Ayblin, ici
    rc.d, pas init.d" (un clin d'œil à ArchLinux) et vous permet généralement de moins penser aux tâches de routine.

    De nombreuses ressources dépendent d’autres ressources. Par exemple, pour la ressource « service sshd », vous avez besoin de la ressource « package sshd » et éventuellement « config sshd »
    Voyons comment cela est implémenté : file ( "sshd_config": path => "/etc/ssh/sshd_config", Ensure => file, content => "Port 22 Protocol 2 HostKey /etc/ssh/ssh_host_rsa_key HostKey /etc/ssh / ssh_host_dsa_key HostKey /etc/ssh/ssh_host_ecdsa_key UsePrivilegeSeparation oui KeyRegenerationInterval 3600 ServerKeyBits 768 SyslogFacility AUTH LogLevel INFO LoginGraceTime 120 PermitRootLogin oui StrictModes oui RSAAuthentication oui PubkeyAuthentication oui IgnoreRhosts oui RhostsRSAAuth entication non Authentification non PermitEmptyPasswords non ChallengeResponseAuthentication non X11Forwarding oui X11DisplayOffset 10 PrintMotd non PrintLastLog oui TCPKeepAlive oui AcceptEnv LANG LC_* Sous-système sftp /usr/lib/openssh/sftp-server UsePAM yes", mode => 0644, propriétaire => racine, groupe => racine, require => Package["sshd"] ) package ( "sshd" : assurer => dernier, nom => "openssh-server" ) service ( "sshd": assurer => en cours d'exécution, activer => vrai, nom => "ssh" s'abonner => Fichier["sshd_config"], require => Paquet[ "sshd"])

    Cela utilise une configuration en ligne, ce qui rend le manifeste laid. En réalité, cela n'est presque jamais fait, il existe un moteur de création de modèles basé sur ERB et la possibilité d'utiliser uniquement des fichiers externes. Mais ce n'est pas cela qui nous intéresse.

    Les lignes les plus délicieuses ici sont les lignes de dépendance - exiger et s'abonner.

    Puppet prend en charge de nombreuses options pour décrire les dépendances. Comme toujours, vous pouvez lire en détail dans


    Auteur : Luke Kanies
    Date de publication : 2 mai 2012
    Traduction : A. Panin
    Date de traduction : 27 août 2013

    18.1. Introduction

    Puppet est un outil de gestion d'infrastructure informatique développé à l'aide du langage de programmation Ruby et utilisé pour automatiser la maintenance des centres de données et la gestion des serveurs pour Google, Twitter, la Bourse de New York et de nombreuses autres organisations. Le développement du projet est principalement soutenu par l'organisation Puppet Labs, qui a jeté les bases de son développement. Puppet peut gérer de 2 à 50 000 serveurs et être maintenu par une équipe composée d'un ou de centaines d'administrateurs système.

    Puppet est un outil conçu pour configurer et entretenir vos ordinateurs ; Grâce à son langage de configuration simple, vous pouvez indiquer à Puppet comment vous souhaitez configurer vos machines, et il les reconfigurera si nécessaire pour répondre à vos spécifications. Au fur et à mesure que vous modifiez cette spécification au fil du temps en raison de circonstances telles que des mises à jour de packages, l'ajout de nouveaux utilisateurs ou des mises à jour de configuration, Puppet mettra automatiquement à jour la configuration de vos machines pour qu'elle corresponde à la spécification. S'ils sont déjà correctement configurés, Puppet ne fera aucun travail.

    En général, Puppet fait tout son possible pour utiliser les fonctionnalités d'un système existant pour faire son travail ; c'est-à-dire que sur les distributions basées sur les technologies RedHat, il utilisera l'utilitaire yum pour gérer les packages et init.d pour gérer les services, tandis que sur OS X, il utilisera l'utilitaire dmg pour gérer les packages et launchd pour gérer les services. L'un des objectifs fondamentaux du projet Puppet est de produire un travail utile, que ce soit en utilisant le code du projet Puppet ou le système lui-même, les normes système suivantes sont donc essentielles.

    Le projet Puppet a été construit sur la base de l’expérience acquise avec de nombreux autres outils. Dans le monde des applications open source, les plus grandes influences sur son développement ont été le projet CFEngine, qui fut le premier outil de configuration open source à usage général, et le projet ISconf, qui utilisait l'utilitaire make pour effectuer tout le travail, ce qui à son tour conduisait à un accent particulier sur les dépendances explicitement décrites dans le système. Dans le monde des logiciels commerciaux, Puppet peut être considéré comme un concurrent des projets BladeLogic et Opsware (qui ont ensuite été acquis par de plus grandes entreprises), dont chacun se vendait bien lors de l'introduction de Puppet, mais chacun de ces outils a été vendu à des dirigeants de grandes entreprises, au lieu d'être développé en conséquence avec des exigences directes en matière d'outils de qualité pour les administrateurs système. Le but du projet Puppet était de résoudre des problèmes similaires à ceux résolus par ces outils, alors qu'il était destiné à des utilisateurs complètement différents.

    À titre d'exemple simple d'utilisation de Puppet, voici un extrait de code pour garantir que le service Secure Shell (SSH) est installé et configuré correctement : class ssh ( package ( ssh: assurer => installé ) file ( "/etc/ssh /sshd_config ": source => "puppet:///modules/ssh/sshd_config", Ensure => présent, require => Package ) service ( sshd: Ensure => en cours d'exécution, require => , Package] ) )

    Ce code vous permet d'être sûr que le package sera installé, que le fichier sera placé à l'emplacement requis et que le service sera démarré. Il convient de noter que nous avons décrit les dépendances entre les ressources, nous effectuerons donc toujours tout travail dans le bon ordre. Cette classe peut être associée à n'importe quel nœud pour appliquer une configuration donnée au sein de ce nœud. Notez que les éléments de base de la configuration de Puppet sont des objets structurés, dans ce cas les objets package , file et service. Dans la terminologie Puppet, nous appelons ces objets ressources ( ressources) et toutes les spécifications de configuration de Puppet se composent de ces ressources et des dépendances entre elles.

    Une installation normale de Puppet contiendra des dizaines, voire des centaines de ces morceaux de code, que nous appelons classes ( cours); Nous stockons ces classes sur le disque dans des fichiers appelés manifestes, et nous regroupons également les classes logiquement liées dans des groupes appelés modules ( modules). Par exemple, vous pourriez avoir un module ssh avec cette classe ssh et toute autre classe logiquement liée, ainsi que les modules mysql, apache et sudo.

    La plupart des interactions avec Puppet se font à l'aide du shell de commande ou en exécutant des services HTTP, mais il existe également des interfaces graphiques pour effectuer des tâches telles que le traitement des rapports. Puppet Labs propose également des produits logiciels commerciaux Puppet qui utilisent des interfaces graphiques Web.

    Le premier prototype de Puppet a été développé à l'été 2004 et le développement complet du projet a commencé en février 2005. Il a été initialement conçu et développé par Luke Kanies, un administrateur système possédant une vaste expérience dans le développement de petits outils, mais aucune expérience dans le développement de projets contenant plus de 10 000 lignes de code. Essentiellement, Luke Kanies a acquis des compétences en programmation au cours du développement du projet Puppet, ce qui a affecté l'architecture du projet à la fois positivement et négativement.

    Puppet a été développé initialement et principalement comme un outil permettant aux administrateurs système de leur faciliter la vie, leur permettant de faire leur travail plus rapidement, plus efficacement et avec moins d'erreurs. La première innovation clé pour mettre en œuvre ce principe a été les ressources décrites ci-dessus, qui sont des primitives Puppet ; ils peuvent être transférés entre les systèmes d'exploitation tout en représentant les détails de mise en œuvre de manière abstraite, permettant à l'utilisateur de réfléchir aux résultats du travail plutôt qu'à la manière de les atteindre. Cet ensemble de primitives a été implémenté au niveau de la couche d'abstraction des ressources de Puppet.

    Les ressources Puppet doivent être uniques à un nœud donné. Vous ne pouvez avoir qu'un seul package nommé "ssh", un service nommé "sshd" et un fichier nommé "/etc/ssh/sshd_config". Cette limitation évite les conflits mutuels entre différentes parties de vos configurations et vous en prenez conscience dès le début du processus de configuration. Nous faisons référence à ces ressources par leurs types et leurs noms, c'est-à-dire Package et Service. Vous pouvez avoir un package et un service portant le même nom car ils sont de types différents, mais pas deux packages ou services portant le même nom.

    La deuxième innovation clé de Puppet est la possibilité de spécifier directement les dépendances entre les ressources. Les outils précédemment utilisés visaient à effectuer des tâches individuelles sans tenir compte des relations entre ces tâches ; Puppet a été le premier outil à indiquer explicitement que les dépendances sont un élément fondamental de vos configurations, qui doivent à leur tour être modélisées en conséquence. Il a créé un graphe de ressources et de leurs dépendances comme l'un des principaux types de données, et presque toutes les actions de Puppet dépendaient de ce graphe (appelé catalogue), de ses sommets et de ses arêtes.

    Le dernier composant important de Puppet est le langage de configuration. Ce langage est déclaratif et est davantage destiné à décrire la configuration qu'à une programmation à part entière - il reprend presque entièrement le format de configuration Nagios, mais a également été créé sous l'influence significative des langages de CFEngine et Ruby.

    Les composants fonctionnels de Puppet reposent sur deux principes directeurs : il doit être aussi simple à utiliser que possible, en donnant la priorité à la convivialité plutôt qu'aux fonctionnalités ; et il doit également être développé sous la forme d'un framework d'abord et d'une application ensuite. Ainsi, s'ils le souhaitent, les développeurs tiers auront la possibilité de créer leurs applications basées sur des composants logiciels Puppet. Il était clair qu'en plus du framework, il fallait également une application largement utilisée et de haute qualité, mais la première priorité des développeurs restait le framework, et non l'application. Beaucoup de gens croient encore que Puppet est l'application elle-même, et non le framework sur lequel elle est implémentée.

    Après avoir construit son premier prototype de Puppet, Luke est devenu un bon développeur Perl avec une certaine expérience en matière de script shell et une certaine expérience en C, principalement acquises en travaillant avec le système CFEngine. De plus, il avait de l'expérience dans la construction de systèmes d'analyse pour des langages simples, ayant développé deux de ces systèmes pour fonctionner dans de petits outils et redéveloppant le système d'analyse CFEngine à partir de zéro pour le rendre plus facile à maintenir (ce code n'a pas été transféré au projet). en raison d'incompatibilités mineures).

    La décision d'utiliser un langage dynamique pour implémenter Puppet a été prise assez rapidement en raison de la productivité nettement plus élevée du développeur et de la diffusion de ce type de langage, mais le choix lui-même s'est avéré assez difficile. Les premiers prototypes en Perl ont été rejetés, des expériences ont donc été menées pour trouver d'autres langages. Une tentative a été faite pour utiliser le langage Python, mais Luke a trouvé le langage très incompatible avec sa vision du monde. Après avoir entendu un ami parler des avantages du nouveau langage, Luke a essayé d'utiliser Ruby et a créé un prototype fonctionnel en quatre heures. Lorsque le développement à grande échelle de Puppet a commencé, le langage Ruby était pratiquement inconnu, la décision de l'utiliser était donc un gros risque, mais dans ce cas, la productivité des développeurs a encore une fois joué un rôle décisif dans le choix du langage. La principale caractéristique distinctive du langage Ruby, du moins de Perl, était la facilité de créer des relations de classe non hiérarchiques, tandis que le langage ne contredisait pas la pensée critique du développeur Luke.

    Lorsque le nombre de serveurs que vous gérez est inférieur à dix, on pense rarement à leur gestion centralisée, cela peut ne pas être nécessaire. Lorsqu’il existe des dizaines de serveurs, une gestion centralisée des logiciels et des configurations est extrêmement utile. Lorsqu’il y a des centaines et des milliers de serveurs, c’est vital. Il existe de nombreux programmes de ce genre, par exemple : Chef, CFEngine, ... C'est de ce dernier qui sera abordé dans ce post.

    Puppet est considéré comme l'une des meilleures solutions de ce type. Il est utilisé par des sociétés telles que Google, Citrix et Red Hat. Il s'agit d'une application client-serveur écrite dans le langage de programmation Ruby, distribuée en deux versions :

    • Puppet Open Source - version entièrement gratuite
    • Puppet Enterprise - gratuit jusqu'à 10 serveurs, puis licences requises

    Envisageons d'installer le serveur et l'agent Puppet Open Source, qui sont inclus dans les packages de la plupart des distributions modernes. Nous parlerons ensuite d'Ubuntu 12.04 Precise Pangolin.

    L'arrière-plan de Puppet s'appelle marionnettiste, commençons l'installation à partir de là :

    :~# apt-get install puppetmaster

    Et maintenant le client :

    :~# apt-get installer la marionnette

    Dans le fichier de configuration client /etc/puppet/puppet.conf vous devez parler du serveur en ajoutant la section suivante :

    Serveur=puppet.local report=true pluginsync=false

    Au stade initial, il est préférable de désactiver pluginsync.

    Exécutons le client Puppet pour qu'il crée une demande de certificat :

    :~# puppetd --verbose --test info : Création d'une nouvelle clé SSL pour linux.local info : Mise en cache du certificat pour ca info : Création d'une nouvelle demande de certificat SSL pour linux.local info : Empreinte digitale de demande de certificat (md5) : E5 : EA:AC:5B:22:9A:BA:42:B8:A1:63:9E:1F:1F:23:51 Sortie ; aucun certificat trouvé et waitforcert est désactivé

    Sur le serveur, vous devez vérifier que la demande de certificat a bien été reçue et, si oui, émettre un certificat :

    :~# puppetca --list "linux.local" (E5:EA:AC:5B:22:9A:BA:42:B8:A1:63:9E:1F:1F:23:51) :~# puppetca - -sign linux.local notice : demande de certificat signée pour linux.local notice : suppression du fichier Puppet::SSL::CertificateRequest linux.local à "/var/lib/puppet/ssl/ca/requests/linux.local.pem"

    Répétez l'étape précédente sur le client :

    :~# puppetd --verbose --test info : mise en cache du certificat pour les informations linux.local : récupération des informations sur le plugin : mise en cache de certificate_revocation_list pour les informations ca : mise en cache du catalogue pour les informations linux.local : application de la version de configuration "1356278451" informations : création du fichier d'état / Avis var/lib/puppet/state/state.yaml : exécution du catalogue terminée en 0,02 seconde

    Super, tout fonctionne. Passons à la création du premier manifeste. Les manifestes, ou configurations, sont décrits dans un langage déclaratif spécial. On s'habituera tout de suite aux bonnes choses, à utiliser une structure et des cours modulaires. Par exemple, écrivons un module qui maintiendra le fichier à jour /etc/hôtes sur tous nos serveurs.

    Vérifions où Puppet recherche les modules :

    :~# puppet apply --configprint modulepath /etc/puppet/modules:/usr/share/puppet/modules

    Créez des répertoires pour votre module

    :~# cd /etc/puppet/modules :~# hôtes mkdir ; hébergeurs de CD ; mkdir se manifeste ; manifestes cd

    Le premier manifeste, également appelé fichier du module principal, doit être appelé init.pp

    Hôtes de classe ( # puppet.local host ( "puppet.local": Ensure => "present", target => "/etc/hosts", ip => "192.168.0.1", host_aliases => "puppet", ) # hôte linux.local ("linux.local": assurer => "présent", cible => "/etc/hosts", ip => "192.168.0.2", host_aliases => "linux", ) )

    Par défaut, Puppet recherche un fichier /etc/puppet/manifests/site.pp pour charger la configuration, mettons-la sous la forme suivante :

    Nœud par défaut (inclure les hôtes)

    Nous vérifions le manifeste sur le serveur :

    :~# puppet apply --verbose /etc/puppet/manifests/site.pp info : Application de la version de configuration "1356281036" avis : /Stage//Host/ensure : information créée : FileBucket ajoutant (md5)avis : /Stage// Héberger/assurer : avis créé : exécution du catalogue terminé en 0,03 seconde

    Sur le client :

    :~# ll /etc/hosts rw-r--r-- 1 root root 290 16 décembre 19:10 /etc/hosts :~# puppetd --verbose --test info : catalogue de mise en cache pour linux.local info : application version de configuration "1356283380" informations : ajout de FileBucket (md5)avis : /Stage/Hosts/Host/ensure : avis créé : /Stage/Hosts/Host/ensure : avis créé : catalogue terminé exécuté en 0,04 secondes :~# ll /etc /hosts -rw-r--r-- 1 racine racine 551 23 décembre 20:43 /etc/hosts

    Une fois que nous sommes sûrs que tout fonctionne, nous permettons au service de démarrer, en /etc/default/puppet changement:

    # Démarrer Puppet au démarrage ? DÉBUT=oui

    Démarrage du service

    :~# démarrage de la marionnette de service

    Puppet interrogera le serveur puppetmaster toutes les 30 minutes pour connaître les modifications de configuration et, si nécessaire, ajustera le système en conséquence.

    Pour utiliser Puppet plus efficacement, vous devez comprendre comment les modules et les manifestes sont créés. Ce didacticiel vous expliquera comment fonctionnent ces composants Puppet en configurant une pile LAMP sur un serveur Ubuntu 14.04.

    Exigences

    • Installation de Puppet (maître et agent). Plus à ce sujet -.
    • La possibilité de créer au moins un serveur virtuel Ubuntu 14.04 pour servir le nœud de l'agent Puppet.

    Bases du code des marionnettes

    Ressources

    Le code Puppet est principalement constitué de ressources. Une ressource est un morceau de code qui décrit l'état du système et détermine les modifications dont il a besoin. Par exemple:

    utilisateur("mitchell":
    assurer => présent,
    uid => "1000",
    gid => "1000",
    shell => "/bin/bash",
    maison => "/maison/mitchell"
    }

    La déclaration de ressource a le format suivant :

    type_ressource("nom_ressource"
    attribut => valeur
    ...
    }

    Pour afficher tous les types de ressources Puppet, exécutez la commande :

    ressource de marionnette --types

    Vous en apprendrez davantage sur les types de ressources dans ce guide.

    Manifestes

    Un manifeste est un script d'orchestration. Les programmes Puppet avec une extension .pp sont appelés manifestes. Le manifeste Puppet par défaut est /etc/puppet/manifests/site.pp.

    Cours

    Comme dans tout langage de programmation classique, les classes sont responsables de l’organisation et de la réutilisation de parties de l’orchestration.

    Dans une définition de classe se trouve un bloc de code qui décrit le fonctionnement de la classe. Une fois que vous avez défini une classe, vous pouvez l'utiliser dans des manifestes.

    La définition de classe a le format suivant :

    classe exemple_classe (
    ...
    code
    ...
    }

    Ce code définit la classe example_class. Le code Puppet sera entre accolades.

    Une déclaration de classe est l'endroit dans le code où une classe particulière est appelée. Avec une déclaration de classe, Puppet traite son code.

    La déclaration de classe peut être ordinaire et par type de ressource.

    Une déclaration de classe normale est ajoutée au code à l'aide du mot clé include.

    inclure example_class

    Lorsqu'elle est déclarée comme type de ressource, la classe est déclarée au format ressource :

    classe("exemple_classe":)

    Cette déclaration vous permet d'ajouter des paramètres de classe à votre code qui remplacent les valeurs par défaut des attributs de classe. Par exemple:

    nœud "host2" (
    classe ("apache": ) # utiliser le module apache
    apache::vhost ( "example.com": # définir la ressource vhost
    port => "80",
    docroot => "/var/www/html"
    }
    }

    Modules

    Un module est un groupe de manifestes et d'autres fichiers organisés de manière prédéfinie qui facilite le partage et la réutilisation de parties individuelles de l'orchestration. Les modules aident à organiser le code Puppet car ils peuvent être utilisés pour séparer le code en plusieurs manifestes.

    Les modules Puppet sont stockés dans le répertoire /etc/puppet/modules.

    Rédaction d'un manifeste

    Vous pouvez vous entraîner à écrire des manifestes, des modules et des classes Puppet en utilisant l'exemple de l'installation d'une pile LAMP sur un serveur Ubuntu (le résultat sera ).

    Ainsi, pour orchestrer un serveur Ubuntu 14.04 et y installer une pile LAMP, vous avez besoin de ressources pour les actions suivantes :

    • installation du paquet apache2.
    • démarrer le service Apache2.
    • installer le package du serveur MySQL, mysql-server.
    • démarrer le service MySQL.
    • installation du paquet php5
    • création d'un script de test PHP, info.php.
    • mettre à jour l'index apt avant d'installer chaque package.

    Vous trouverez ci-dessous trois exemples de code Puppet qui peuvent être utilisés pour réaliser une telle configuration de pile LAMP.

    Le premier exemple vous apprendra comment écrire des manifestes de base dans un seul fichier. Le deuxième exemple vous aidera à assembler et à utiliser une classe et un module basés sur des manifestes précédemment écrits. Le troisième exemple vous montrera comment utiliser des modules publics prédéfinis pour installer une pile LAMP.

    Note: Pour les tests, il est préférable d'utiliser un nouveau serveur virtuel.

    Exemple 1 : Installation de LAMP avec un seul manifeste

    Le manifeste Puppet peut être écrit sur le nœud de l'agent, puis exécuté à l'aide de la commande puppet apply (vous n'avez pas besoin d'une configuration maître et agent pour ce faire).

    Dans cette section, vous apprendrez à rédiger des manifestes qui utiliseront ces types de déclarations de ressources :

    • exec : exécute des commandes.
    • package : installer les packages.
    • service : gestion des services.
    • fichier : gestion des fichiers.

    Créer un manifeste

    Créez un nouveau manifeste :

    sudo vi /etc/puppet/manifests/lamp.pp

    Ajoutez-y le code suivant pour déclarer les ressources requises.

    # exécutez la commande "apt-get update"
    exec("apt-update": # ressource exec "apt-update"
    command => "/usr/bin/apt-get update" # commande que cette ressource exécutera
    }
    # installer le paquet apache2
    paquet("apache2":
    require => Exec["apt-update"], # request "apt-update" avant d'installer le package
    assurer => installé,
    }
    # démarrer le service Apache2
    service("apache2":
    assurer => en cours d'exécution,
    }
    # installer le serveur mysql
    package("serveur-mysql":
    require => Exec["apt-update"], # request "apt-update" en réinstallant
    assurer => installé,
    }
    # démarrer le service mysql
    service("mysql":
    assurer => en cours d'exécution,
    }
    # installer le paquet php5
    paquet("php5":
    require => Exec["apt-update"], # demande "apt-update" avant l'installation
    assurer => installé,
    }
    # démarrer le service info.php
    fichier("/var/www/html/info.php":
    assurer => fichier,
    contenu => "", #code phpinfo
    require => Package["apache2"], # requête pour le package "apache2"
    }

    Appliquer un manifeste

    Pour utiliser le nouveau manifeste, entrez la commande :

    sudo marionnette appliquer --test

    Il affichera un résultat volumineux qui affiche tous les changements dans l'état de l'environnement. S'il n'y a aucune erreur dans le résultat, vous devriez pouvoir ouvrir votre adresse IP externe ou votre nom de domaine dans votre navigateur. Une page de test PHP avec des informations sur la pile apparaîtra à l'écran. Cela signifie qu'Apache et PHP fonctionnent.

    La pile LAMP est maintenant installée sur le serveur à l'aide de Puppet.

    Il s'agit d'un manifeste assez simple puisqu'il peut être exécuté sur un agent. Si vous n'avez pas de maître Puppet, les autres nœuds d'agent ne pourront pas utiliser ce manifeste.

    Le serveur maître Puppet vérifie les changements d'état du serveur toutes les 30 minutes.

    Exemple 2 : Installation d'une pile LAMP à l'aide d'un module

    Essayez maintenant de créer un module simple basé sur le manifeste LAMP que vous avez écrit dans la section précédente.

    Pour créer un module, créez un nouveau répertoire dans le répertoire modules (son nom doit correspondre au nom du module). Ce répertoire doit contenir un répertoire manifestes et un fichier init.pp. Le fichier init.pp spécifie la classe Puppet (son nom doit également correspondre au nom du module).

    Création d'un module

    Accédez au serveur maître Puppet et créez une structure de répertoires pour le module :

    cd /etc/puppet/modules
    sudo mkdir -p lampe/manifestes

    Créez et ouvrez le fichier init.pp dans l'éditeur :

    sudo vi lamp/manifests/init.pp

    Insérez la classe de lampe dans le fichier :

    lampe de classe (
    }

    Copiez le contenu du manifeste de la section 1 et collez-le dans le bloc de classe de lampe. Vous disposez désormais d’une définition de classe de lampe. D'autres manifestes pourront utiliser cette classe comme module.

    Enregistrez et fermez le fichier.

    Utiliser un module dans le manifeste principal

    Vous pouvez maintenant configurer le manifeste principal et utiliser le module lamp pour installer la pile LAMP sur le serveur.

    Sur le serveur maître Puppet, modifiez le fichier suivant :

    sudo vi /etc/puppet/manifests/site.pp

    Très probablement, le fichier est vide pour le moment. Ajoutez-y les lignes suivantes :

    nœud par défaut ( )
    nœud "lampe-1" (
    }

    Note: Remplacez lamp-1 par le nom d'hôte de votre agent Puppet sur lequel installer la pile.

    Le bloc de nœuds vous permet de spécifier le code Puppet qui ne s'appliquera qu'à certains nœuds.

    Le bloc par défaut s'applique à tous les nœuds d'agent qui n'ont pas de bloc individuel (laissez-le vide). Le bloc lamp-1 sera appliqué au nœud d’agent lamp-1.

    Ajoutez la ligne suivante à ce bloc, qui utilise le module lamp :

    Enregistrez et fermez le fichier.

    Le nœud de l'agent Puppet pourra désormais télécharger les paramètres du serveur maître et installer la pile LAMP. Si vous souhaitez apporter des modifications maintenant, exécutez la commande sur l'agent :

    agent sudo marionnette --test

    Les modules constituent le moyen le plus pratique de réutiliser le code Puppet. De plus, les modules vous aident à organiser logiquement votre code.

    Exemple 3 : Installation de LAMP à l'aide de modules publics

    Le module MySQL est utilisé de la même manière. Ajoutez les lignes suivantes au bloc node :

    classe("mysql::serveur":
    root_password => "mot de passe",
    }

    Vous pouvez également transmettre les paramètres du module MySQL.

    Ajoutez une ressource qui copiera info.php à l'emplacement souhaité. Utilisez le paramètre source. Ajoutez les lignes suivantes au bloc node :

    file("info.php": # nom du fichier de ressource
    chemin => "/var/www/html/info.php", # chemin cible
    assurer => fichier,
    require => Class["apache"], # classe Apache à utiliser
    source => "puppet:///modules/apache/info.php", # emplacement où copier le fichier
    }

    Cette déclaration de classe utilise le paramètre source au lieu du contenu. Cette option utilise non seulement le contenu du fichier, mais le copie également.

    Puppet copiera le fichier puppet:///modules/apache/info.php dans /etc/puppet/modules/apache/files/info.php.

    Enregistrez et fermez le fichier.

    Créez un fichier info.php.

    sudo sh -c "écho""> /etc/puppet/modules/apache/files/info.php"

    Le nœud de l'agent Puppet pourra désormais télécharger les paramètres du serveur maître et installer la pile LAMP. Si vous souhaitez apporter des modifications à l'environnement de l'agent dès maintenant, exécutez la commande sur ce nœud :

    agent sudo marionnette --test

    Cette commande téléchargera toutes les mises à jour pour le nœud actuel et installera la pile dessus. Pour vérifier qu'Apache et PHP fonctionnent, ouvrez l'adresse IP ou le domaine du nœud dans un navigateur :

    http://lamp_1_public_IP/info.php

    Conclusion

    Vous disposez désormais de connaissances de base sur l'utilisation des modules et des manifestes Puppet. Essayez de créer vous-même un manifeste et un module simples.

    Puppet est idéal pour gérer les fichiers de configuration des applications.

    Mots-clés : ,

    L'article a été écrit dans le magazine System Administrator

    Révolution mondiale

    La gestion de plusieurs systèmes Unix ne peut pas être qualifiée de confortable. Pour configurer le 1er paramètre, l'administrateur doit contacter chaque machine ; les scripts ne peuvent aider que partiellement, et pas dans toutes les situations.

    Il convient de reconnaître que les administrateurs réseau Windows occupent toujours une position plus efficace. Il suffit de modifier les fonctions des politiques de groupe et au bout d'un certain temps, tous les ordinateurs du réseau, y compris ceux dotés d'un système d'exploitation récemment installé, « découvriront » l'innovation, si elle les affecte naturellement.

    En regardant la longue période de développement d'Unix, on peut voir que rien de tel n'a jamais fait son chemin. Il existe des solutions comme kickstart qui facilitent l'installation initiale du système d'exploitation, mais le développement futur nécessitera des efforts importants.

    Les solutions commerciales comme BladeLogic et OpsWare ne résolvent que partiellement le problème des options d'automatisation ; leur principal avantage est la présence d'une interface graphique, et elles ne peuvent être achetées que par les grandes organisations. Naturellement, il existe des projets qui proposent des solutions gratuites, mais tout au long de leur existence, ils n'ont jamais réussi à créer une grande société.

    Par exemple, Cfengine n'est pas très populaire parmi les administrateurs, même si, outre Linux, il peut être utilisé sous *BSD, Windows et Mac OS X. Cela peut être dû à la relative complexité du développement des configurations. Lors de la description des tâches, vous devez prendre en compte les caractéristiques de chaque système spécifique et contrôler manuellement la séquence d'actions lors de l'exécution des commandes.

    En d'autres termes, l'administrateur doit garder à l'esprit que pour certains systèmes, il est nécessaire d'écrire adduser pour d'autres systèmes useradd, de prendre en compte le placement des fichiers sur différents systèmes, etc. Cela complique grandement le processus d'écriture des commandes ; difficile de faire la bonne configuration à la volée, et les configurations sont presque impossibles à lire au bout d'un certain temps.

    Malgré la licence GPL, Cfengine est en réalité le projet d'une seule personne qui contrôle toutes les configurations et n'est pas très intéressée par la construction d'une société ouverte. En fin de compte, les capacités de cfengine sont tout à fait satisfaisantes pour le développeur, mais pour les autres administrateurs, c'est plutôt un casse-tête supplémentaire.

    Pour améliorer cfengine, divers modules complémentaires ont été créés par des développeurs tiers, ce qui n'a souvent fait qu'empirer la situation. Le créateur de plusieurs de ces modules cfengine, Luke Kanies, a finalement décidé de créer un outil similaire, mais sans bon nombre des défauts de cfengine.

    Caractéristiques des marionnettes

    Puppet, comme cfengine, est un système client-serveur qui utilise un langage déclaratif, c'est-à-dire invariable, pour décrire les tâches et les bibliothèques pour leur implémentation. Les clients se connectent périodiquement (30 minutes par défaut) au serveur central et reçoivent la dernière configuration.

    Si les fonctions acquises ne coïncident pas avec l'état du système, elles seront exécutées si nécessaire, un rapport sur les opérations effectuées est envoyé au serveur. Le serveur peut enregistrer des messages dans Syslog ou dans un fichier, créer un graphique RRD et les envoyer à une adresse e-mail désignée.

    Les couches d'abstraction supplémentaires Transactional et Resource offrent la plus grande comparabilité avec les options et applications existantes, vous permettant de vous concentrer sur les objets système sans vous soucier des différences dans l'implémentation et la description des commandes détaillées et des formats de fichiers. L'administrateur opère uniquement avec le type d'objet, Puppet s'occupe du reste. Ainsi, le type de package connaît dix-sept systèmes de packages ; celui qui convient sera automatiquement reconnu en fonction des informations sur la version de la distribution ou du système, bien que, si nécessaire, le gestionnaire de packages puisse être défini de force.

    Contrairement aux scripts, qui ne peuvent souvent pas être utilisés sur d'autres systèmes, les configurations Puppet écrites par des administrateurs tiers fonctionneront, pour la plupart, sans problème sur n'importe quel autre réseau. Puppet CookBook est déjà livré avec trois packs de 10 recettes prêtes à l'emploi. Puppet prend actuellement officiellement en charge les systèmes d'exploitation et services suivants : Debian, RedHat/Fedora, Solaris, SUSE, CentOS, Mac OS X, OpenBSD, Gentoo et MySQL, LDAP.

    Langage des marionnettes

    Pour aller plus loin, il faut d’abord comprendre les éléments de base et les capacités du langage. La langue est l'une des forces de Puppet. Avec son aide, les ressources que l'administrateur envisage de gérer et leurs actions sont décrites.

    Contrairement à la plupart des solutions similaires, le langage Puppet vous permet de simplifier l'accès à toutes les ressources similaires sur n'importe quel système dans un environnement hétérogène. La description de la ressource comprend généralement le nom, le type et les attributs. Par exemple, pointons sur le fichier /etc/passwd et définissons ses attributs :

    fichier("/etc/passwd":

    propriétaire => racine,

    groupe => racine,

    À ce stade, les clients se connectant au serveur copieront le fichier /etc/passwd et installeront les attributs indiqués. Dans une règle, vous pouvez définir plusieurs ressources à la fois, en les séparant par un point-virgule.

    Que faire si le fichier de configuration utilisé sur le serveur diffère de celui du client ou n'est pas utilisé du tout ? Par exemple, cette situation peut apparaître lors de la configuration des connexions VPN. Dans ce cas, le fichier peut être pointé vers l'aide de la directive source.

    Il existe ici deux options, comme d'habitude, pour spécifier le chemin d'accès à un autre fichier ; deux protocoles URI sont également pris en charge : file et puppet. Dans le premier cas, un lien vers un serveur NFS externe est utilisé, dans la deuxième option, un service de type NFS est lancé sur le serveur Puppet, qui exporte les ressources.

    Dans ce dernier cas, le chemin par défaut est relatif au répertoire racine de la marionnette - /etc/puppet. Autrement dit, le lien puppet://server.domain.com/config/sshd_config correspondra au fichier /etc/puppet/config/sshd_config.

    Vous pouvez remplacer ce répertoire à l'aide de la directive filebucket, bien qu'il soit plus correct d'utiliser la section du même nom dans le fichier /etc/puppet/fileserver.conf. Dans ce cas, vous pouvez restreindre l'accès au service uniquement à partir de certaines adresses. Par exemple, décrivons la section de configuration.

    chemin /var/puppet/config

    autoriser *.domain.com

    autoriser 192.168.0.*

    autoriser 192.168.1.0/24

    refuser *.wireless.domain.com

    Et plus tard, nous nous tournons vers cette section pour décrire la ressource.

    source => "puppet://server.domain.com/config/sshd_config"

    Avant les deux points se trouve le nom de la ressource. Dans les cas les plus courants, vous pouvez simplement spécifier un alias ou des variables comme nom. L'alias est défini à l'aide de la directive alias. chemin complet du fichier. Dans des configurations plus complexes

    fichier("/etc/passwd":

    alias => mot de passe

    Une autre option pour créer un alias est parfaite dans ce cas lorsque vous devez gérer différents systèmes d'exploitation. Par exemple, créons une ressource décrivant le fichier sshd_config :

    fichier (sshdconfig :

    nom => $système d'exploitation ? (

    solaris => "/usr/local/etc/ssh/sshd_config",

    par défaut => "/etc/ssh/sshd_config"

    Dans cet exemple, nous sommes confrontés à un choix. Le fichier pour Solaris est spécifié séparément, pour tous les autres, le fichier /etc/ssh/sshd_config sera sélectionné. Pour le moment, cette ressource est accessible en tant que sshdconfig, en fonction du système d'exploitation, le chemin approprié sera sélectionné.

    Par exemple, nous indiquons que si sshd est en cours d'exécution et qu'un nouveau fichier est reçu, le service doit être redémarré.

    assurer => vrai,

    abonnez-vous => Fichier

    Les variables sont souvent utilisées lorsque vous travaillez avec des données utilisateur. Par exemple, nous décrivons l’emplacement des répertoires personnels des utilisateurs :

    $homeroot = "/home"

    Actuellement, les fichiers d'un utilisateur spécifique sont accessibles sous forme de

    $(homeroot)/$nom

    Le paramètre $name sera renseigné avec le nom du compte de l'utilisateur. Dans certains cas, il est pratique de trouver la valeur par défaut pour un type donné. Par exemple, pour le type exec, ils indiquent souvent les collections dans lesquelles il doit rechercher le fichier exécutable :

    Exec (chemin => "/usr/bin:/bin:/usr/sbin:/sbin")

    Si vous devez pointer vers plusieurs fichiers et répertoires imbriqués, vous pouvez utiliser le paramètre recurse.

    fichier("/etc/apache2/conf.d":

    source => "puppet:// puppet://server.domain.com/config/apache/conf.d",

    récursivité => "vrai"

    Plusieurs ressources peuvent être combinées en classes ou définitions. Les classes constituent une description complète d’un système ou d’un service et sont utilisées séparément.

    "/etc/passwd" : propriétaire => racine, groupe => racine, mode => 644 ;

    "/etc/shadow": propriétaire => racine, groupe => racine, mode => 440

    Comme dans les langages orientés objet, les classes peuvent être remplacées. Par exemple, sur FreeBSD, le groupe propriétaire de ces fichiers est wheel. Par conséquent, afin de ne pas réécrire complètement la ressource, créons une nouvelle classe freebsd, qui héritera de la classe Linux :

    la classe freebsd hérite de Linux (

    Fichier["/etc/passwd"] ( groupe => roue );

    Fichier["/etc/shadow"] ( groupe => roue )

    Pour plus de commodité, toutes les classes peuvent être placées dans un fichier séparé, qui peut être connecté à l'aide de la directive include. Les définitions peuvent prendre de nombreuses propriétés comme arguments, mais ne prennent pas en charge l'héritage et sont utilisées dans ce cas si vous devez décrire des objets utilisés plusieurs fois. Par exemple, nous déterminerons le répertoire personnel des utilisateurs et les commandes nécessaires pour créer un nouveau compte.

    définir user_homedir ($group, $fullname, $ingroups) (

    utilisateur("$nom":

    assurer => présent,

    commentaire => "$nom complet",

    gid => "$groupe",

    groupes => $ingroups,

    adhésion => minimum,

    shell => "/bin/bash",

    maison => "/home/$nom",

    require => Groupe[$group],

    exec("$nom rép_accueil":

    commande => « /bin/cp -R /etc/skel /home/$name; /bin/chown -R $nom:$groupe /home/$nom",



    Des questions ?

    Signaler une faute de frappe

    Texte qui sera envoyé à nos rédacteurs :