Guida introduttiva alla gestione dei server con Puppet
Introduzione
Puppet è un'utility open source per la gestione della configurazione che consente all'utente di gestire automaticamente e, se necessario, anche da remoto più sistemi e la loro configurazione. Puppet è dichiarativo, il che significa che l'utente deve solo richiedere uno stato del servizio o della risorsa e non deve realmente pensare a come questo stato verrà raggiunto.
In altre parole, immagina di essere un amministratore di sistema che gestisce centinaia di sistemi e di dover assicurarti che quella determinata risorsa come hello
package sia installata. Per ottenere questo risultato in un modo tradizionale di amministrazione del sistema, l'utente amministratore dovrà sottoporsi a molteplici controlli come lo stato attuale dell'installazione del pacchetto, il tipo di piattaforma del sistema operativo, il comando di installazione da utilizzare prima che l'installazione effettiva del pacchetto abbia luogo. Essendo puppet un dichiarativo, l'utente deve solo definire lo stato del pacchetto desiderato e il burattino si occuperà del resto. Nel caso in cui il nostro pacchetto "hello" sia installato, puppet non intraprenderà alcuna azione, mentre se il pacchetto non è installato lo installerà.
Scenario
Nel nostro scenario non eseguiremo centinaia di sistemi operativi e tenteremo di gestirli. Il nostro obiettivo sarà molto più semplice di così. In realtà eseguiremo solo due sistemi separati che eseguono puppet master e puppet agent. Pertanto, attraverso il server puppet master, tenteremo di configurare un nodo remoto e installare il pacchetto "hello" utilizzando l'agente puppet. Questa operazione verrà eseguita con una configurazione minima possibile.
Terminologia
- puppet master – server centrale che ospita e compila tutti i manifesti di configurazione dell'agente
- Puppet Agent – Un servizio che viene eseguito su Node e controlla periodicamente lo stato di una configurazione con Master Puppet Server e recupera un manifesto di configurazione aggiornato
- manifest: file di configurazione che viene scambiato tra puppet muster e puppet agent
- Node: un sistema operativo su cui viene eseguito il servizio Puppet
Impostazioni dello scenario
In questo tutorial farò riferimento a entrambi gli host semplicemente come master
e node1
. Il sistema operativo utilizzato sia sulle istanze master
che su quelle node1
è Debian 8 Jessie. Ubuntu Linux può anche essere utilizzato come alternativa per seguire questo tutorial. La configurazione di rete sottostante è irrilevante. Tuttavia, si prevede che il nodo1
sia in grado di risolvere l'host master
in base al nome ed entrambi gli host siano connessi e che vengano applicate le impostazioni del firewall appropriate per consentire la comunicazione tra il puppet master
e l'agente del nodo1
:
root@node1:/# ping -c 1 master
PING master (172.17.0.1): 56 data bytes
64 bytes from 172.17.0.1: icmp_seq=0 ttl=64 time=0.083 ms
--- master ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.083/0.083/0.083/0.000 ms
NOTA: Leggi l'appendice su come configurare facilmente lo scenario precedente con Docker.
Installazione e configurazione di Pupper Master
Cominciamo con l'installazione del burattinaio:
root@master:~# apt-get install puppetmaster-passenger
Il comando precedente installerà Puppet insieme ad Apache e Passenger. Pertanto, invece di utilizzare il tipico server WEBrick, coinvolgeremo Apache Passenger per eseguire puppet master sulla porta 8140
. Il file di configurazione predefinito e generato automaticamente di Apache Passenger si trova in /etc/apache2/sites-available/puppetmaster.conf
:
This Apache 2 virtual host config shows how to use Puppet as a Rack
application via Passenger. See
http://docs.puppetlabs.com/guides/passenger.html for more information.
You can also use the included config.ru file to run Puppet with other Rack
servers instead of Passenger.
you probably want to tune these settings
PassengerHighPerformance on
PassengerMaxPoolSize 12
PassengerPoolIdleTime 1500
PassengerMaxRequests 1000
PassengerStatThrottleRate 120
Listen 8140
SSLEngine on
SSLProtocol ALL -SSLv2 -SSLv3
SSLCipherSuite EDH+CAMELLIA:EDH+aRSA:EECDH+aRSA+AESGCM:EECDH+aRSA+SHA384:EECDH+aRSA+SHA256:EECDH:+CAMELLIA256:+AES256:+CAMELLIA128:+AES128:+SSLv3:!aNULL:!eNULL:!LOW:!3DES:!MD5:!EXP:!PSK:!DSS:!RC4:!SEED:!IDEA:!ECDSA:kEDH:CAMELLIA256-SHA:AES256-SHA:CAMELLIA128-SHA:AES128-SHA
SSLHonorCipherOrder on
SSLCertificateFile /var/lib/puppet/ssl/certs/master.pem
SSLCertificateKeyFile /var/lib/puppet/ssl/private_keys/master.pem
SSLCertificateChainFile /var/lib/puppet/ssl/certs/ca.pem
SSLCACertificateFile /var/lib/puppet/ssl/certs/ca.pem
# If Apache complains about invalid signatures on the CRL, you can try disabling
# CRL checking by commenting the next line, but this is not recommended.
SSLCARevocationFile /var/lib/puppet/ssl/ca/ca_crl.pem
# Apache 2.4 introduces the SSLCARevocationCheck directive and sets it to none
# which effectively disables CRL checking; if you are using Apache 2.4+ you must
# specify 'SSLCARevocationCheck chain' to actually use the CRL.
# SSLCARevocationCheck chain
SSLVerifyClient optional
SSLVerifyDepth 1
# The `ExportCertData` option is needed for agent certificate expiration warnings
SSLOptions +StdEnvVars +ExportCertData
# This header needs to be set if using a loadbalancer or proxy
RequestHeader unset X-Forwarded-For
RequestHeader set X-SSL-Subject %{SSL_CLIENT_S_DN}e
RequestHeader set X-Client-DN %{SSL_CLIENT_S_DN}e
RequestHeader set X-Client-Verify %{SSL_CLIENT_VERIFY}e
DocumentRoot /usr/share/puppet/rack/puppetmasterd/public/
RackBaseURI /
Options None
AllowOverride None
Order allow,deny
allow from all
Guardando il file di configurazione sopra possiamo notare un numero di certificati SSL generati automaticamente in base al nome host del sistema. Verifica che tutti i percorsi dei certificati elencati puntino a un certificato SSL puppet corretto. In caso contrario, sarà necessario generare nuovi certificati SSL. Se è necessario generare prima nuovi certificati, rimuovere i certificati correnti:
root@master:~# rm -rf /var/lib/puppet/ssl
Quindi, esegui puppet in primo piano per vedere i tuoi nuovi certificati da generare. Al termine, interrompere il processo con la combinazione di tasti CTRL+C:
root@master:~# puppet master --verbose --no-daemonize
Info: Creating a new SSL key for ca
Info: Creating a new SSL certificate request for ca
Info: Certificate Request fingerprint (SHA256): FA:D8:2A:0F:B4:0B:91:8C:01:AD:71:B4:49:66:1F:B1:38:BE:A4:4E:AF:76:16:D2:97:50:C8:A3:8F:35:CC:F2
Notice: Signed certificate request for ca
Info: Creating a new certificate revocation list
Info: Creating a new SSL key for master
Info: csr_attributes file loading from /etc/puppet/csr_attributes.yaml
Info: Creating a new SSL certificate request for master
Info: Certificate Request fingerprint (SHA256): 43:67:42:68:64:73:83:F7:36:2B:2E:6F:06:20:65:87:AB:61:96:2A:EB:B2:91:A9:58:8E:3F:F0:26:63:C3:00
Notice: master has a waiting certificate request
Notice: Signed certificate request for master
Notice: Removing file Puppet::SSL::CertificateRequest master at '/var/lib/puppet/ssl/ca/requests/master.pem'
Notice: Removing file Puppet::SSL::CertificateRequest master at '/var/lib/puppet/ssl/certificate_requests/master.pem'
Notice: Starting Puppet master version 3.7.2
^CNotice: Caught INT; calling stop
Prima di avviare il nostro puppet master, dobbiamo prima creare un manifesto di configurazione vuoto predefinito:
root@master:~# > /etc/puppet/manifests/site.pp
Tutto è pronto per abilitare l'avvio del burattinaio dopo il riavvio:
root@master:~# systemctl enable apache2
Synchronizing state for apache2.service with sysvinit using update-rc.d...
Executing /usr/sbin/update-rc.d apache2 defaults
Executing /usr/sbin/update-rc.d apache2 enable
e avvia puppet master avviando Apache WebServer:
root@master:~# service apache2 start
[ ok ] Starting web server: apache2.
root@master:~#
Verifica che il pupazzo sia in esecuzione
ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 20228 2016 ? Ss 11:53 0:00 /bin/bash
root 1455 0.0 0.0 98272 4600 ? Ss 12:40 0:00 /usr/sbin/apache2 -k start
root 1458 0.0 0.0 223228 1920 ? Ssl 12:40 0:00 PassengerWatchdog
root 1461 0.0 0.0 506784 4156 ? Sl 12:40 0:00 PassengerHelperAgent
nobody 1466 0.0 0.0 226648 4892 ? Sl 12:40 0:00 PassengerLoggingAgent
www-data 1476 0.0 0.0 385300 5116 ? Sl 12:40 0:00 /usr/sbin/apache2 -k start
www-data 1477 0.0 0.0 450880 5608 ? Sl 12:40 0:00 /usr/sbin/apache2 -k start
root 1601 0.0 0.0 17484 1140 ? R+ 12:44 0:00 ps aux
e in ascolto sulla porta 8140
:
netstat -ant
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp6 0 0 :::8140 :::* LISTEN
tcp6 0 0 :::80 :::* LISTEN
tcp6 0 0 :::443 :::* LISTEN
Configurazione del nodo Puppet
Al momento il nostro server master è in esecuzione e si aspetta richieste dall'agente puppet e quindi è il momento di installare il nostro agente puppet sul node1
:
apt-get install puppet
Successivamente, dobbiamo configurare puppet in modo che agisca come agente rimuovendo tutte le direttive predefinite del server master dal suo file di configurazione /etc/puppet/puppet.conf
:
DA:
[main]
logdir=/var/log/puppet
vardir=/var/lib/puppet
ssldir=/var/lib/puppet/ssl
rundir=/var/run/puppet
factpath=$vardir/lib/facter
prerun_command=/etc/puppet/etckeeper-commit-pre
postrun_command=/etc/puppet/etckeeper-commit-post
[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
A:
[main]
logdir=/var/log/puppet
vardir=/var/lib/puppet
ssldir=/var/lib/puppet/ssl
rundir=/var/run/puppet
factpath=$vardir/lib/facter
prerun_command=/etc/puppet/etckeeper-commit-pre
postrun_command=/etc/puppet/etckeeper-commit-post
[agent]
server = master
La direttiva server = master
di cui sopra definisce un server master a cui deve connettersi l'agente puppet. Dove word master
nel nostro caso come nome host che si risolve nell'indirizzo IP del server master:
ping -c 1 master
PING master (172.17.0.43): 56 data bytes
64 bytes from 172.17.0.43: icmp_seq=0 ttl=64 time=0.226 ms
--- master ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.226/0.226/0.226/0.000 ms
La parte di installazione è terminata e ciò che resta è abilitare l'avvio del pupazzo dopo il riavvio e l'avvio del pupazzo:
systemctl enable puppet
Synchronizing state for puppet.service with sysvinit using update-rc.d...
Executing /usr/sbin/update-rc.d puppet defaults
Executing /usr/sbin/update-rc.d puppet enable
root@node1:/# service puppet start
[ ok ] Starting puppet agent.
Inoltre, per impostazione predefinita, l'agente è disabilitato dopo l'installazione su nuovi host non coconfigurati. Per abilitare l'agente puppet dobbiamo eseguire:
root@node1:/# puppet agent --enable
Certificato dell'agente di firma
Sia il master
host che il nodo1
sono attivi e in esecuzione. L'ultimo set di configurazione necessario per far comunicare sia il master che l'agente consiste nel firmare la richiesta di certificato di node1
. Dopo aver avviato l'agente puppet sul nodo 1
, è stata inviata una richiesta di firma del certificato al server master
:
root@master:/# puppet cert list
"node1" (SHA256) 2C:62:B3:A4:1A:66:0A:14:17:93:86:E4:F8:1C:E3:4E:25:F8:7A:7C:FB:FC:6B:83:97:F1:C8:21:DD:52:E4:91
Per impostazione predefinita, ogni richiesta di firma del certificato deve essere firmata manualmente:
root@master:/# puppet cert sign node1
Notice: Signed certificate request for node1
Notice: Removing file Puppet::SSL::CertificateRequest node1 at '/var/lib/puppet/ssl/ca/requests/node1.pem'
In questa fase, il nostro master dovrebbe ospitare due certificati firmati:
root@master:/# puppet cert list --all
+ "master" (SHA256) EE:E0:0A:5C:05:17:FA:11:05:E8:D0:8C:29:FC:D2:1F:E0:2F:27:A8:66:70:D7:4B:A1:62:7E:BA:F4:7C:3D:E8
+ "node1" (SHA256) 99:DC:41:BA:26:FE:89:98:DC:D6:F0:34:64:7A:DF:E2:2F:0E:84:48:76:6D:75:81:BD:EF:01:44:CB:08:D9:2A
Attivazione della richiesta di configurazione del pupazzo
È il momento di creare un primo manifesto di configurazione. Come già accennato in precedenza, ora ci assicureremo che il pacchetto hello
sia disponibile su node1
. Apri un file manifest predefinito /etc/puppet/manifests/site.pp
sugli host master
e aggiungi la seguente configurazione semplicistica del nodo:
package { "hello":
ensure => "installed"
}
Il nostro agente sul node1
è impostato per impostazione predefinita per recuperare la configurazione del master ogni 30 minuti. Se non vogliamo aspettare, possiamo attivare manualmente la richiesta di configurazione:
root@node1:/# hello
bash: hello: command not found
Il pacchetto hello non è attualmente disponibile in node1
. Attiva manualmente la nuova richiesta di configurazione:
root@node1:/# puppet agent --test
Info: Caching certificate_revocation_list for ca
Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Caching catalog for node1
Info: Applying configuration version '1434159185'
Notice: /Stage[main]/Main/Package[hello]/ensure: ensure changed 'purged' to 'present'
Info: Creating state file /var/lib/puppet/state/state.yaml
Notice: Finished catalog run in 4.00 seconds
Dall'output precedente possiamo vedere che è stata applicata una nuova configurazione e che il pacchetto "hello" è ora disponibile:
root@node1:/# hello
Hello, world!
Conclusione
Il testo sopra mostrava una procedura di configurazione semplicistica del burattino. Tuttavia, dovrebbe fungere da punto di partenza per le distribuzioni multi-nodo. Per aggiungere altri nodi, è sufficiente rivedere la sezione Configurazione del nodo Puppet
precedente e le sezioni Certificato dell'agente di firma
di questo articolo.
Risoluzione dei problemi
apache2: Impossibile determinare in modo affidabile il nome di dominio completo del server, utilizzando 172.17.0.43. Impostare la direttiva 'ServerName' a livello globale per sopprimere questo messaggio
echo "ServerName `hostname`" >> /etc/apache2/apache2.conf
Avviso: Salto dell'esecuzione del client di configurazione Puppet; disabilitato a livello amministrativo (motivo: "Disabilitato per impostazione predefinita su installazioni nuove o vecchie non configurate");
Usa 'puppet agent –enable' per riattivare.
root@node1:/# puppet agent --enable
Appendice
Impostazioni rapide dello scenario con Docker
linuxconfig/sandbox
è un'immagine docker contenente una base di strumenti di modifica del testo e di rete per aiutarti a configurare e risolvere i problemi del tuo puppet master e agent.
Primo inizio burattinaio:
docker run -it -h master --name=master linuxconfig/sandbox /bin/bash
Una volta che il puppet master è attivo e funzionante, avvia node1
:
docker run -it -h node1 --name=node1 --link master:master linuxconfig/sandbox /bin/bash