Il post di oggi vorrei usarlo per tenere traccia di alcune metodologie che sto usando per il provisioning di stack pesanti e che richiedono tempi lunghissimi.
Il software interessato rientra nella categoria del “monolite”. Lo stack monolitico è una sorta di amico enorme e per portarlo in giro bisogna prendere determinate precauzioni.
È tipo Zangief…
Per il raggiungimento del risultato finale, ovvero il bootstrap di ambienti completi, sto implementando un giro di provisioning fatto da cookbook Chef, script shell e Rubygem custom.
Alcuni ostacoli del progetto:
- Per un provisioning completo ci vogliono più di 3 ore
- La fase di installazione e configurazione è composta da centinaia di esecuzioni di script, chiamate a servizi REST e numerosi riavvii di servizi systemd. Tutto deve essere rigorosamente idempotente.
- Gli errori durante il provisioning sono da evitare assolutamente. Ripartire nel mezzo dell’installazione non è mai come partire da zero.
La scelta del provisioner e per cosa usarlo
Di base, a meno che non ci siano vincoli progettuali, siamo in grado di fare quasi tutto con i più importanti configuration management tool come Chef, Puppet e Ansible.
È importante capire cosa far fare al provisioner e cosa no. Alcune operazioni che sono specifiche per il mio ambiente di laboratorio le metto tranquillamente in blocchi shell script (che alla fine è anch’esso un provisioner di Vagrant)
$script = <<-SCRIPT echo I am provisioning... date > /etc/vagrant_provisioned_at SCRIPT Vagrant.configure("2") do |config| config.vm.provision "shell", inline: $script end
Per usare o meno un proxy può essere utile una semplice variabile d’ambiente.
if ENV['NO_CUSTOMER_PROXY'] config.vm.provision 'shell', inline: '> /etc/profile.d/proxy.sh' config.vm.provision 'shell', inline: '> /etc/environment' else config.proxy.http = 'http://CUSTOMER.PROXY.LOCAL:8080' config.proxy.https = 'http://CUSTOMER.PROXY.LOCAL:8080' config.proxy.no_proxy = '' end
Roadmap delle box
Il punto è che non vogliamo fare e rifare il lunghissimo provisioning tutte le volte ma poter “debuggare” stati diversi della macchina.
Per esempio, nel caso esistano i seguenti possibili stati:
- macchina con prerequisiti installati, aggiornamenti OS e personalizzazioni.
- macchina con monolite installato.
- macchina con monolite configurato.
- macchina con applicazioni del monolite configurate.
Rifare tutto da zero può richiedere parecchio tempo per cui ho utilizzato il “package” di Vagrant…
vagrant package --base $id --output os_ok.box; vagrant box os_ok.box
vagrant package --base $id --output monolite_ok.box; vagrant box add monolite_ok.box
vagrant package --base $id --output monolite_configurato.box; vagrant box monolite_configurato.box
vagrant package --base $id --output monolite_con_applicazioni_configurate.box; vagrant box add monolite_con_applicazioni_configurate.box
All’occorrenza, nel Vagrantfile e nel bocco relativo alla vm, ho usato la box che mi serviva in determinato punto.
Archivi pesanti in /vagrant
Durante il provisioning ho avuto bisogno di scaricare da locazioni remote archivi anche di grandi dimensioni.
Questo durante le prove non è performante per cui i puntamenti, dei ruoli Chef nel mio caso, sono tutti verso src: “file:////vagrant/foo.tar.gz”. Naturalmente è opportuno dichiararli nel .gitignore.
Ciao