Breve corso di Vagrant – Puntata 1

Vagrant Stack-LAMP

Vagrant Stack-LAMP

Dopo aver gia scritto in precedenti articoli di Vagrant ho sentito l’esigenza di metter, come si suol dire, nero su bianco un piccolo corso/progetto da portare avanti su queste pagine in cui verra’ spiegato non solo l’uso piu’ avanzato di Vagrant ma anche alcuni concetti fondamentali inerenti la creazione di un servizio WEB moderno, introducendo i concetti di “scalabilita’” e di “high availability“.

Iniziamo con un breve elenco dei comandi di vagrant usati più comunemente :
vagrant init [nome-box] [url-box] = inizializza la directory corrente come ambiente per Vagrant e crea il file di configurazione Vagrantfile
vagrant up = crea, configura e avvia la macchina virtuale definita in Vagrantfile . Se la macchina virtuale già esiste, la fa solo partire
vagrant halt <nome macchina> = ferma una macchina virtuale
vagrant destroy = elimina la macchina virtuale
vagrant ssh <nome macchina> = si collega alla macchina virtuale via ssh

Nel seguente esempio verra’ creata una directory che conterra’ il progetto di Vagrant, poi, inizializzemo il progetto, configureremo una macchina virtuale, la lanceremo e infine ci collegheròemo. I seguenti comandi creeranno una macchina virtuale con Ubuntu 14.04 (64bit). Notate che la prima volta che eseguirete questa serie di comandi, verrà scaricata dalla rete un’immagine del sistema operativo Ubuntu. Per farlo ci potranno volere svariati minuti, a seconda anche del tipo di connessione ADSL di cui disponete. Le volte successive, il processo sara’ molto più rapido, perché l’immagine usata per creare la macchina virtuale sarà già stata memorizzata nel vostro sistema.

PARTIAMO
Questi sono i primi comandi che useremo: vagrant init ubuntu/trusty64  &  vagrant up

<> vagrant init ubuntu/trusty64
A `Vagrantfile` has been placed in this directory. You are now
ready to `vagrant up` your first virtual environment! Please read
the comments in the Vagrantfile as well as documentation on
`vagrantup.com` for more information on using Vagrant.

<> vagrant up
Bringing machine ‘default’ up with ‘virtualbox’ provider…
==> default: Box ‘ubuntu/trusty64’ could not be found. Attempting to find and install…
default: Box Provider: virtualbox
default: Box Version: >= 0
==> default: Loading metadata for box ‘ubuntu/trusty64’
default: URL: https://atlas.hashicorp.com/ubuntu/trusty64
==> default: Adding box ‘ubuntu/trusty64’ (v20151214.0.0) for provider: virtualbox
default: Downloading: https://atlas.hashicorp.com/ubuntu/boxes/trusty64/versions/20151214.0.0/providers/virtualbox.box
default: Progress: 6% (Rate: 115k/s, Estimated time remaining: 0:43:23)))
==> default: Preparing network interfaces based on configuration…
default: Adapter 1: nat
==> default: Forwarding ports…
default: 22 => 2222 (adapter 1)
==> default: Booting VM…
==> default: Waiting for machine to boot. This may take a few minutes…
default: SSH address: 127.0.0.1:2222
default: SSH username: vagrant
default: SSH auth method: private key
…………..etc etc !!

> vagrant ssh
Welcome to Ubuntu 14.04.3 LTS (GNU/Linux 3.13.0-73-generic x86_64)

* Documentation: https://help.ubuntu.com/

System information disabled due to load higher than 1.0

Get cloud support with Ubuntu Advantage Cloud Guest:
http://www.ubuntu.com/business/services/cloud

vagrant@vagrant-ubuntu-trusty-64:~$ ifconfig
eth0 Link encap:Ethernet HWaddr 08:00:27:6b:55:0f
inet addr:10.0.2.15 Bcast:10.0.2.255 Mask:255.255.255.0
inet6 addr: fe80::a00:27ff:fe6b:550f/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:544 errors:0 dropped:0 overruns:0 frame:0
TX packets:392 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:69053 (69.0 KB) TX bytes:53324 (53.3 KB)

lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

vagrant@vagrant-ubuntu-trusty-64:~$ exit

Dato che il nostro obiettivo è arrivare ad avere uno Stack LAMP, sappiamo che dovremo tenere conto di dover ancora installare e configurare gli altri software necessari ossia,  Apache, MySQL e PHP. Ci sono però anche altri componenti meno ovvi di cui va tenuto conto. Iniziamo studiando lo stack LAMP su di un modello di web application 2.0. Vediamo quindi di spiegare alcuni concetti fondamentali per questo tipo di architetture che vanno decisi prima d’iniziare a creare fisicamente le macchine/server che ci servono.

Scalabilità VS Disponibilità

Scalabilità verticale
Si può scalare un sistema senza aumentarne la disponibilità o il tempo di uptime. Esemplifichiamo, diciamo che vogliate gestire più utenti, più traffico e più carico per l’applicazione web, se si tratta di un server fisico, potreste spegnerlo, installare più memoria e potenziare la CPU, ad esempio. Potreste anche copiare tutti i dati da un solo piccolo server ad un server più grande che abbia più memoria, una CPU più potente e dischi più veloci. Se invece state usando un server virtuale, potreste fermarlo, allocare maggiori risorse e riavviarlo. Se il server è posizionato nel cloud, potrete cambiare il tipo di istanza ad uno che abbia più risorse. Questo si chiama scalare verticalmente. Non c’è niente di male in questo tipo di scalabilità, soprattutto se avete applicazioni in cui il tempo di fermo e’ accettabile.

Scalabilità orizzontale
Un’ altro modo per scalare è di aggiungere altri server, che a volte vengono indicati con il termine di nodi. Questo si chiama scalabilità orizzontale. Per scalare orizzontalmente, si deve fare prima un po’ di lavoro in anticipo, e progettare bene la transizione. Per andare ad esempio da un server web a due, dovrete trovare un modo per instradare il traffico al nodo aggiuntivo, e preferibilmente suddividere il carico tra i due server. Se vi servono più risorse, aggiungete un terzo server,  un quarto, un quinto e cosi’ via. Quando invece avete un solo server, e questo va giù, il servizio si interrompe, ma se avete più di un server che fanno gestiscono la stessa funzione, e uno di loro ha un malfunzionamento, lo scenario peggiore è che il servizio è degradato e non altrettanto prestante come di solito. Lo scenario migliore avviene quando un singolo malfunzionamento non viene nemmeno notato.

Il meglio di entrambi i mondi
In molti casi ha senso scalare il server web in modo orizzontale, e il server di database in modo verticale. Vedremo piu’ avanti, nei prossimi articoli, come prendere il meglio di entrambi i mondi, eliminando, o almeno riducendo moltissimo, il tempo di fermo per il servizio.

Nel secondo capitolo inizieremo la configurazione del file Vagrant per la preparazione delle 5 macchine necessarie al nostro progetto.

Stay Tuned !

Le novita’ di Debian 8

Debian 8 Jessie

Debian 8 Jessie

Il 25 aprile 2015 è stato annunciato il rilascio di Debian 8 (alias Jessie), che e’ l’ultima versione di uno dei più noti ed apprezzati sistemi operativi basati su Linux. Questo rilascio, atteso da moltissimi utenti e da altrettante aziende, porta con sè alcune novità significative, frutto di un lavoro di sviluppo durato circa due anni, e culminato in un sistema operativo che sarà supportato fino al 2020.

In questo articolo vedremo le principali novità introdotte su Debian 8, di cui è possibile effettuare il download direttamente dal sito ufficiale del progetto.

Una distribuzione universale
Debian, ad oggi vanta una vasta gamma di pacchetti software (circa 43 mila), che consentono a chiunque di personalizzarla a proprio piacimento, in base al tipo di applicazione per cui questo sistema sarà utilizzato: dai server alle workstation, passando per il cloud, i mainframe o le board che implentano l’Internet of Things.

L’idea della distribuzione universale, adatta a tanti contesti, ha spinto negli anni la comunità open source a creare un gran numero di derivate (ed il caso più noto risponde al nome di Ubuntu). Il fatto che molti sistemi Linux si basino su Debian aumenta quindi l’importanza di ogni aggiornamento apportato a questa distribuzione in ogni rilascio, dal momento che ciò si ripercuote su tutte le sue derivate (ufficiali e non).

Il passaggio a systemd
La novità più significativa, che ha creato molti dibattiti accesi, introdotta con Debian 8, riguarda il passaggio definitivo a systemd quale sistema di init principale, sebbene sia possibile utilizzare sysvinit come alternativa. Tale scelta trova le sue motivazioni nella riduzione dei tempi di avvio ed arresto del sistema, sebbene non tutti gli utenti sembrano convinti di ciò. Inoltre, systemd non si occupa solo della fase di boot: in quanto gestore di sistema, esso incorpora anche la gestione di diverse altre funzioni (alimentazione, dispositivi, login, eccetera), con conseguenze che potrebbero comportare, ad esempio, la necessità di riavviare il sistema in caso di aggiornamento. Un problema significativo per una distribuzione server, dovuto proprio a systemd. Il problema piu’ grande sorge per via del fatto che oggettivamente, l’attuale sistema usato, SysVInit, è oggettivamente un sistema antiquato, con un elenco di noti difetti, il principale dei quali è sicuramente la grande lentezza derivante dall’approccio seriale all’avvio dei servizi. L’idea di sostituirlo con un prodotto più moderno e meglio ingegnerizzato è, quindi, tutt’altro che sbagliata.

Il problema reale è che systemd sta andando ben oltre questo encomiabile tentativo, ma sta fagocitando al suo interno tutta una serie di servizi che con la gestione dei processi e la creazione dello ‘spazio utente’ poco hanno a che fare. Approccio, questo, che viola radicalmente le logiche della filosofia Unix, che sono alla base non solo dei Linux che usiamo oggi, ma in larga parte di quella che è l’informatica moderna.

Va detto, però, che il passaggio a systemd era già in atto da tempo, e non soltanto sulle distribuzioni basate su Debian: anche Red Hat, Fedora e SUSE (per citare alcune grandi distribuzioni Linux) sono già passate a questo nuovo gestore.

Desktop e applicazioni
Dal punto di vista dell’interfaccia utente, il grande grado di personalizzazione offerto da Debian si traduce nella possibilità di scegliere il proprio desktop environment preferito tra un gran numero di possibilità. L’ultimo rilascio è infatti compatibile con GNOME 3.14, KDE Plasma 4.11.13, Xfce 4.10, MATE 1.8 e Cinnamon 2.2.16.

Ai sopra citati desktop environment si aggiungono anche diverse applicazioni, tra cui Iceweasel 31.6, GIMP 2.8.14 e LibreOffice 4.3.3 per la sfera desktop, Apache 2.4.10, Tomcat 7.0.56 e 8.0.14, MariaDB 10.0.16 e MySQL 5.5.42 per quella server, nonchè OpenJDK 7u75, PHP 5.6.7 e Python 2.7.9 e 3.4.2 per gli sviluppatori.

Altre novità
Per concludere ricordiamo che Debian 8 è basato sul kernel Linux 3.16.7, che garantisce la compatibilità con le più recenti tecnologie disponibili. È altresì interessante notare che, con il nuovo rilascio, viene garantito il supporto a ben dieci architetture diverse, tra cui x86, PowerPC, MIPS, ARM e diverse altre.

 

#DebianottoJessie

Rsync e la sincronizzazione dei contenuti Web

rsync aggiornamento web

Rsync aggiornamento Web

Supponiamo che ci tocchi gestire in produzione un numero X di frontend Web dietro un bilanciatore e che quindi, ad ogni nuova release, si renda necessario caricare i contenuti su ciascuno di essi (rendendo la vita difficile agli sviluppatori).

Certo il mercato e’ ricco di software di Configuration Manager, ma in questo caso ho deciso di usare come esempio l’automazione mediante l’uso di rsync, del resto non serve una Ferrari per fare la spesa. In pratica, i contenuti Web verranno caricati manualmente su un’unico frontend (che servirà da server) mentre le altre macchine fungeranno da client (ovvero aggiorneranno i loro contenuti ogni X minuti consultando direttamente la macchina server).

Configurazione della macchina server

Tale attività si articola in due fasi: la prima consiste nell’installazione e nella corretta configurazione del demone xinetd (evoluzione del celebre inetd), mentre la seconda riguarda solo ed esclusivamente rsync.

Procediamo dunque con l’installazione di xinetd:

[root@server ~]# yum install xinetd

ed impostiamo l’avvio automatico del demone in questione per i diversi runlevel:

[root@server ~]# chkconfig --levels 2345 xinetd on

Posizioniamoci nella dir /etc/xinetd.d ed apriamo in scrittura il file rsync, sostituendo la direttiva:

disable = yes

con

disable = no

In definitiva, il suddetto file, dovrà avere il seguente contenuto:

service rsync
{
        disable = no
        flags           = IPv6
        socket_type     = stream
        wait            = no
        user            = root
        server          = /usr/bin/rsync
        server_args     = --daemon
        log_on_failure  += USERID
}

Passiamo ora al secondo step relativo alla configurazione della macchina server, ovvero la creazione del file rsyncd.conf nella directory /etc:

[root@server ~]# touch /etc/rsyncd.conf

All’interno del suddetto file creeremo dei moduli ad-hoc contenenti tutte le direttive necessarie per la sincronizzazione dei contenuti tra server e client, ad esempio:

log file = /var/log/rsyncd.log
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsync.lock
[images]
   path = /var/www/html/images
   uid = root
   gid = root
   read only = no
   list = yes
   host allow = 10.11.12.0/24

Salviamo il file ed avviamo xinetd:

[root@server ~]# service xinetd start

Configurazione delle macchine client

Tale configurazione consiste esclusivamente nella creazione di una entry crontab del tipo:

*/1 * * * *  root rsync -agruv root@10.11.12.1::images /var/www/html/images/

ovvero ogni minuto viene contattato il server (10.11.12.1, modulo images che punta a/var/www/html/images/) e viene sincronizzato il contenuto della Dir del client /var/www/html/images/.

Bene, l’aggiornamento e’ servito!

#RsyncSincronizzazione#AmbientiWeb

La Pivacy dei Processi

Privacy dei Processi

Privacy dei Processi

Nella maggior parte dei sistemi GNU/Linux e’ consentito ad ogni utente di visualizzare i processi in esecuzione nel dato momento (real time) sul computer, tutti i processi…, utilizzando tool quali htop, glances etc. Questo puo’ rappresentare pero’ un problema dal punto di vista della privacy, in particolar modo li dove i pc vengono utilizzati in modalita’ multiutente (come ad esempio i server) , visto che altri utenti potrebbero sapere, senza alcuno sforzo, quali programmi stiamo eseguendo, in qualsiasi momento.

Questo comportamento del sistema per fortuna puo’ essere modificato a patto pero’ di disporre di un kernel superiore alla versione 3.2 (per sapere qual’e’ la versione attualmente installata sulla vostra macchina utilizzate il comando ” uname -a ” ). Infatti da questa versione in avanti e’ presente una specifica opzione per il comando mount, da passargli quando viene attivato il file system virtuale /proc , che agisce proprio sulla visibilita’ dei vari processi.

L’opzione in questione si chiama hide-pid (ossia nascondi il pid) e puo’ assumerre tre valori
0, 1, e 2.
Il valore 0 imposta il comportamento normale di visualizzazione senza limiti,
Il valore rende impossibile l’accesso alle cartelle dei processi che non appartengono all’utente attualmente utilizzato,
Il valore definisce invece il livello piu’ restrittivo, quindi le cartelle dei processi altrui verranno nascoste e non si potra’ quindi ne accedervi, ne sapere nulla del loro contenuto compresa la loro esistenza.

Pera ttivare tale funzione bastera’ utilizzare il comando mount con il parametro aggiunto “hidepid” :

esempio

# sudo mount - o remount,rw,hidepid=2 /proc

…dopo aver dato invio ed inserita la password dell’amministratore di sistema, il livello di massima privacy sara’ stato impostato. Chiaramente per l’utente  root tali limitazioni non valgono.

Per rendere definitive le modifiche sopra testate si dovra’ editare il file /etc/fstab , ed aggiungere, nella riga relativa al file system /proc, l’opzione hidepid che meglio si adatta alle nostre esigenze.

 

#HidepidKernelPrivacy

Docker – costruire i contenitori

Docker costruire i contenitori

Docker costruire i contenitori

Recentemente abbiamo parlato della virtualizzazione tramite Docker (vedi articolo Docker – cosi cambia la virtualizzazione) e, prima di proseguire sara’ meglio rifare una piccola introduzione.

Docker e’ indubbiamente una valida alternativa alla virtualizzazione tradizionale nel mondo Linux. Questo tipo di virtualizzazione, detta a “container” non emula un’ intero hardware come fanno invece gli hypervisor tipo VMware, Virtualbox, Xen o KVM, ma crea invece dei “contenitori” nel sistema operativo dove possono essere messe in esecuzione applicazioni di vario genere in modo del tutto separato una dall’altra.

Dato che con il cloud il ruolo del sistema operativo diventa sempre meno importante perchè si punta più sullo strato applicativo, PaaS, rendendo il tutto più flessibile. A questo punto se dovessimo far girare 1000 clienti su un ambiente condiviso, diventerebbe interessante disporre di una tecnologia di virtualizzazione che riduca al minimo fisiologico gli overhead.

La virtualizzazione classica non è così, perchè per ogni ambiente applicativo, riservato ad un cliente, si dovrebbe  lanciare una intera macchina virtuale con dentro l’intero sistema operativo. E allora perchè non condividere lo stesso sistema operativo e invece isolare solo gli ambienti di esecuzione delle applicazioni , tipo application server, DB ecc…

I container sono dunque alla base dei moderni servizi cloud di tipo PaaS (Platform as a service) che usano questo tipo di virtualizzazione per misurare il consumo di risorse ed assegnarne i limiti.

Ad esempio, se su uno stesso server fisico, con una soluzione di virtualizzazione di tipo hypervisor si possono ospitare, supponiamo 50 virtual machines, con la virtualizzazione a container si potra’ arrivare anche a 1000 container. Questo perchè un container di per sè è solo un contenitore di processi, mentre una virtual machine completa contiene tutto un ambiente operativo emulato.

Il container può anche essere portabile, infatti ci basta copiare la directory che contiene il filesystem modificato dall’utente dopo la creazione del container, un piccolo file di configurazione, ed il container diventera’ eseguibile su qualsiasi sistema che supporti LXC.

Il concetto è talmente interessante, che qualcuno ha pensato di fare un sistema operativo Linux interamente basato sui container, in cui non c’è nemmeno un package manager perchè si assume che gli applicativi saranno solo in forma di container. Coreos è nato proprio con il principio di supportare ambienti di esecuzione a container, togliendo dal sistema tutto quello che non è strettamente necessario per farlo funzionare.

INSTALLAZIONE

Abbiamo tre possibili metodi d’installazione :

1) Centos

sudo yum -y install docker-io

2) Debian/Ubuntu

sudo apt-get update 
sudo apt-get install docker.io 
sudo sudo apt-get install lxc-docker

3) Download con Curl

sudo curl -sSL https://get.docker.io/ubuntu/ | sudo sh

* Linkiamo docker alla nostra bash

ln -sf /usr/bin/docker.io /usr/local/bin/docker
sed -i '$acomplete -F _docker docker' /etc/bash_completion.d/docker.io

* Rendiamo docker attivo all’avvio

update-rc.d docker.io defaults

P.S.: Ci sono molti contenitori già disponibili nella community docker, che possono essere trovati attraverso una ricerca. Ad esempio con questo comando cerchero’ la parola debian:

# docker search debian

NAME    DESCRIPTION      STARS     OFFICIAL   AUTOMATED
debian  Debianbaseimage  310         [OK]
google/debian            31                     [OK]

….e molte altre che potrete leggere dall’output completo.

** Installiamo e facciamo provisioning con una immagine Centos

# docker pull blalor/centos  # GitHub blalor/docker-centos-base  image

oppure per chi fosse interessato ad una immagine con gia inserito il tool Ansible (per il Configuration Management ed IT Automation) di cui ho da poco parlato, potra’ scegliere quest’altra immagine.

sudo docker pull ansible/centos7-ansible # GitHub Ansible on Centos7
Pulling repository ansible/centos7-ansible
fff2afd18a57: Download complete

Avviamo un container docker

Attiveremo ora un contenitore centos-base con una shell bash, utilizzando il comando run. Docker eseguira’ questo comando in un nuovo contenitore, -i attribuisce stdin e stdout, -t assegna un terminale.

docker run -i -t centos /bin/bash

Questo è tutto! Adesso stai usando una shell bash all’interno di un contenitore centos.
Per scollegarsi dalla shell la sequenza di escape e’ : Ctrl-p + Ctrl-q.

Diamo un’occhiata ai processi attivi tramite :

# docker ps -a
CONTAINER   ID IMAGE          COMMAND     CREATED
fff2afd18a57     blalor/centos     /bin/bash         About an hour ago

Il Dockerfile
Per automatizzare la procedura di creazione e modifica di un container docker, possiamo utilizzare il Dockerfile, che è una delle parti principali di Docker, infatti attraverso il Dockerfile è possibile non solo fare il deploy istantaneo automatizzato di più istanze e più container, ma è anche possibile eseguire il provisioning di queste istanze, automatizzando task di gestione del sistema, installazione del software e molto altro.

Nel prossimo articolo vedremo un esempio utile, utilizzando ad esempio un’applicazione leggera, che puo’ lavorare molto bene in un contenitore, come NGINX, il noto server web/cached per la gestione di siti web/proxy ad alto carico.

#DockerContainerAvviato