1ring: Automating Ops

L'obiettivo e' di passare da un approccio “artigianale” nell'amministrazione di tutti i server gestiti da beFair ad uno piu' “industriale”, ovvero automatizzando tutta una serie di operazioni tra cui:

deploy delle applicazioni

monitoraggio dei processi principali (attivi e disattivi)

monitoraggio dell'occupazione della RAM e del disco

assicurarsi che tutti i server siano sempre accessibili via SSH

test su tutti i siti web (richiesta http, verifica ritorno 200)

inviare notifiche a sysadmin-alert@befair.it nel caso di errori o superamento di alcune soglie

I luoghi di riferimento di questo progetto sono:

questa stessa pagina wiki

l'alias sysadmin@befair.it

gli alert arrivano all'alias sysadmin-alert@befair.it

Repository Git

Il master (befair2) dispone di un repository Git in /root/1ring contenente del codice per Ansible, strutturato a partire dalle buone pratiche consigliate. In breve:

doc/ documentazione
inventories/ info su tutti gli host e gruppi di host
group_vars/ dati sui gruppi di host
group_files/ file ricorrenti tra piu' host, come le chiavi SSH
host_vars/ dati per ogni singolo host
host_files/ file specifici per host
prod.ini inventario con tutti gli host e i gruppi
dev.ini inventario per i test
playbooks/ script da lanciare, applica 1+ role ad 1+ host
jobs_high.yml script per i task ad alta priorita' (ogni 10 minuti)
jobs_low.yml script per i task giornalieri
roles/ contiene i role, cioe' i "pacchetti" di Ansible
secrets/ contiene l'archivio keepassx ed eventualmente altri file cifrati
utils/ script di varia utilita'
ansible.cfg file principale di configurazione
README.rst guida per installare/configurare Ansible

Nota: per info sui nostri role tutti i dettagli qui

FAQ

Alcune FAQ su dove trovare cosa:

archivio keepassx? secrets/befair.kdb

chiavi SSH? inventories/group_files/all/ssh/id_*.pub

info sulle installazioni di Gasista Felice? inventories/host_vars/befair2.yml → gf_flavours

messaggio motd per host befair0? inventories/host_vars/befair0.yml → motd

demoni/processi per host spes_hosting? inventories/host_vars/spes_hosting.yml

limite swap su tutti i server spes? inventories/group_vars/spes.yml → swap_perc_limit

info per accedere via SSH ai server? inventories/group_vars/staff.yml → hosts

ci sono variabili globali? inventories/group_vars/all.yml

Il repository Git disponde di 2 branch:

master: branch di sviluppo dove pushiamo direttamente le modifiche (dopo aver fatto pull + rebase)

prod: branch di checkout, attivo sul server che verra' usato

L'idea e' fare periodicamente il rebase del branch prod con il master.

E' possibile clonarsi il repository in locale con:

$ git clone root@befair2.befair.it:1ring

Monitoraggio delle risorse

E' possibile accedere all'interaccia web Grafana:

$ ssh root@befair2 -L 8889:localhost:8889 -L 8086:localhost:8086

Ora visitare http://localhost:8889/

Ho aggiunto solo un paio di grafici, ma se ne possono aggiungere altri (anche se non vengono memorizzati sul server ← IMHO questo e' l'unico vero problema di Grafana). Per ulteriori info sulla configurazione di Grafana vedere http://grafana.org/docs/features/influxdb/

Inoltre e' possibile accedere ai dati da client Python:

$ ssh root@befair2

# workon 1ring && ipython

> from influxdb import InfluxDBClient
> client = InfluxDBClient(host='127.0.0.1', port=8086,
username='1ring', password='fajw49849f4jp', database='1ring')

Ecco 3 query di esempio:

> client.get_list_series()
> client.query('select mem_usage from befair1')
> client.query('select * from befair1')

Per info sul linguaggio per le query vedere http://influxdb.com/docs/v0.8/api/query_language.html

Monitoraggio dei log (TODO)

Da valutare:

Sentry (Python)

Logster (Python)

Logstash (Ruby), componente di Elastic Search

Approfondimenti

comparativa principali sw automazione: A B

Labs (R&D)

In questa sezione faremo un brainstorming sul mondo Docker e sui microservizi, non direttamente connesso a 1ring (almeno per ora) ma sempre legato all'automatizzazione dell'infrastruttura IT, nell'ottica di applicarla in futuro. In particolare, le tecnologie presentate di seguito rappresentano lo stato dell'arte di un modello di sviluppo software che riguarda una maggiore integrazione tra il workflow di sviluppatori e sistemisti (dev e ops), cosiddetto DevOps.

Premessa: tutto cio' che andremo a vedere di seguito parte dal presupporto di adottare strumenti rilasciati come software libero e che quindi possiamo usare sulla nostra infrastruttura senza dipendere da servizi esterni. Laddove andiamo ad usare servizi esterni (principalmente l'affitto di server virtuali) e' importante non legarsi ad un venditore specifico per essere flessibili nella scelta dei fornitori.

Docker

Introduzione a Docker: https://speakerdeck.com/slok/ship-it-with-docker

Gli obiettivi di usare Docker puo' portare a diversi vantaggi:

avere ambienti riproducibili e standardizzati tra dev e ops

in dev, ridurre l'overhead rispetto ad eventuali VM/Vagrant

in ops, aumentare la sicurezza grazie ad ambienti isolati

L'idea di adottare un set di strumenti basati su Docker che ne estendono le funzionalita' nell'ottica di avere un'infrastruttura IT Docker-based, automatizzata, autoscalabile, HA minimizzando costi e interventi umani, proponendo una standardizzazione del forkflow dev e ops.

Questi strumenti possono essere:

Projects tracker (es: Jagom, Taiga), non e' direttamente legato a Docker ma e' fondamentale per gestire il workflow di dev e ops

Server GIT (es: GitLab), non e' direttamente legato a Docker ma e' la base per lo sviluppo (ma comunque puo' essere deployato tramite Docker)

Server di CI (es: GitLab CI, Drone), infrastruttura che si occupa dei test automatici ad ogni push. Questa prende in ingresso i repository, effettua dei test, ed eventualmente effettua delle operazioni di publish o deployment, o comunque puo' avvisare altri software.

PaaS (es: Deis…) e' il cuore dell'infrastruttura che si occupa di tenere su tutte le applicazioni, in produzione e non, regolando il workflow degli ops. In particolare, si occupa di gestire:

il deploy di tutte le app a partire da un modello dichiarativo

i log delle applicazioni

il carico delle app sui singoli host, il load balancing e l'autoscaling

Projects tracker

Questi strumenti possono fungere anche da wiki e issue tracker e sostituiscono ad esempio JIRA.

Jagom, primo progetto di beFair, e' un fork di Trac con dovuti potenziamenti.

Taiga, metodologia agile (scrum) e/o snella (kanban), applicazione Django e Angular. Taiga si puo' interfacciare con GitLab (vedi sezione dopo).

Timetracker, esercizio di sviluppo per prendere confidenza con Django, punta a fornire un'interfaccia web anche su mobile, per segnare il tempo delle proprie attivita'. Puo' essere integrato con Jagom e/o Taiga.

Repository

Questo strumento puo' fungere anche da wiki e issue tracker e sostituisce GitHub o BitBucket.

GitLab e' un software simile a GitHub ma libero, e quindi puo' essere hostato nella nostra infrastruttura. E' disponibile una versione Dockerizzata non ufficiale.

Docker-based CI

Drone e' un sistema per il CI basato su Docker, nel senso che usa dei container Docker per i test, ed eventualmente puo' essere lui stesso installato con Docker. Sostituisce software come Jenkins (Java, lo standard de facto) e GitLab CI (Ruby). Drone prende come input repository da:

GitHub, Bitbucket, GitLab

E puo' deployare e/o pubblicare su:

Deployment: Git, Bash, OpenShift(TODO), Tsuru …

Publish: S3, Swift (OpenStack), NPM, PyPI, Docker, GitHub

Una volta scelta una PaaS, possiamo capire meglio quale puo' essere l'output piu' adatto per Drone (publish o deployment che sia).

Docker-based PaaS

Tra tutte e' emersa una proposta alternativa nell'uso di Docker non visto piu' come un container che fornisce microservizi ma una come VM a basso overhead. In questo caso la differenza principale e' data dall'avere (come in un normale OS) un normale demone di init come PID 0, mentre nei microservizi il PID 0 e' il processo che vogliamo lanciare (Nginx, uWSGI, PostgreSQL…). Questo approccio risolve alcuni aspetti nell'uso di Docker in produzione, come la questione del logging. Tuttavia per sfruttare appieno Docker non e' neanche sufficiente dotare ogni container di demoni init nativi, SSH e SysLog, ma bisogna andare un po' oltre e pensare un sistema di orchestrazione che risolve questo e altri problemi come l'HA, l'autoscaling, etc fermorestanto l'approccio dei microservizi.

Infatti se Docker di default puo' avere vantaggi principalmente in fase di sviluppo, per sfruttarlo in fase di ops e' necessario dotarsi di un orchestration engine o, ancora meglio, una PaaS Docker-based che quindi puo' portare a:

infrastruttura piu' agile basata sui microservizi

migliorare l'efficienza del deploy di un'applicazione tramite:

minimizzazione dei costi di deploy di un'applicazione

migliorare la scalabilita' in produzione

Cosa si intende per PaaS e a quale livello di astrazione si pongono questi strumenti? Qui si puo' avere un'idea sui differenti livelli di astrazione.

Deis

Deis e' la prima PaaS libera costruita su Docker ed evoluta nel tempo (ed attualmente l'unica pronta per la produzione) che implementa i principi di 12factor e rappresenta una sorta di Heroku libero

basato su CoreOS

Deis e CoreOS sono entrambi production-ready

prevede solo applicazioni stateless

Deis scritto in Python e Go, CoreOS in Go

OpenShift 3 Origin

Kubernetes e' stato presentato da Google all'I/O 2014 come proposta per standardizzare l'orchestrazione di applicazioni dockerizzate stateless (dove un'applicazione e' costituita da vari pod, ogni pod e' un insieme di container)

OpenShift 3 e' la riscrittura della PaaS di RedHat in Go (prima era in Ruby) e basato su Docker (prima era su un container engine specifico di RedHat)

basato su Kubernetes

OpenShift e Kubernetes entrambi in beta

Kubernetes (per ora) permette solo applicazioni stateless, mentre OpenShift punta a supportare anche app stateful.

scritti in Go

repository

Flynn

sviluppato a partire da un documento presentato da Google

in alpha

prevede sia app stateless che stateful

scritto in Go

repository

Tsuru

?

prevede sia app stateless che stateful

scritto in Go

repository

Nota: per stateless s'intende che la soluzione proposta non gestisce dati persistenti (che sia su database o su file system), e questo e' dovuto al fatto che i container possono essere costruiti/distrutti in qualsiasi momento (come se fossero in sola lettura). Quindi eventuali database (relazionali o non) o file caricati dagli utenti dovranno risiedere altrove, ad esempio su un nostro VPS qualsiasi, cosi' come Google Persistent Disk, Amazon S3, etc. Tuttavia questo e' un argomento abbastanza complesso su cui siamo in piena fase di R&D, per cui ora non approfondiamo ulteriormente.

IaaS abstraction level

A titolo di completezza, aggiungiamo questa sezione per fare una panoramica sulla soluzioni libere attualmente disponibili per fornire un livello IaaS, mentre nella sezione prima partivamo da questo livello per fornire un'astrazione maggiore piu' vicina allo sviluppatore. In linea di massima non dovrebbe essere necessario ricorrere a queste soluzioni a meno che vogliamo fare concorrenza a qualche colosso, possiamo accontentarci di qualche VPS gia' pronto.. :)

Mesosphere e' una sorta di “sistema operativo distribuito”, ed e' alla base di Twitter. Sotto a tutto abbiamo Mesos, un kernel distribuito, sopra il quale girano scheduler, cron-like e le applicazioni specifiche per questa sorta di framework/OS. I componenti principali sono scritti in C++ o Java.

OpenStack, scritto in Python e sviluppato inizialmente da NASA e RackSpace, si definisce un “sistema operativo cloud” ed e' largamente usato al CERN cosi' come in altri grandi datacenter. E' pensato per girare su bare metal con hardware comune, Xen e KVM. Prevede anche la gestione di container LXC (una tecnologia un po' piu' grezza di libcontainer, usata di default da Docker). E' un'ottima soluzione per un'infrastruttura standard o parzialmente dockerizzata (con Deis sopra ci si possono fornire Docker-based stateful apps).

Se vogliamo invece un cluster di macchine totalmente dedicato ai container, possiamo prendere in considerazione Kubernetes, sviluppato da Google e scritto in Go, in quanto e' la soluzione piu' easy e, sebbene offre un livello piu' alto di IaaS, puo' girare su bare metal, cosi' come su OpenStack, un VPS generico con Fedora, CoreOS… e' in sviluppo un layer per farlo andare su Mesos (nel caso si voglia creare un'infrastruttura ibrida Docker-based apps + Mesos-based apps).

In linea di massima l'unico limite per combinare tra loro queste tecnologie e' data dalla propria fantasia, comunque l'unico limite dovrebbe essere che Docker non puo' girare dentro Docker (almeno fino a prova contraria), quindi i container sono lo stack piu' alto (sopra al quale non ci puo' stare niente). Di seguito alcuni esempi di stack IaaS/PaaS che possono avere senso:

Deis: layer 0 + CoreOS + Deis –> stateless Docker-based PaaS

OpenStack/Deis: layer 0 + OpenStack (+ CoreOS + Deis) –> Hybrid stateful Docker-based PaaS + normal apps

OpenStack/OpenShift: layer 0 + OpenStack (+ Kubernetes + OpenShift) –> Hybrid stateful Docker-based PaaS + normal apps

OpenShift: layer 0 + Kubernetes + OpenShift –> stateful Docker-based PaaS

Mesosphere: layer 0 + Mesos (+ Kubernetes/Mesos + OpenShift?) –> Hybrid (stateful?) Docker-based PaaS + Mesos-based apps

Come layer 0 s'intende:

bare metal

Ganeti si basa su Xen (o KVM) e LVM, scritto in Python.

Xen Orchestra Basic e' un'interfaccia web a Xen Server che permette di orchestrare un cluster di macchine Xen.

affitto di un server virtuale su GCE, AWS, Linode, Digital Ocean…

FAQs

Ma non sarebbe utile fare qualche disegnino per capire meglio?

Decisamente si'!

Cosa ci possiamo fare oggi con tutto questo?

Attualmente (gennaio 2015) c'e' molto fermento e non sembra esserci una soluzione production-ready PaaS-only che permette di gestire sia componenti stateless che stateful, tuttavia avere una visione d'insieme dell'attuale ecosistema e dare un occhio al domani puo' essere utile per arrivare preparati e fare oggi scelte piu' opportune/lungimiranti nel progetto 1ring.

Dov'e' Ansible in tutto questo?

Risposta brevissima: non lo so, ma da qualche parte lo infileremo, no? :D

Risposta breve: Nell'era dei container perde molta della sua importanza, sebbene puo' comunque essere usato, ad esempio per il bootstraping di Kubernetes su un host.

Risposta non breve:

Ansible di base accede via SSH ad 1+ host ed esegue 1+ task, mentre piu' in generale verifica e si assicura che ci siano certi stati in certi host. Nei container, non disponendo di default di un demone SSH, diventa molto difficile lavorarci. C'e' un filone di pensiero (vedi Phusion) che vede i container come VM leggere, e quindi un demone di init + SSH + syslog + cron + processi delle applicazioni, ma come dicevamo all'inizio qui siamo partiti dal pressupposto di avere un'infrastruttura basata su microservizi e quindi questo lo ecludiamo.

Nei container stateless, per logica, non dovrebbe essere necessario applicarci dei playbook di Ansible, ma bisognerebbe (piu' drasticamente) distruggere/ricreare container per assicurare gli stati. Per i container stateful invece potrebbe tornare utile, ad esempio per backup e snapshot (tuttavia non sono certo di questo).

I campi in cui comunque rimane fondamentale sono:

acquisto/gestione delle VM via API

bootstraping di baremetal/VM (a cui si accede via SSH)

“tappare i buchi” laddove non ci sia una funzionalita' nativa gia' implementata

Questo ci permette di attivare funzionalita' molto potenti come:

autoscaling su numero variabile di VM (AWS-like), cioe' aggiungere VM al cluster di container Docker quando questi complessivamente hanno bisogno di maggiori risorse (e' un po' difficile da spiegare)

Alcune cose dovrebbero essere modificate sui repository perche' Ansible non potra' andare a scrivere dati specifici all'interno delle clone dei repository, ad esempio:

i settings.py di Django che oggi vengono gestiti come template in Jinja2 con Ansible, dovrebbero invece essere suddivisi in diversi file, in modo che Django lanci il corretto settings.py in base ad una ipotetica variabile d'ambiente del tipo TYPE=prod oppure TYPE=stage o TYPE=dev (approccio 12factor)

Questa parte magari e' da scrivere un po' meglio..