Elaborato Maiello Alessandro N46001176

Transcript

Elaborato Maiello Alessandro N46001176
Scuola Politecnica e delle Scienze di Base
Corso di Laurea in Ingegneria Informatica
Elaborato finale in RETI DI CALCOLATORI
Sistemi di gestione automatica della
configurazione: Puppet
Anno Accademico 2013/2014
Candidato:
Alessandro Maiello
matr. N46001176
Alla mia famiglia, che con tanti
sacrifici mi ha permesso di
arrivare fin qui.
Indice
Indice .................................................................................................................................................. III
Introduzione ......................................................................................................................................... 4
Capitolo 1: DevOps .............................................................................................................................. 6
1.1 DevOps: principi e finalità .................................................................................................... 7
1.2 DevOps e il mobile ................................................................................................................ 9
Capitolo 2: Software Management tools ............................................................................................ 11
2.1 Modelli di funzionamento ................................................................................................... 11
2.2 Panoramica su Salt, Ansible e Chef .................................................................................... 13
2.2.1
Salt ............................................................................................................................... 13
2.2.2
Ansible ......................................................................................................................... 14
2.2.3
Chef .............................................................................................................................. 15
2.2.3.1 Componenti di chef ........................................................................................................ 16
Capitolo 3: Puppet .............................................................................................................................. 19
3.1 Puppet Management Tool ................................................................................................... 20
3.1.1
Modelli di funzionamento ............................................................................................ 20
3.2 Il linguaggio Puppet ............................................................................................................ 22
3.2.1
Risorse .......................................................................................................................... 22
3.2.2
Manifesti e classi .......................................................................................................... 23
3.2.3
Moduli .......................................................................................................................... 25
3.2.4
Variabili e parametri di classe ...................................................................................... 27
3.2.5
Facts e conditional statements...................................................................................... 28
3.2.6
Ordinamento delle risorse ............................................................................................ 31
3.3 Installazione e configurazione di Puppet open source ........................................................ 34
3.3.1
Creazione e configurazione del Puppet master ............................................................ 34
3.3.2
Creazione e configurazione del Puppet agent .............................................................. 37
3.3.3
Prima connessione e scambio certificati ...................................................................... 38
Conclusioni ........................................................................................................................................ 45
Bibliografia ........................................................................................................................................ 46
Introduzione
Con l’introduzione e l’estensione di tecniche informatiche e telematiche si è avuta una
vera e propria rivoluzione in parecchi settori, dall’economia alla politica, alla società in
generale. Soprattutto nel settore economico, ma non solo, l’informatizzazione ha cambiato
sia i ritmi produttivi che i consumi, automatizzando gran parte del lavoro e portando
l’uomo ad occuparsi prevalentemente di funzioni di controllo. Sempre più aziende, enti o
organizzazioni hanno bisogno di una propria infrastruttura IT, che a causa del gran numero
di macchine da cui è costituita, non è molto semplice da gestire e configurare.
Al fine di migliorare i tempi di produzione e di sviluppo dei prodotti e per semplificare la
gestione dell’infrastruttura IT, molte compagnie hanno investito il loro denaro per lo
sviluppo di alcuni software management tools, che vengono incontro alle esigenze degli
amministratori di sistema: facilitano ed automatizzano la gestione delle configurazioni di
software
e
servizi
di
un’infrastruttura
informatica.
Attraverso
questi
tools,
indipendentemente dal numero di macchine che costituiscono la rete del sistema, è
possibile definire una o più configurazioni che verranno poi applicate automaticamente a
sottoinsiemi di nodi del sistema e gestite dagli stessi.
Puppet è uno di questi strumenti software open-source ed è in grado di gestire sistemi e
infrastrutture di rete durante il loro ciclo di vita in maniera del tutto automatica, dalla
configurazione e provisioning fino al reporting, e di mantenere sempre aggiornata
4
un'enorme quantità di servizi da essi offerti, garantendo così costi sempre più bassi.
Oltre a Puppet, vi sono altri tools sia open-source che in versione Enterprise, in grado di
gestire infrastrutture IT molto complesse. Ognuno di essi è dotato di un proprio DSL
(Domain-Specific Language), essenziale al fine di poter definire files di configurazione
contenenti la descrizione dello stato finale desiderato per il sistema da gestire.
Questo elaborato si propone, nel primo capitolo, di illustrare l’importanza del movimento
DevOps ai fini dello sviluppo dei tools di gestione automatica delle configurazioni, per poi
fornire, nel secondo capitolo, una panoramica degli stessi delineandone le caratteristiche
principali. Il terzo capitolo, infine, focalizzerà l’attenzione sul modello Master/Agent del
tool Puppet, sugli elementi fondamentali del suo DSL e sulla sua installazione e
configurazione iniziali, mostrando anche qualche semplice esempio di funzionamento.
5
Capitolo 1: DevOps
Con il termine DevOps, si intende quel movimento secondo il quale sviluppatori e addetti
alle operations all’interno di un’organizzazione IT debbano collaborare e comunicare tra
loro al fine di migliorare la produttività e la velocità di sviluppo e distribuzione del
software, automatizzando i flussi di lavoro e misurando costantemente le prestazioni delle
applicazioni.
Tradizionalmente, Dev (Developers) e Ops (Operations Team) lavorano separatamente: gli
sviluppatori si occupano di creare l’applicazione; gli addetti alle operations si occupano di
tutto il resto, come l’ottimizzazione delle risorse e delle prestazioni, il controllo di qualità
del software ecc. Questa divisione dei ruoli nello sviluppo del software poteva andare bene
fintanto che i prodotti da rilasciare richiedevano settimane o mesi di lavoro, ma
nell’attuale era degli app store, dove le applicazioni vengono rilasciate in pochi giorni,
essa inizia ad essere una scelta poco sensata.
Questo movimento viene reso popolare tramite una serie di DevOps Day, iniziati nel 2009
in Belgio, e poi svolti in India, USA, Brasile, Australia, Germania e Svezia, per discutere
6
sul divario operativo e lasciare che ingegneri del software potessero parlare dei modi
migliori per raggiungere dimensioni e velocità ottimali nella distribuzione del codice.
Il movimento DevOps riprende i principi delle metodologie Agili, le quali avevano
abbandonato il modello a cascata a favore di un modello di sviluppo continuo per il
software, e applica lo stesso concetto anche alle operations, implementando quindi rilasci
e integrazione continui. In modo da facilitare ciò, DevOps incoraggia l’automazione dei
processi di rilascio e configurazione e dei cambiamenti.
DevOps ha trovato terreno fertile soprattutto grazie all’avvento del cloud computing, un
insieme di servizi e tecnologie che permettono di memorizzare e elaborare dati utilizzando
risorse hardware/software distribuite e virtualizzate in rete, favorendo così l’automazione e
la continuità in termini di sviluppo e distribuzione del software.
L’idea fondamentale di DevOps è di “descrivere un’infrastruttura come codice” per
consentire il provisioning e la configurazione di ambienti DevOps, e per permettere
l’utilizzo di tools di gestione della configurazione quali Chef, Puppet, Salt e Ansible, al
fine di rendere le aziende sempre più competitive perché pronte a rispondere rapidamente
alle richieste di mercato.
1.1 DevOps: principi e finalità
L’utilizzo e l’adozione di DevOps consente di velocizzare i cambiamenti del software e,
indipendentemente dal settore di interesse, permette di rilasciare più celermente servizi e
software migliore, con costi e rischi minori. DevOps esalta la collaborazione tra i
partecipanti allo sviluppo del software, quali sviluppatori, tester, business teams e addetti
alle operations, al fine di ottenere un obiettivo comune: l’innovazione, sostenuta da rilasci
continui e feedback costante.
DevOps, quindi, non è l’obiettivo ma è il mezzo che consente di raggiungere gli obiettivi
prefissati a patto di seguire determinati principi. DevOps aiuta ad ottenere alcuni punti
fondamentali:
 Velocizzare i cicli di feedback.
7
 Miglioramento dell’esperienza dell’utente finale.
 Aumentare la produttività.
 Ottimizzare i processi.
 Diminuire i difetti di produzione.
 Ridurre i tempi di rilascio del software.
Al fine di raggiungere questi obiettivi è necessario seguire alcuni principi essenziali:
 Incoraggiare l’apprendimento collaborativo e la sperimentazione: la condivisione
della conoscenza consente ai team di identificare e riutilizzare i pattern ben riusciti,
mentre la sperimentazione permette di tentare nuovi approcci, imparare dai
fallimenti e innovare il software durante il suo ciclo di vita.
 Supporto alla distribuzione mediante processi affidabili e ripetibili: qui
l’automazione gioca un ruolo essenziale. Definire i test in maniera automatica
consente di velocizzare il rilascio del software, di ridurre il numero di errori dovuti
alla definizione manuale dei testi e, quindi, di diminuire la possibilità di fallimenti
al momento del rilascio.
 Monitoring e convalida della qualità operativa: in base a questo principio è
necessario monitorare le caratteristiche, funzionali e non, dell’applicazione
attraverso l’utilizzo e la valutazione di determinate metriche sulla qualità. Questi
parametri devono essere acquisiti in un formato tale da poter essere compresi e
utilizzati da tutti gli stakeholder dell’azienda.
 Amplificazione dei cicli di feedback: consentire a tutti gli addetti allo sviluppo del
software di imparare dai feedback è essenziale al fine di effettuare i cambiamenti il
più presto possibile e di ridurre di conseguenza i costi. Per fare ciò le
organizzazioni devono creare canali di comunicazione efficienti che consentano a
tutti di accedere ai dati raccolti.
8
1.2 DevOps e il mobile
Nel settore mobile, vi è una grande varietà di piattaforme di rilascio. La situazione è in
qualche modo simile a quella presente molti anni fa nel settore desktop quando ancora
esistevano parecchi standard differenti tra loro. Ciò che la differenzia da essa è che nel
settore mobile, oltre ai diversi sistemi operativi, bisogna tenere in considerazione anche le
diverse caratteristiche dei terminali di destinazione, quali la risoluzione, il processore, la
potenza grafica, le reti supportate, ognuna delle quali aggiunge un ulteriore livello di
complessità allo sviluppo dell’applicazione. Quest’ultimo è reso ancora più difficile dalla
necessità di accorciare i tempi di rilascio sul mercato, in quanto dei ritardi eccessivi
potrebbero incidere sull’effettiva capacità dell’applicazione di venire incontro alle
esigenze degli utenti.
DevOps rappresenta una delle possibili soluzioni a questi problemi. Esso consente di
rilasciare un’applicazione funzionante completa di tutte le caratteristiche più recenti, in
qualsiasi momento durante la produzione della stessa. DevOps, infatti, rigetta il modello a
cascata a favore di un approccio agile, che consenta di sviluppare l’applicazione in modo
incrementale, tenendo traccia di tutti i cambiamenti della stessa e della effettiva possibilità
di implementare i cambiamenti stessi. Per garantire il successo del rilascio è necessario
quindi identificare, tracciare, catturare e testare ogni cambiamento e ciò è possibile
attraverso un approccio disciplinato che vede i team di sviluppo e delle operations lavorare
assieme al fine di garantire rilasci del software frequenti, affidabili e di alta qualità.
Attraverso DevOps è possibile:
 Catturare i cambiamenti
 Automatizzare il modo in cui essi avvengono
 Automatizzare il testing
 Mantenere i cambiamenti piccoli abbastanza da ridurre i rischi
DevOps
fornisce
un
approccio
disciplinato
e
automatizzato
allo
sviluppo
dell’applicazione, integrando piccoli miglioramenti funzionali, che potrebbero evolvere
col tempo in funzioni ben più complesse e articolate. Per DevOps, infatti, sia i rilasci delle
9
applicazioni sia gli aggiornamenti sono fondamentali, in quanto il vero obiettivo non è la
perfezione, ma il miglioramento continuo.
10
Capitolo 2: Software Management tools
I software management tools sono strumenti che permettono la gestione automatica della
configurazione di una grande quantità di nodi della rete in maniera prevedibile ed
idempotente. Essi leggono le informazioni contenute nei file di configurazione ed espresse
nel proprio DSL che descrivono lo stato finale desiderato per il sistema, e le applicano ai
nodi interessati. Attraverso di esse, un amministratore di sistema è in grado quindi di
replicare un configurazione su più nodi in maniera automatica o di ripristinarla celermente
in caso vi fossero dei problemi.
2.1 Modelli di funzionamento
I due modelli di funzionamento supportati dai software management tools sono: il
Master/Agent e lo Standalone.
Il modello Standalone è consigliato per infrastrutture piccole e poco complesse in quanto
permette di aggirare l’overhead introdotto dal modello Master/Agent, che è invece
consigliato per infrastrutture che richiedono un alto tasso di parallelizzazione delle
operazioni di gestione e maggior centralizzazione.
Nel modello Standalone (Fig.1) i cataloghi, contenenti le informazioni sullo stato
desiderato del sistema, sono testati e inviati da una o più workstations locali ai vari nodi.
11
Figura 1: Modello Standalone
Nel modello Master/Agent (Fig.2), invece, una macchina viene designata come server
(Master) e si occuperà di stabilire connessioni in entrata o in uscita con i nodi della rete
(Agent), che possono richiedere i cataloghi al Server, e di gestire separatamente le
informazioni di configurazione per ognuno di essi.
In questo modello, quindi, gli amministratori applicano cambiamenti al master, il quale poi
li propagherà verso i nodi che li applicheranno localmente. I nodi riportano poi al master
se i cambiamenti sono stati applicati con successo o meno. I nodi possono ricevere le
informazioni dal master attraverso due modalità distinte: pull e push.
Modalità pull: gli Agent interrogano periodicamente il Master (di default ogni 30 min),
per verificare se vi sono nuovi cambiamenti da dover applicare. In questo modello, i
cambiamenti applicati al master vengono quindi propagati ai nodi con un certo ritardo.
Modalità push: il Master ha il compito di propagare i cambiamenti agli Agents, di solito
attraverso code di messaggi. I cambiamenti si propagano più rapidamente rispetto al
modello pull.
12
Figura 2: Modello Master/Agent
2.2 Panoramica su Salt, Ansible e Chef
Analizziamo ora alcuni dei tools più diffusi.
2.2.1 Salt
Salt, rilasciato nel 2011 da SaltStack, è un tool molto scalabile in grado di gestire decine di
migliaia di server. Si basa su CLI e la comunicazione, basata sul metodo push, è
abbastanza semplice poiché avviene tramite SSH. I clients, detti minions, ricevono i
comandi dal server master e rispondono con i relativi risultati. I server master possono
essere più di uno e distribuiti su più livelli in modo da distribuire il carico delle richieste,
anche se così facendo si rischia di aumentare la ridondanza dei dati. Salt si può eseguire
sia in modalità Standalone, nelle piccole infrastrutture o per ragioni di testing, sia in
modalità Master/Agent, tramite la quale il client riceverà la propria configurazione
attraverso files chiamati Salt States (SLS), raccolti, compilati e successivamente inviati dal
master. Infine, grazie al sistema di peering, i masters, dopo aver ricevuto richieste dai
minions, possono a loro volta delegare le risposte ad altri masters. Per esempio, questo
meccanismo risulta efficace quando deve essere analizzato in tempo reale un database per
il recupero di dati utili al completamento di una configurazione per un client.
Salt supporta diverse distribuzioni: Arch Linux, Debian, Fedora, FreeBSD, Gentoo, OS X,
RHEL e derivate, Solaris, Ubuntu, Windows,Suse. Per maggiori informazioni riguardo
alle specifiche installazioni vedi http://docs.saltstack.com/en/latest/topics/installation.
13
2.2.2 Ansible
Un altro strumento open-source utilizzato per la gestione delle configurazioni e per
l’automazione di un’infrastruttura IT è Ansible. Lanciato nel 2012, gestisce i nodi tramite
SSH e necessita di Python (2.4 o successivi) per essere installato su questi ultimi. Ansible
ha un’architettura modulare che consente di poterlo estendere all’infinito: ogni modulo,
che può essere scritto in qualsiasi linguaggio di programmazione, svolge una determinata
funzione e gestisce un singolo aspetto di ogni sistema. I componenti principali sono:
• Inventario. E’ la lista di server sui quali Ansible applica, a comando, le
configurazioni di sistema e le istruzioni di automazione. Di default è contenuto
all’interno del file /etc/ansible/hosts, anche se è possibile specificare un percorso a
piacere.
• Tasks. Sono una serie di istruzioni che Ansible esegue in ordine di apparizione.
• Handlers. Sono delle istruzioni che vengono eseguite a seguito di una determinata
azione. Gli Handlers si basano sul modulo service, utilizzato per gestire i servizi di
sistema.
• Playbook. Sono delle collezioni di Tasks e devono essere definiti in linguaggio
YAML.
• Moduli. Vengono utilizzati per la gestione di servizi cloud. Facilitano l’installazione
di pacchetti software su server Linux con apt e yum, la gestione di file di
configurazione e database etc.
A differenza di altri tools, Ansible, non richiede l’installazione di alcun agent sui server, in
quanto utilizza di default il trasporto SSH, eliminando così anche la necessità di installare
software estraneo sui nodi. Qualora la comunicazione avvenga con sistemi che non
consentono di default l’accesso alla SSH come root, Ansible accetta credenziali di tipo
sudo per eseguire comandi e operazioni su tali sistemi. Per operazioni semplici, come ad
esempio verificare che un servizio sul sistema è in esecuzione o innescare aggiornamenti
del sistema e riavvii dello stesso, lo scambio di informazioni tra hosts avviene senza
l’utilizzo di particolari file di configurazione.
14
Ansible può essere distribuito in ambienti di virtualizzazione e in ambienti di cloud
pubblico e privato, quali VMware, OpenStack, AWS, Eucalyptus Cloud, KVM, e
CloudStack. La macchina da cui vengono lanciati i comandi richiede l’installazione di
Python 2.6 e supporta diverse distribuzioni basate su Linux e Unix, tra le quali ricordiamo
Red Hat, Debian, CentOS, OS X e BSD; sistemi Windows non supportati. I nodi invece
che devono essere gestiti richiedono l’installazione di Python 2.4 (o successivi).
L’installazione di python-simplejson è necessaria se si eseguono versioni di Python
precedenti alla 2.5. Inoltre viene fornito supporto per macchine Windows.
2.2.3 Chef
Anche Chef, come i precedenti, è un tool per la gestione delle configurazioni di
un’infrastruttura IT, distribuito sotto la licenza Apache 2.0 e scritto in Ruby (lato client) e
in Erlang4 (lato server). Chef si basa su semplici concetti, quali il raggiungimento dello
stato di sistema desiderato, la pianificazione centralizzata dell’infrastruttura IT e
l’aggregazione di semplici risorse per realizzare sistemi complessi. Si basa su due
modalità di funzionamento:
• Architettura Standalone. Permette di utilizzare i cookbooks (“ricette”) senza
richiedere alcun accesso allo Chef server. Il demone chef-solo viene eseguito in
locale e richiede che: sia i cookbooks sia le relative dipendenze vengano
memorizzati sul disco fisico di quel nodo. Non supporta tutto l’insieme di
funzionalità che invece mette a disposizione chef-client.
• Architettura Client/Server. In quest’architettura, lo Chef server rappresenta il
repository centrale di tutti i dati, le “ricette”, di configurazione. Qualsiasi nodo che
esegue chef-client, invece, può essere gestito tramite il sistema Chef. Chef-client
esegue tutte le attività di configurazione specificate dalla run-list, prelevando tutti i
dati di configurazione necessari dal server centrale. La comunicazione tra client e
server viene resa sicura tramite l’utilizzo di una combinazione di chiavi pubbliche
e private.
15
2.2.3.1 Componenti di chef
Come si nota dall’immagine sottostante, numerosi sono i componenti che permettono di
gestire un sistema con Chef. Questi lavorano insieme per fornire informazioni le istruzioni
a chef-client, affinchè questo possa eseguire il proprio lavoro.
Figura 3: Chef Components
I principali componenti di Chef (Fig. 3) sono:
• Chef-client. E’ l’agent che viene eseguito su ogni nodo che deve essere gestito da
Chef. Questo esegue tutte le operazioni necessarie per portare il nodo nello stato
16
richiesto. Rappresenta il componente principale installato sui nodi insieme ad ohai,
tool utilizzato per individuare gli attributi dei nodi (utilizzo della rete, della
memoria, della CPU etc.)
•
Workstation. E’ la macchina che esegue knife e che viene utilizzata per controllare
un singolo Chef server. Permette all’utente di testare e gestire i cookbooks e di
caricarli sullo Chef server. Knife è uno strumento a linea di comando utilizzato per
gestire nodi, cookbooks e ricette, risorse cloud etc.
•
Chef server. Raccoglie tutti i dati di configurazione necessari a chef-client per
configurare un nodo. Memorizza cookbooks, le politiche che devono essere
applicate ai nodi e i metadati che li descrivono. I cookbooks costituiscono la parte
fondamentale per la distribuzione delle politiche di configurazione. Questi
definiscono come deve essere configurato un nodo, attraverso l’utilizzo di attributi e
“ricette”; quest’ultime, scritte in Ruby, devono definire qualsiasi cosa sia necessaria
per configurare una specifica parte del sistema. Due componenti molto importanti
del server sono gli attributi e le run-list: i primi rappresentano specifici dettagli di
un nodo, quali lo stato corrente, lo stato precedente e successivo all’esecuzione di
chef-client e vengono definiti dallo stato del nodo stesso, dai cookbooks, dalle varie
regole. Le run-list, invece, definiscono tutte le impostazioni di configurazione da
applicare al nodo, un elenco ordinato di regole da eseguire, secondo l’ordine di
apparizione.
•
Chef Supermarket. E’ il luogo in cui i cookbooks della comunità vengono creati e
mantenuti.
Inoltre, Chef server mette a disposizione dell’utente delle funzionalità premium che
possono essere facilmente abilitate ed integrate, quali:
• Chef Manager. Fornisce un’interfaccia web-based per la gestione di attributi,
runlist, roles, cookbooks etc. che sono memorizzati sul server.
• Chef Analytics. Fornisce visibilità in tempo reale di cosa sta accadendo sullo Chef
server, compreso cosa sta cambiando, chi ha fatto e quando sono avvenuti i cambi.
17
• Chef Availability. Si occupa di replicare lo Chef server, in modo da fornire supporto
per l’High Availability.
Chef può essere integrato con le piattaforme di gestione di sistemi cloud, come Rackspace,
Amazon EC2, Google Cloud Platform, OpenStack, Microsoft Azure, per configurare
automaticamente nuove macchine. Chef-client `e supportato da diverse distribuzioni Linux,
Unix, e Microsoft Windows, tra le quali troviamo Ubuntu, Debian, RHEL/CentOS, Fedora,
Mac OS X, Solaris, FreeBSD, Windows Server. Chef-server supporta invece solo alcune
versioni di CentOS, Oracle Linux, RHEL ed Ubuntu.
18
Capitolo 3: Puppet
Puppet è uno strumento di gestione delle risorse e del software, rilasciato nel 2005 dalla
Puppet Labs, grazie al quale è possibile automatizzare ogni passo del processo di sviluppo
del software, a partire dal provisioning delle macchine virtuali e fisiche fino alla
configurazione e al reporting; dalle prime fasi di sviluppo del codice fino al testing, al
rilascio del prodotto e dei futuri aggiornamenti.
Puppet consente di:
• definire lo stato desiderato della configurazione dell’infrastruttura grazie ad un
semplice linguaggio di tipo dichiarativo;
• simulare modifiche alla configurazione prima di applicarle definitivamente
all’infrastruttura, in modo da sapere cosa accadrà quando il cambio verrà
effettuato;
• applicare lo stato desiderato in maniera automatica, correggendo così eventuali
variazioni nella configurazione;
• consultare i reports presenti sul puppet Master, contenenti informazioni dettagliate
sull’esatta configurazione dei nodi, inclusi tutti i cambiamenti effettuati e quando
sono stati applicati. Il reporting è disponibile solo in Puppet Enterprise.
Per definire, quindi, lo stato desiderato del sistema, è possibile scrivere i moduli in base
alle proprie specifiche di realizzazione utilizzando il DSL di Puppet, oppure utilizzare dei
moduli pre-compilati disponibili online sul Puppet Forge Marketplace e scaricabili
gratuitamente.
Puppet Software è disponibile nelle due distribuzioni OpenSource (personalizzabile,
19
flessibile e disponibile sotto la licenza Apache 2.0) e Enterprise (che include più di 40
servizi open-source come Puppet, PuppetDB, PE Console, ecc.). Puppet Enterprise,
inoltre, include un’interfaccia grafica web per l’analisi dei reports e il controllo
dell’infrastruttura, funzioni per la gestione degli aggiornamenti e della manutenzione,
meccanismi di gestione dei certificati e strumenti di cloud provisioning.
3.1 Puppet Management Tool
Puppet Management Tool rappresenta lo strumento più completo in termini di azioni
disponibili, moduli di configurazione e interfaccia utente. La versione open-source offre le
funzionalità fondamentali sulla gestione a quasi tutti i principali sistemi operativi. Tutti i
moduli e le configurazioni sono scritti con un linguaggio specifico basato su Ruby, mentre,
per quanto riguarda l’interfaccia utente, Puppet ha la GUI più completa tra i tools
sovracitati, con pieno supporto per Linux, Microsoft Windows, Unix/Unix-like e
MacOS X, consentendo il controllo in tempo reale dei nodi gestiti mediante moduli e
cataloghi precedentemente compilati ma limitando la possibilità di configurarli. Il
reporting, invece, è ben sviluppato in quanto fornisce dettagli sullo stato dei sistemi e sulle
modifiche di volta in volta apportate.
3.1.1 Modelli di funzionamento
Puppet offre due possibili modalità di funzionamento: Master/Agent (predefinita), e
standalone.
In Puppet standalone, ogni nodo usa periodicamente il commando puppet apply per
compilare e applicare il proprio catalogo, usando il set completo di moduli e manifesti di
Puppet. Ogni nodo, cioè, possiede una copia degli stessi files e dati che il puppet master
possiede nel modello Agent/Master.
Questa modalità di funzionamento distribuisce il carico della compilazione su più nodi
invece di concentrarlo su un unico o su pochi master servers, e non richiede la presenza di
un servizio puppet master sempre disponibile e reattivo. Lo svantaggio è che risulta meno
20
pratico aggiornare le configurazione e che ogni nodo può vedere come sono configurati gli
altri nodi. Inoltre, la distribuzione dei manifesti, moduli e dati aggiornati ad ogni nodo è a
completo carico dell’utente, e non viene gestita automaticamente dal puppet master.
La modalità di funzionamento Master/Agent, ovvero quella predefinita, prevede la
presenza di uno o più Puppet master servers che controllano le informazioni di
configurazione, mentre i nodi che devono essere controllati richiedono al master solo i
propri cataloghi di configurazione.
In questa architettura, i nodi da controllare eseguono il Puppet Agent daemon, come un
servizio in background. Uno o più servers eseguono il Puppet master daemon,
generalmente come un’applicazione Rack gestita attraverso un web server (come Apache
con Passenger).
La comunicazione avviene in questo modo. Periodicamente i Puppet agent invieranno
informazioni al Puppet master contattandolo sulla porta 8140 (impostata di default). La
connessione che si stabilisce tra loro è crittografata: il client genera una key auto-firmata
prima di collegarsi al server, dopodiché gliela invia e attende che la verifichi. In seguito,
l’agent invia una richiesta di certificato che il master deve convalidare per poter stabilire
definitivamente una connessione sicura, cioè il server si comporta come “autorità di
certificazione”. In questo modo il client potrà richiedere (polling) un catalogo al master.
Questo compilerà e reinvierà il catalogo al rispettivo nodo, usando diversi mezzi di
informazione ai quali ha accesso. Ricevuto il catalogo, il Puppet agent lo applicherà
controllando ogni risorsa descritta da esso. Se trova delle risorse che non sono nello stato
desiderato, applicherà ogni cambiamento necessario per correggerle. (Oppure, in no-op
mode, esso riporterà al master quali cambiamenti sarebbero stati necessari). Dopo aver
applicato il catalogo, l’agent invierà un report al Puppet master.
21
3.2 Il linguaggio Puppet
Puppet usa un proprio domain-specific language (DSL) per descrivere le configurazioni
delle macchine. Il DSL di Puppet è un linguaggio di tipo dichiarativo anziché imperativo,
ovvero invece di definire un processo o un set di istruzioni, il codice di Puppet descrive
solamente lo stato finale desiderato per il sistema e si affida a providers interni per
l’effettiva implementazione. Il codice in questo linguaggio viene salvato in files chiamati
manifesti, che non sono altro che semplici files di testo txt salvati con estensione .pp. Più
manifesti vengono raggruppati in moduli, le cui combinazioni permettono di creare le
diverse configurazioni.
3.2.1 Risorse
Prima di definire nel dettaglio cosa sono i manifesti ed i moduli, è opportuno partire
dall’analisi dei blocchi fondamentali della sintassi del modello di linguaggio dichiarativo
di Puppet, ovvero le risorse.
Le risorse sono le unità fondamentali per la modellazione dei sistemi. Ogni risorsa
descrive un aspetto del sistema ed il suo stato, ad esempio un servizio che dovrebbe essere
in esecuzione oppure un package da installare. Il blocco di codice che descrive la risorsa è
detto dichiarazione della risorsa, come ad esempio:
L
user { 'root':
ensure => 'present',
comment => 'root',
gid => '0',
home => '/root',
password => '$1$jrm5tnjw$h8JJ9mCZLmJvIxvDLjw1M/',
password_max_age => '99999',
password_min_age => '0',
shell => '/bin/bash',
uid => '0',
}
La parola user, prima della parentesi graffa, è il tipo della risorsa. Esso serve a definire il
22
genere della risorsa in questione.
La parola root tra le singole virgolette prima della colonna è il titolo della risorsa. Puppet
utilizza il titolo della risorsa come suo identificatore univoco, ovvero non vi possono
essere due risorse con lo stesso nome.
Dopo i due punti della prima linea vi è una lista di attributi ed i corrispondenti valori.
Ogni linea è costituita dal nome dell’attributo, un => (detto ‘hash rocket’), un valore, e una
virgola finale.
La dichiarazione di una risorsa assume quindi la seguente forma contratta:
type {'title':
attribute => 'value',
}
Dichiarare una risorsa serve ad aggiungerla al catalogo, e per dire a Puppet di gestirne lo
stato. Così, quando Puppet applicherà il catalogo compilato, esso:
 Leggerà lo stato attuale della risorsa sul sistema di destinazione;
 Confronterà lo stato attuale con quello desiderato;
 Se necessario, cambierà il sistema al fine di forzare lo stato desiderato;
Puppet fornisce alcuni tools essenziali per la gestione delle risorse. Essi sono:
 Puppet describe: fornisce una descrizione del tipo della risorsa;
 Puppet resource: fornisce una descrizione della risorsa e, se eseguito con il flag –e,
di aprirla nell’editor di testo per modificarla;
 Puppet apply: permette di creare una risorsa, o di effettuare modifiche veloci ad una
esistente.
Questo sistema di dichiarazione delle risorse e di providers è chiamato Resource
Abatraction Layer o RAL.
3.2.2 Manifesti e classi
Due elementi fondamentali di Puppet per l’organizzazione e l’implementazione della
dichiarazione delle risorse sono: le classi e i manifesti. Il corretto uso di entrambi è
23
essenziale al fine di creare codice Puppet testabile e riusabile.
Come è stato già detto, un manifesto è un file di testo che contiene codice Puppet ed è
salvato con estensione .pp. Sebbene sia utile salvare e modificare codice Puppet attraverso
un file, lo scopo principale dei manifesti è quello di organizzare il codice in un modo che
Puppet stesso può comprendere. Teoricamente è possibile aggiungere qualsiasi pezzo di
codice sintatticamente valido ad un manifesto, ma, affinchè l’architettura di Puppet
funzioni efficacemente, occorre seguire delle regole di base nella scrittura e nel
posizionamento dei manifesti. Un elemento chiave della corretta gestione dei manifesti è
costituito dalle classi.
Nel DSL di Puppet una classe è un blocco di codice, contenente risorse o altre classi, al
quale viene assegnato un nome. Una classe serve a gestire un insieme di risorse relative a
una singola funzione o a un componente del sistema.
Per usare una classe sono necessari due operazioni. Innanzitutto è necessario definirla
scrivendo una definizione di classe e salvandola in un manifesto. La classe può poi essere
dichiarata per applicarla ai nodi dell’infrastruttura. Quest’operazione può essere effettuata
in modi diversi. Una possibile soluzione prevede l’utilizzo del classificatore di nodi della
PE Console, mentre un’altra prevede l’utilizzo del manifesto site.pp. Questo è il primo
manifesto che il Puppet agent controlla quando si connette al master. Esso definisce i
settaggi globali e le risorse di default che verranno applicate a tutti i nodi
dell’infrastruttura, e contiene le definizioni dei nodi (chiamate node statements), ovvero
blocchi di codice Puppet che definiscono insiemi di nodi e dichiarano quali classi devono
essere applicate ad essi.
Tornando alle classi, esse in Puppet sono singleton, ovvero una classe può essere
dichiarata una sola volta su un dato nodo.
Un esempio di definizione di classe che deve essere salvata in un opportuno manifesto
cowsay.pp nella directory ./manifests è illustrato alla pagina successiva.
24
class cowsayings::cowsay {
package { 'cowsay':
ensure => 'present',
}
}
In questo modo abbiamo definito la classe, ma non l’abbiamo dichiarata. Per fare ciò è
possibile creare un manifesto cowsay.pp nella directory ./tests ed applicarlo tramite puppet
apply, oppure utilizzare uno dei metodi menzionati in precedenza. Nel primo caso, ciò che
dovrà essere inserito nel manifesto è il seguente codice:
include cowsayings::cowsay
Puppet fornisce il tool puppet parser per controllare la sintassi di un manifesto. Il parser
non ritornerà nulla se non vi sono errori, altrimenti occorre riaprire il manifesto e
correggere il problema.
3.2.3 Moduli
I moduli sono una convenzione per organizzare i manifesti in modo che possano essere
localizzati e caricati automaticamente dal Puppet master. Essi consentono di organizzare il
codice Puppet in unità che siano testabili, riusabili e portabili, ovvero modulari. Questo
comporta che anziché scrivere da zero il codice per ogni configurazione di cui si ha
bisogno, è possibile riutilizzare e comporre tra loro moduli già esistenti. E poiché questi
moduli sono separati e indipendenti, essi risultano facili da testare, manutenere e
condividere.
I moduli possono contenere molteplici classi di Puppet, generalmente collegate tra loro.
Un modulo è una directory con uno specifico layout interno, che è localizzata in una delle
modulepath directories del Puppet master. In Puppet Enterprise la directory modulepath
principale per gli utenti si trova in /etc/puppetlabs/puppet/modules sul Puppet master
server. E’ possibile conoscere il modulepath su un sistema con Puppet utilizzando il
comando ‘puppet agent --configprint modulepath’.
25
Un esempio di modulo è il seguente:
/etc/puppetlabs/puppet/environments/production/modules/
└── apache
├── files
├── lib
├── manifests
├── spec
├── templates
└── tests
...
Le subdirectories standardizzate consentono agli utenti di Puppet e a Puppet stesso di
localizzare ognuno dei componenti che costituiscono il modulo:
 apache: la directory più esterna corrisponde al nome del modulo;
 files: contiene files statici che i nodi possono scaricare;
 lib: contiene plugins;
 manifests: contiene tutti i manifesti del modulo;
 spec: contiene tests per i plugins;
 templates: contiene i templates che i manifesti possono usare;
 tests: contiene esempi che mostrano come dichiare le classi del modulo;
I moduli e la struttura di directory degli stessi, infine, forniscono un importante mezzo per
la gestione dello scope in Puppet. Mantenendo tutto perfettamente impacchettato nel
proprio modulo, infatti, è possibile evitare più facilmente confusioni e collisioni di nomi.
26
3.2.4 Variabili e parametri di classe
La sintassi delle variabili di Puppet consente di assegnare un nome a una parte di dati, in
modo da utilizzare quel nome in un manifesto per riferirsi al valore contenuto. Nella
sintassi di Puppet, i nomi di variabile sono preceduti da un $ (segno del dollaro), e il
valore è assegnato con l’operatore = ;
Un esempio di assegnazione di una stringa a una variabile è il seguente:
$myvariable = 'look, a string!'
Una volta definita la variabile, è possibile usarla in qualsiasi parte del manifesto in cui ci si
voglia riferire al valore assegnato.
Sebbene il sistema delle variabili possa sembra simile a quello di altri linguaggi di
programmazione, esso presenta delle differenze sostanziali:
 A differenza della dichiarazione di una risorsa, in un manifesto è necessario
dichiarare la variabile prima di poterla usare;
 Se si prova a usare una variabile non definita, Puppet parser non ritornerà errori, in
quanto considererà la variabile come se contenesse il valore speciale undef.
 E’ possibile assegnare una variabile una sola volta all’interno dello stesso scope,
ovvero, una volta assegnato, il valore non può essere modificato.
La sintassi delle variabili di Puppet comprende anche meccanismi di interpolazione,
attraverso i quali è possibile inserire stringhe, memorizzate come variabili, all’interno di
altre stringhe, e meccanismi che consentono di definire il valore di una variabile in una
classe quando essa viene dichiarata anziché definita. In quest’ultimo caso si parla di
parametri di classe.
Quando si definisce una classe, è possibile inserire una lista di parametri e, opzionalmente,
di valori di default tra il nome della classe e la parentesi graffa aperta. Una classe
parametrizzata assumerà quindi la seguente forma:
class classname ( $parameter = 'default' ) {
...
}
27
Una volta definita, una classe parametrizzata può essere dichiarata con una sintassi simile
a quella della dichiarazione di una risorsa, incluse le coppie chiave valore per ogni
parametro da settare.
class {'classname':
parameter => 'value',
}
L
e classi parametrizzate sono utili nel caso in cui si voglia applicare la classe ad ogni nodo
dell’infrastruttura o a molti nodi, apportando dei cambiamenti su ogni nodo. Anziché
riscrivere l’intera classe o il modulo da zero per apportare questi cambiamenti, è possibile
usare le classi parametrizzate per modificare questi valori quando la classe viene
dichiarata.
3.2.5 Facts e conditional statements
Puppet gestisce configurazioni su molteplici sistemi differenti, quindi il codice che viene
scritto deve essere flessibile e portabile. Sebbene il resource abstraction layer faccia già
molto al fine di garantire l’adattabilità del codice, vi sono comunque degli elementi che è
opportuno lasciare alla gestione del programmatore. Puppet fornisce due strumenti
essenziali per la scrittura di codice adattabile, ovvero i facts e i conditional statements.
Il tool facter è uno strumento attraverso il quale è possibile reperire tutte le informazioni
riguardanti uno specifico nodo, come ad esempio il sistema operativo in esecuzione, la
versione di puppet installata e altre informazioni utili per la gestione del nodo. Il facter
può essere lanciato da riga di comando, e in questo caso fornisce a video le informazioni
del nodo al quale si riferisce, oppure può essere utilizzato per incapsulare le informazioni
del nodo nelle variabili nei manifesti.
Per ottenere la lista di tutti i facts disponibili attraverso il facter, occorre lanciare il
comando:
facter -p | less
28
Ogni fact che comparirà nella lista potrà essere usato nei manifesti con la sintassi
$::factname. I doppi punti ‘::’ indicano che il fact è definito nel top scope, ovvero prima
che ogni variabile nelle classi o nelle definizioni dei nodi sia assegnata. Sebbene si
possano usare i facts senza i due punti, è opportuno adottare questa sintassi al fine di
evitare collisioni di nomi, in quanto un fact potrebbe essere sovrascritto da una variabile
definita localmente.
I conditional statements ritornano valori differenti o eseguono diversi blocchi di codice
sulla base del valore di una determinata variabile. Usati in combinazione con i facts, essi
quindi permettono di scrivere codice adattabile che si comporti in maniera desiderata su
macchine che eseguono sistemi operativi differenti e che svolgono ruoli diversi
nell’infrastruttura.
Puppet supporta diversi metodi per implementare i conditional statements:

If statements;

Unless statements;

Case statements;

Selectors;
Gli if statements in Puppet sono simili a quelli presenti negli altri linguaggi di
programmazione.
Un if statement include un blocco di codice Puppet che sarà eseguito solo se la condizione
che lo precede risulta vera. Un if statement può anche contenere un numero qualsiasi di
clausole elseif e else. Le regole sono le seguenti:
 Se la if condition fallisce, Puppet si sposta sulla elseif condition (se ne esiste una);
 Se sia la if che la elseif falliscono, Puppet eseguirà il codice nel blocco else (se ne
esiste uno).
 Se tutte le condizioni falliscono e non c’è un blocco else, Puppet non farà nulla e
continuerà l’esecuzione.
29
Segue un esempio di codice:
class accounts ($name) {
if $::operatingsystem == 'centos' {
$groups = 'wheel'
}
elsif $::operatingsystem == 'debian' {
$groups = 'admin'
}
else {
fail( "This module doesn't support ${::operatingsystem}." )
}
notice ( "Groups for user ${name} set to ${groups}" )
user { $name:
ensure => 'present',
home => "/home/${name}",
groups => $groups,
}
}
Lo statement unless si comporta in maniera inversa all’if. Esso eseguirà il blocco di codice
solo se la condizione è falsa. In questo caso però non esistono gli equivalenti dell’elseif e
dell’else.
Come l’if statement, i case statements eseguono solo uno di una serie di blocchi di codice.
Essi sono costituiti da un’espressione di controllo, una lista di casi, e una serie di blocchi
di codice che corrispondono ai casi. Puppet eseguirà il primo blocco di codice il cui valore
corrisponde all’espressione di controllo.
Un esempio è il seguente:
Qcase $::operatingsystem {
u 'CentOS': { $apache_pkg = 'httpd' }
'Redhat': { $apache_pkg = 'httpd' }
e 'Debian': { $apache_pkg = 'apache2' }
'Ubuntu': { $apache_pkg = 'apache2' }
s
default: { fail("Unrecognized operating system for webserver.") }
t}
package { $apache_pkg :
ensure => present,
}
30
Questo codice in particolare consente di settare la variabile $apache_pkg in base al sistema
operativo presente sul nodo, il cui nome è noto attraverso la variabile $::operatingsystem.
I selector statements, infine, sono simili ai case statements, ma invece di eseguire un
blocco di codice, un selettore assegna direttamente un valore. Un selettore può apparire in
questo modo:
Q
$rootgroup = $::osfamily ? {
'Solaris' => 'wheel',
'Darwin' => 'wheel',
'FreeBSD' => 'wheel',
'default' => 'root',
}
Qui, il valore della variabile $rootgroup è determinato sulla base del controllo della
variabile $::osfamily.
3.2.6 Ordinamento delle risorse
Quando si ha a che fare con del codice, generalmente lo si legge dall’alto verso il basso e
lo si esegue nello stesso ordine. Nel caso di Puppet non è così. Quando Puppet lavora con
le dichiarazioni delle risorse nei manifesti, non le esegue in un ordine prefissato ma cerca
di volta in volta il modo più efficiente di agire.
Il catalogo è una lista di tutte le risorse che dovranno essere applicate a un determinato
sistema, e le relazioni tra di esse. Per alcuni tipi di risorse Puppet è intelligente abbastanza
da capire quali sono le dipendenze tra le risorse. Queste dipendenze implicite tra le risorse
sono dette autorequisiti.
Il comando utilizzato per controllare gli autorequisiti di una risorsa è puppet describe.
Eseguendo ad esempio:
puppet describe file
31
Nella descrizione della risorsa apparirà il seguente paragrafo:
Autorequires: If Puppet is managing the user or group that owns a file, the
file resource
will autorequire them. If Puppet is managing any parent directories of a file,
the file
resource will autorequire them.
Questo significa che dichiarando una risorsa di tipo file, Puppet gestirà automaticamente i
suoi autorequisiti.
Alcune volte, tuttavia, è necessario specificare a Puppet quale dichiarazione di risorsa
deve essere applicata prima di un’altra. Ad esempio, volendo dichiarare un servizio che
dovrebbe essere in esecuzione, bisogna assicurarsi che il package corrispondente sia già
installato e configurato prima di avviare il servizio.
Per ovviare al problema, la sintassi di Puppet offre diversi metodi per gestire
esplicitamente l’ordinamento delle risorse.
Uno di questi metodi consiste nel dire a Puppet quale ordinamento delle risorse adottare
attraverso l’utilizzo di metaparametri nella dichiarazione delle stesse.
I metaparametri sono attributi che possono essere settati in qualsiasi risorsa per dire a
Puppet come gestirla. Ci sono in totale quattro attributi metaparametrici che è possibile
include nella dichiarazione delle risorse per ordinare le relazioni tra le stesse.
 Before indica che la risorsa debba essere applicata prima della risorsa specificata.
 Require indica che la risorsa debba essere applicata dopo la risorsa specificata.
 Notify indica che la risorsa debba essere applicata prima della risorsa specificata,
proprio come con before. In aggiunta a ciò, notify genererà un evento di refresh per
la risorsa specificata qunado la risorsa notificante cambierà.
 Subscribe indica che la risorsa debba essere applicata dopo la risorsa specificata,
proprio come con after. In aggiunta a ciò, subscribe genererà un evento di refresh
per la risorsa sottoscrivente quando la risorsa specificata cambierà.
32
Il valore del metaparametro è il titolo o i titoli (in un array) di una o più risorse target.
Ecco un esempio di utilizzo del metaparametro notify:
file {'/etc/ntp.conf':
ensure => file,
source => 'puppet:///modules/ntp/ntp.conf',
notify => Service['ntpd'],
}
service {'ntpd':
ensure => running,
}
I
In questo esempio viene gestito il file /etc/ntp.conf. Ogni volta che il file ntp.conf cambia,
un evento di refresh sarà avviato per il servizio di nome ntpd.
Gli eventi di refresh, di default, riavviano un servizio, ma è possibile specificare cosa
dovrebbe essere fatto durante un refresh usando l’attributo refresh per il tipo di risorsa
service, il cui valore è il comando da eseguire.
33
3.3 Installazione e configurazione di Puppet open source
Come abbiamo già detto in precedenza, Puppet può essere installato su una moltitudine di
sistemi operativi differenti. La guida che verrà mostrata in questa sezione fa riferimento
all’installazione di Puppet su due macchine dotate di Ubuntu 14.04, quindi, in caso di
sistemi differenti, i comandi mostrati saranno diversi.
Prima di procedere con l’installazione è opportuno verificare che il firewall non sia
restrittivo e che consenta al master di essere raggiungibile sulla porta 8140, e che la rete
sia opportunamente configurata assegnando a ogni host un hostname univoco.
3.3.1 Creazione e configurazione del Puppet master
1. Il Puppet master, per questa guida, dovrà essere una macchina dotata di Ubuntu 14.04
e con hostname ‘puppet’. Per fare ciò, una volta avviata la macchina, è necessario
configurare il file /etc/hosts su tutte le macchine della rete e aggiungere la seguente
riga:
#IPpuppetMaster puppetmaster.example.com puppet
dove #IPpuppetMaster è l’ip del puppet master che può essere visualizzato utilizzando
il comando ifconfig sulla macchina master.
2. Installare il package NTP e configurarlo impostando i server di riferimento il più
vicino possibile al puppet master. Usare il seguente comando per l’installazione:
P
sudo apt-get update && sudo apt-get -y install ntp
Per la configurazione, invece, occorre aprire il file ntp.conf:
sudo nano /etc/ntp.conf
34
Aggiungere poi i server dalla pagina NTP Project Pool all’inizio del file:
I
server
server
server
server
0.it.pool.ntp.org
1.it.pool.ntp.org
2.it.pool.ntp.org
3.it.pool.ntp.org
Infine, riavviare il servizio per applicare le modifiche:
sudo service ntp restart
L’installazione dell’NTP è necessaria al fine di garantire che il tempo di sistema del
master sia accurato per una corretta gestione dei certificati. Certificati inviati dal
passato o dal futuro, infatti, potrebbero essere rifiutati dai nodi.
3. Scaricare e installare il package Puppet Labs:
I
wget https://apt.puppetlabs.com/puppetlabs-release-trusty.deb
sudo dpkg -i puppetlabs-release-trusty.deb
sudo apt-get update
sudo apt-get install puppetmaster-passenger
Interrompere il Puppet master fermando il servizio apache2:
sudo service apache2 stop
4. Eliminare i certificati creati in automatico durante l’installazione dei package. La
posizione di default dei certificati di Puppet è /var/lib/puppet/ssl.
Per eliminarli usare il seguente comando:
sudo rm -rf /var/lib/puppet/ssl
35
5. Configurare i certificati modificando il file di configurazione del puppet master:
I sudo nano /etc/puppet/puppet.conf
Il file conterrà il seguente testo:
M[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
[master]
# These are needed when the puppetmaster is run by passenger
# and can safely be removed if webrick is used.
ssl_client_header = SSL_CLIENT_S_DN
ssl_client_verify_header = SSL_CLIENT_VERIFY
Modificarlo eliminando la riga templatedir e aggiungendo le seguenti righe in coda
alla sezione main:
S
certname = puppet
dns_alt_names = puppet,puppetmaster.example.com
Se nel momento della connessione tra master e agent, il servizio puppet sull’agent
dovesse dare errore di certificato non trovato, allora è necessario modificare il file di
configurazione di Apache per settare il corretto nome al certificato da trovare
(/etc/apache2/sites-available/puppetmaster.conf).
6. Generare un nuovo certificato CA eseguendo il seguente comando:
i
sudo puppet master --verbose --no-daemonize
Il cui output sarà il seguente:
36
Info: Creating a new SSL key for ca
Info: Creating a new SSL certificate request for ca
Info: Certificate Request fingerprint (SHA256):
EC:7D:ED:15:DE:E3:F1:49:1A:1B:9C:D8:04:F5:46:EF:B4:33:91:91:B6:5D:19:A
C:21:D6:40:46:4A:50:5A:29
Notice: Signed certificate request for ca
...
Notice: Signed certificate request for puppet
Notice: Removing file Puppet::SSL::CertificateRequest puppet at
'/var/lib/puppet/ssl/ca/requests/puppet.pem'
Notice: Removing file Puppet::SSL::CertificateRequest puppet at
'/var/lib/puppet/ssl/certificate_requests/puppet.pem'
Notice: Starting Puppet master version 3.6.2
Premere CTRL-C per ritornare alla shell.
7. La configurazione del master è terminata e quindi occorre avviare il servizio. Prima di
fare ciò è opportuno creare un file di manifesto site.pp vuoto con il comando:
sudo touch /etc/puppet/manifests/site.pp
Avviare quindi il servizio apache2:
sudo service apache2 start
3.3.2 Creazione e configurazione del Puppet agent
1. Scaricare e installare il package Puppet Labs:
wget https://apt.puppetlabs.com/puppetlabs-release-trusty.deb
sudo dpkg -i puppetlabs-release-trusty.deb
sudo apt-get update
sudo apt-get install puppet
2. Abilitare il puppet agent. Per fare ciò, aprire il file:
e
sudo nano /etc/default/puppet
37
e modificare il valore di START a “yes”:
START=yes
3. Configurare l’agent modificando il suo file di configurazione.
sudo vi /etc/puppet/puppet.conf
Il contenuto sarà uguale a quello del file di configurazione del puppet master prima
delle modifiche. Eliminare anche qui la riga di templatedir, e tutta la sezione del master.
Aggiungere poi il seguente testo:
[agent]
server = puppetmaster.example.com
Avviare il puppet agent:
sudo service puppet start
3.3.3 Prima connessione e scambio certificati
1. Eseguire il seguente comando sul puppet agent per effettuare la prima connessione:
Apuppet agent -t
Al primo tentativo di comunicazione, l’agent invierà una richiesta di firma del
certificato al master che dovrà accettarla prima di poter controllare il nodo.
2. Eseguire il seguente comando sul puppet master per visualizzare la lista di certificati da
firmare:
sudo puppet cert list
Avendo configurato un unico nodo, la lista conterrà una sola richiesta contenente
l’hostname del nodo stesso come ad esempio:
38
N"hostnameNodo" (SHA256)
B1:96:ED:1F:F7:1E:40:53:C1:D4:1B:3C:75:F4:7C:0B:A9:4C:1B:5D:95:2B:79:C
o 0:08:DD:2B:F4:4A:36:EE:E3
Non vi sarà alcun ‘+’ davanti ad essa. Questo indica che non è stata ancora firmata.
3. Per firmare la richiesta, eseguire il seguente comando sul puppet master:
sudo puppet cert sign hostnameNodo
L’output sarà il seguente:
Notice: Signed certificate request for hostnameNodo
Notice: Removing file Puppet::SSL::CertificateRequest hostnameNodo at
'/var/lib/puppet/ssl/ca/requests/hostnameNodo.pem'
L’infrastruttura è ora perfettamente configurata per essere gestita da Puppet.
39
3.4 Esempi di funzionamento di Puppet
3.4.1 Utilizzo dei facts
Ora che l’infrastruttura è stata configurata, è possibile verificarne il corretto
funzionamento attraverso l’esecuzione di semplici manifesti. Come abbiamo detto in
precedenza, il file di manifesto principale sul Puppet master è collocato in
/etc/puppet/manifests/site.pp.
Aprirlo sul master:
sudo nano /etc/puppet/manifests/site.pp
Aggiungere le seguenti righe di codice:
S file {'/tmp/example-ip':
ensure => present,
mode
=> 0644,
content => "Questo è il mio indirizzo IP pubblico:
${ipaddress_eth0}.\n",
}
Salvare il file e chiuderlo. Queste linee di codice servono a specificare che ogni nodo
dovrà avere un file di testo di nome /tmp/example-ip, con i permessi –rw–r—r--, e
contenente l’IP pubblico del nodo.
Applicare le modifiche ai nodi eseguendo il comando sudo puppet agent –test da uno
dei nodi, oppure attendere che essi richiedano automaticamente il catalogo al master.
Per stampare il contenuto del file a video eseguiamo il seguente comando da un nodo:
L
cat /tmp/example-ip
L’output dovrebbe essere simile al seguente:
Questo è il mio indirizzo IP pubblico: 192.128.182.133
40
3.4.2 Specifica dei nodi
Se si vuole definire una risorsa per dei nodi in particolare e non per tutti, è necessario
definire un nodo nel manifesto.
Sul master, aprire il site.pp:
sudo vi /etc/puppet/manifests/site.pp
Aggiungere le seguenti righe di codice:
S
node 'ns1', 'ns2' {
file {'/tmp/dns':
ensure => present,
mode => 0644,
content => "Solo i server DNS possiedono questo file.\n",
}
}
node default {}
Salvare e uscire. Queste linee di codice specificano che solo i nodi di nome ‘ns1’ e ‘ns2’
dovranno avere un file di nome /tmp/dns contenente il testo indicato in content.
Come prima, applicare le modifiche ai nodi con il comando sudo puppet agent –test
da uno dei nodi interessati, oppure attendere che essi richiedano automaticamente il
catalogo al master.
Per stampare il contenuto del file a video eseguiamo il seguente comando da un nodo:
L
cat /tmp/dns
L’output sarà il seguente:
Solo i server DNS possiedono questo file.
41
3.4.3 Utilizzo di un modulo
Proviamo adesso ad utilizzare un modulo disponibile sul Puppet Forge Marketplace:
Apache. Per installarlo, eseguire sul Puppet master il seguente comando:
Msudo puppet module install puppetlabs-apache
Modificare il site.pp:
A
sudo nano /etc/puppet/manifest/site.pp
Aggiungere le seguenti righe per installare Apache sul nodo #hostdesiderato.
S node '#hostdesiderato' {
class { 'apache': }
apache::vhost { 'example.com':
port
=> '80',
docroot => '/var/www/html'
}
}
Salvare e uscire. La prossima volta che Puppet aggiornerà l’ #hostdesiderato, esso
installerà il package Apache e configurerà un virtual host chiamato “example.com” con le
specifiche descritte nel codice.
Per aggiornare l’host subito, eseguire il seguente comando dall’host in questione:
N
sudo puppet agent --test
Nell’output dovrebbero comparire diverse righe che indicano che Apache sta venendo
installato sul nodo. Una volta terminato, se tutto è stato fatto correttamente, è possibile
recarsi all’indirizzo IP pubblico del nodo attraverso un qualsiasi browser, per visualizzare
la pagina di benvenuto di Apache.
42
3.4.4 Configurare un virtual host Apache
Nel precedente esempio abbiamo visto come è possibile utilizzare il modulo di apache per
visualizzare la pagina di benvenuto dello stesso utilizzando un nodo della rete. In questo
paragrafo invece, utilizzeremo lo stesso modulo per hostare una pagina web di nostro
gradimento, salvata in forma di file html e di files ad esso associati. L’esempio prenderà
come riferimento la homepage di puppetlabs, ovvero https://puppetlabs.com/.
Per iniziare è necessario collegarsi al sito https://puppetlabs.com/ e salvare la pagina web
utilizzando come nome ‘index’ per semplificare il codice. Verranno creati un file
‘index.html’ e una cartella ‘index_files’ contenente tutti i files necessari alla corretta
visualizzazione della pagina.
Per hostare la pagina salvata è necessario definire una propria classe. Per fare ciò, occorre
creare le directories opportune con i seguenti comandi:
A sudo mkdir –p /etc/puppet/modules/sito/manifests
sudo mkdir –p /etc/puppet/modules/sito/files
Aprire il file init.pp con il seguente comando:
Dsudo nano /etc/puppet/modules/sito/manifests/init.pp
Definire la classe nel seguente modo:
C class sito{
class{‘apache’:
default_vhost => false,
}
apache::vhost {‘prova.com’:
port => ‘80’,
docroot=> ‘/var/www/sito’
}
file {‘/var/www/sito/index_files’:
ensure => directory,
mode => ‘0644’,
source => ‘puppet:///modules/sito/index_files’,
recurse => remote,
}
file {‘/var/www/sito/index.html’:
ensure => present,
mode => ‘0644’,
source => ‘puppet:///modules/sito/index.html’,
}
}
43
Copiare i files necessari ad hostare il sito, dalla cartella in cui sono stati salvati alla cartella
‘files’ del relativo modulo:
A
sudo cp –r /home/osboxes/Downloads/index.html
etc/puppet/modules/sito/files/
sudo cp –r /home/osboxes/Downloads/index_files
/etc/puppet/modules/sito/files/
Aprire il file site.pp con il seguente comando:
A
sudo nano /etc/puppet/manifests/site.pp
Aggiungere le seguenti righe per specificare il nodo cui applicare la classe:
I
node ‘#hostdesiderato’{
include sito
}
In questo modo la classe sito sarà applicata al nodo #hostdesiderato.
Per applicare le modifiche, infine, eseguire il seguente comando dal nodo in questione:
S
sudo puppet agent -t
See tutto è stato effettuato correttamente, collegandosi all’indirizzo ip pubblico
dell’#hostdesiderato, sarà possibile visualizzare la homepage del sito della Puppetlabs.
44
Conclusioni
Il processo di automatizzazione che ha colpito la nostra società in questi ultimi anni è stato
sia una conseguenza sia un requisito dello sviluppo e della grande crescita delle
infrastrutture IT, che costituiscono la base di ogni azienda moderna. Senza i software di
gestione automatica delle configurazioni, sarebbe risultato ostico se non impossibile
riuscire a gestire in maniera efficace ed efficiente reti costituite da un enorme e sempre
crescente numero di macchine. Lo scopo di questo elaborato è stato, quindi, quello di
analizzare e far conoscere le piattaforme ed i tools maggiormente utilizzati per la gestione
ed il mantenimento di piccole e grandi infrastrutture IT e di rendere il lettore più familiare
con una tecnologia che in futuro potrebbe riguardarlo più da vicino ed integrarsi con la sua
vita quotidiana.
Automatizzazione è stata e sarà ancora per molto la parola chiave dello sviluppo
tecnologico che ha visto e che vedrà protagonista la nostra società negli anni a venire.
45
Bibliografia
[1]
What is Puppet?,
http://puppetlabs.com/puppet/what-is-puppet, 18 Giugno 2015
[2]
What is DevOps?,
http://devops.com/category/features/, 22 Giugno 2015
[3]
IBM,
http://www.ibm.com/developerworks/devops/index.html, 23 Giugno 2015
[4]
Google Cloud,
https://cloud.google.com/solutions/google-compute-engine-management-puppet-chef-saltansible, 25 Giugno 2015
[5]
SaltStack,
http://www.saltstack.com/, 27 Giugno 2015
[6]
Ansible,
http://www.ansible.com/home, 27 Giugno 2015
[7]
Chef,
http://www.getchef.com/chef/, 28 Giugno 2015
[8]
Puppet 3.8 Reference Manual,
http://docs.puppetlabs.com/puppet/3.8/reference/, 2 Luglio 2015
[9]
Puppet forge Apache,
https://forge.puppetlabs.com/puppetlabs/apache, 14 Luglio 2015
46