I container: perché non usarli?
Gli annunci da parte dei vendor negli ultimi anni vedono apparire i container come la tecnologia definitiva per lo sviluppo delle applicazioni. Le aziende però rimangono restie al cambiamento, negando la possibilità di iniziare vere e proprie linee di prodotti sviluppati in modalità cloud native. Rivolgendo proprio a loro la domanda: <<come mai NON hai iniziato a sviluppare cloud native application al posto delle tecnologie tradizionali?>> si sentono le risposte più disparate, <<non li conosco quindi li evito>> <<perché li dovrei adottare, quando le mie tier-1 sono affidabili e mi fanno guadagnare?>>. Nella maggior parte dei casi la risposta è legato al cosiddetto “gap culturale” che spesso attacca l’evoluzione tecnologica prima di affermarla. Sei poi questo cambiamento sconfina nel terreno proibito dei colossi che sviluppano gli applicativi verticali, allora il freno dell’innovazione diventa una ragione esclusivamente legata ad aspetti politico/economici (vedi il mercato energetico).
Resistenza al cambiamento
L’Italia è un paese di inventori; spesso alcuni ritrovati tecnologici sebbene vestano un marchio straniero sono il frutto di ingegneri Italia che hanno trovato un terreno più fertile in altri paesi. Ma perché? Ebbene il nostro sistema politico/economico spesso è la prima causa di rallentamento dell’innovazione: si tende a sminuire o annullare il lavoro delle eccellenze che spesso si vedono costrette ad espatriare per esprimersi e, finalmente, venire riconosciuti per quello che realmente fanno e possono ancora fare. Diciamo che l’Italia si fonda sul principio con cui per ottenere qualcosa devi prima abbattere un <<dinosauro>> o corrompere qualche <<barone>>. (Refusi del passato che insistono, ma sono in via di estinzione)
Proviamo ad immaginare solo per un attimo, la potenza del colpo inflitta dai container verso i vecchi mausolei della tecnologia? Di fatto questa tecnica definita cloud-native permette ad un team ridotto di sviluppatori di costruire, mettere in produzione e manutenere un’applicazione in tempi ridotti e in piattaforme cloud oriented, ereditandone quindi, garanzie di stabilità e scalabilità. La cosa più sconvolgente è il costo: non è più necessario dotarsi di pesanti infrastrutture (in tutti i sensi) e il cost-model risulta più lineare e meglio correlato al business aziendale.
Spieghiamo meglio…
Oggi per sviluppare un’applicazione non è necessario codificare tutto da zero dato che le nuove applicazioni sono il frutto dell’implementazione di altre applicazioni cloud-native già presenti nel mondo. Per far sì che questo nuovo tessuto applicativo si stabile in termini di controllo e resilienza, occorrono dei presupposti:
- un servizio di connettività: <<dai! che in Italia ce la faremo!!!>> anche se in altre parti del mondo abbiamo ancora la reputazione dei trogloditi…
- uno, o più cloud provider. Attenzione a questi! Devono obbligatoriamente essere meno invasori e più aperti agli standard. Per inciso: i cloud provider, in alcuni casi, sono coloro che semplicemente hanno fatto evolvere il vecchio concetto di hosting cambiando semplicemente il nome. Quindi grandi o piccoli che siano, ancora oggi pensano di far breccia sul mercato attraverso politiche di lock-in, in grado quindi di mettere in “gabbia” i clienti, tra costi esorbitanti e l’impossibilità di spostare le loro applicazioni. Diffidate dalle “imitazioni”: il concetto di cloud va molto al di sopra di un semplice hosting: sicurezza, governance e scalabilità sono i principi che la contraddistinguono dalla restante spazzatura. Scegliete quindi accuratamente il vostro service provider.
- adozione dei cloud services: servizi che rispettano la separazione data-logic e business logic. In questo contesto però vige la regola ferrea dove: i dati sono i miei l’applicazione è tua; i dati fruiscono da te e tornano da me senza lasciare tracce, se non la registrazione di quello che è avvenuto per i fini normativi. Purtroppo per il motivo di cui sopra, molti cloud provider oltre a non rispettare gli standard, non rispettano nemmeno la proprietà del dato. E questo è MALE!
Detto questo, in Italia come in Europa, fortunatamente esistono cloud provider di tutte le misure che rispettano queste logiche, ed è proprio da loro che occorre cominciare.
Entrando nel merito dell’architettura uno dei primi concetti da tenere presente è che le logiche di business non devono contenere dati, o meglio non devono contenere dati cosiddetti primitivi. I dati primitivi e derivati sono l’asse portante della distribuzione logica nelle cloud native applications: ogni microservice, cioè unità contenti logiche di business, attinge dati in un contenitore (nosql, dbrms, object storage), lo elabora e poi decide se presentarlo o metterlo a disposizione per l’elaborazione successiva.
Gli effetti di questa riorganizzazione? Devastanti, dal momento che in passato si usava un database per fare tutto… e quando dico tutto intendo anche per dati derivati, di cache e magari anche gran parte della logica di business (W le stored-procedure). La riorganizzazione logica impone finalmente la caratterizzazione dei dati a partire dal flusso applicativo. Di conseguenza riduciamo spazio disco, o meglio lo caratterizziamo per la destinazione d’uso e possiamo distribuire i dati anche in modo geografico. E questo porta lo SLA applicativo verso valori superiori al 99,9%
Tracciamo un percorso
Le parole chiave utilizzate durante lo sviluppo mediante container, sono riciclare e riorganizzare… ma cosa e come? Accanto ai bidoni per la raccolta della carta, dell’umido e del codice scritto per un cliente, proviamo a estrapolare parti di codice che caratterizzavano l’applicazione. Verifichiamo quindi se lo scopo con cui è stato scritto il codice possa essere trasformato per renderlo qualcosa di generico; questo è il primo passo e prende il nome di “astrazione”. Ma la forma astratta di un codice non prende il nome di libreria? Certamente, ma il container fa qualcosa di più: partendo da una genesi comune alla libreria, è possibile costruire un’immagine che racchiudere:
- sistema operativo (gli elementi necessari)
- librerie
- business logic (cioè l’applicazione astratta)
- connettori con l’esterno.
Ogni container è un’istanza operativa isolata che risulta a tutti gli effetti un’implementazione della sua immagine. Nonostante le analogie, quest’ultimo si distanzia dal concetto di macchina virtuale dal momento che:
- è un oggetto informatico effimero, cioè porta con se i dati dell’applicazione per quanto necessario per la sua esecuzione e visualizzazione dei risultati dell’elaborazione.
- può essere gestito da entità terze a prescindere dall’infrastruttura sottostante
- può girare all’interno di una macchina virtuale o direttamente in un bare-metal (server fisico) senza aver legami con l’hardware e l’infrastruttura sottostante.
Qualcuno potrebbe definire la creazione di un container come il futuro della virtualizzazione… ma oltre ad essere concettualmente errato, risulta essere riduttivo dal momento che OS, applicazioni e runtime sono molto più legate alla business logic dell’applicazione; mentre i dati possono essere stoccati in entità che trovano il loro mondo ideale all’interno di database e di sistemi object storage.
La morte delle Tier-1 application
Partiamo da un esempio pratico: un azienda mi commissiona un portale di e-commerce che si interfacci direttamente con l’applicativo presente presso la lan aziendale. L’approccio Tier-1 prevede lo sviluppo di un componente web inserito all’interno dell’azienda, l’impiego di un ip pubblico diretto e magari sviluppato con tecnologia database oriented come SQL server o Oracle. Dal punto di vista architetturale, gran parte della business logic sarà costruita all’interno del database sotto forma di stored procedure.
Spieghiamo il fallimento prima dell’implementazione:
- il cliente si deve dotare di un’ infrastruttura dedicata (magari nemmeno “virtualizzata”) con un costo approssimativo di non meno di 100K licenze software escluse
- le garanzie di uptime si affidano completamente all’infrastruttura sottostante (da qui l’ignoranza nel tenerla fisica). Se il database diventa indisponibile? Downtime sicuro!
- la richiesta in termini di sviluppo è di non meno di 1 anno tra integrazione, delivery e migrazione.
- al termine della messa in produzione ci porrà un quesito: << e se cambia il business, la mia applicazione (cioè il mio investimento per almeno 10anni) sarà ancora in grado di rispondere adeguatamente? >>
Allora se io produco scarpe e le voglio vendere, un investimento di almeno 300K una tantum e 50K all’anno di manutenzione per almeno 10 anni comincia ad essere veramente poco giustificabile. Ma la gente comune, cioè i manager che non hanno visioni sull’innovazione, pensa ancora, che questa sia la strada obbligata.
Non mento che qualche “genio” dell’informatica ogni tanto viene a farmi visita presentando l’ennesima soluzione Tier-1 come modello nel mercato delle utility; ovviamente il loro ingresso in azienda è favorito da una prima visita ai dirigenti, altrimenti, per quanto mi riguarda, non avrebbero mai varcato la porta dell’azienda. ( Cloud Bastard inside! ). Dato che devo cedere a qualche compromesso per mangiare, allora mi diverto: pensate alle reazioni di queste società di integrazione quando gli fate la domanda: <<ma voi sviluppate in modalità cloud-native? Con quale linguaggio? Conoscete i container? Perché non li usate?>> Loro scomposti ti diranno che è tutto sperimentale o sconosciuto ai livelli enterprise. La cosa più sconcertante è che il tuo interlocutore sarà sempre una persona denominate senior, in grado di celare la verità sul livello di esperienza del team di sviluppo. Volete sapere la verità? Prendono qualche ragazzino neo-laureato e con poca ambizione, lo pagano circa 600€ al mese e gli affidano routines critiche. E se qualcosa non funziona? <<Non ti preoccupare!>> gli dicono <<dai la colpa al sistema o ai sistemisti!>>.
Vorrei però riportare questo articolo ad un livello più alto, dimenticandomi per un attimo a quanto un sysadmin sia costretto a rischiare l’integrità dei propri sistemi a causa delle decisioni irrazionali dei propri superiori.
Ammettiamo che lo sviluppo continui e termini con un delivery… una bottiglia di spumante per festeggiare… festa grande… fino a quando arrivano due grosse questioni da affrontare:
- Se cambia il business quanto codice dovrà essere sviluppato e in che modo e con che tempi?
- Se un altra azienda mi chiede qualcosa di simile, ma con qualche differenza, quale sarà l’effort in termini di risorse umane per completare anche questo progetto?
Lo stimolo al cambiamento viene proprio da questi due problemi; proviamo quindi a ripensare l’applicazione mettendo a posto alcuni concetti chiave:
- La logica dei dati non deve contenere quella di business e viceversa.
- ogni elemento del sistema può vivere anche in assenza del processo precedente
- ogni elemento del sistema deve esporre i connettori verso l’elemento successivo
- occorre necessariamente astrarre tutti gli elementi.
Rivisti i concetti ci occupiamo dell’architettura; di fatto in ottica cloud-native è possibile sviluppare l’applicazione in diverse modalità:
- full-cloud, dove data e business logic sono presenti in un ambiente protetto, ma al di fuori dell’azienda.
- hybrid-cloud, cioè data e business sono residenti sia fuori che dentro le mura aziendali.
- in-premise, solo nel caso in cui esistano vincoli normativi tali per cui il dato non possa uscire dalle mura aziendali. Ovviamente è sempre permessa la movimentazione dentro e fuori dal cloud.
La cosa più entusiasmante però, è la facilità di sviluppo dell’applicazione ovvero utilizzando quanto già disponibile da parte della community, è possibile, con poca integrazione di codice, costruire alcuni o tutti gli elementi applicativi necessari a comporre il sistema finale. Ma c’è di più; è possibile implementare software terzi che possiedono già i connotati di un’applicazione cloud oriented, federandoli con la propria applicazione. Quest’ultimo evita agli sviluppatori di “reinvetarsi la ruota”, propagando la cosiddetta dead-line di progetto con pesanti sviluppi e l’impiego onerose infrastrutture per processi che in alcuni casi si rivelano anche non essere di core-business. Vedi, ad esempio, la geo-localizzazione: che male c’è nell’utilizzo di google maps? Avete mai pensato alle risorse necessarie a sviluppare una “cosa” simile “in casa”?
Consideriamo poi altri ingredienti dell’applicazione come scalabilità, portabilità e impiego delle risorse: sviluppare nella logica dei container prevede l’utilizzo di immagini, cioè definizioni che portano con se tutti gli elementi costitutivi, come sistema operativo, librerie, strumenti e il codice vero e proprio. Impiegando un semplice “puntatore a immagine” è possibile creare diversi container simili all’immagine originale al solo costo capacitivo della variazione di dati che vengono generati e modificati durante il runtime. Deploy e portabilità si coniugano benissimo con il concetto delle immagini di container: sviluppato un microservice, portato all’interno di una repository comune (denominato hub o image registry), possiamo distribuire l’applicazione, le relazioni tra microservices e tutto il necessario per il funzionamento con pochi semplici script, che possono essere lanciati dallo stesso ideatore dell’applicazione. (Ma come? Niente sistemisti che assistono questa fase? Lo vedremo successivamente… )
Risolvendo quindi il problema dell’esempio sopra in logica cloud native, occorre sviluppare un componente software collegato al gestionale in grado, mediante un sistema in polling, di comunicare, quando necessario, i dati essenziali ad un mongo db (o sistema nosql alternativo) in cloud. Con istanze di un semplice cms adibito a portale di e-commerce, modificato per attingere i dati da un mongodb, è possibile presentare un applicazione che scala in base alle richieste del “business”. Come effetto collaterale, l’azienda che svilupperà il sistema, sarà in grado di emettere un prodotto o un semilavorato per altri progetti. La continous developing, cioè la tecnica che prevede sviluppo e la correzione dell’applicazione durante il suo ciclo di vita, permette al sistema di evolvere in modo continuo per restituire una sempre migliore solidità, scalabilità e user experience.
Quindi ripensare l’applicazione in modalità cloud-oriented porta qualche “piccolo” beneficio come:
- Nessun impiego infrastrutturale o in alcuni casi si parla di parziale acquisto infrastrutturale, dal momento che le fasi più pesanti del processo verranno gestite da un virtual-datacenter ubicato a qualche migliaio di Km dall’azienda
- Availability e Resilienza senza eguali, dato che la distribuzione geografica della applicazioni diminuisce la tolleranza al fault dovuto a problemi infrastrutturali (l’esperienza di Google insegna!)
- Le applicazioni vengono realizzate, testate e messe in produzione con meno personale che può essere anche geograficamente distante.
- Ovviamente la scalabilità, cioè uno dei piatti forti delle cloud native application, dal momento che è possibile estendere e contrarre la portata applicativa, sulla base delle richieste del business
E ai manager dirò una sola cosa che va al di là del tecnicismo: costa meno e funziona meglio (anche sul tuo iphone )!
La cultura deve cambiare? No! deve evolvere.
Adesso mi rivolgo a sistemisti, sviluppatori, integratori e tutti quelli che appartengono a questo “passato” ancora attuale: << Lavorare nell’IT implica un percorso formativo continuo, dato che ogni anno, le innovazioni tecnologiche, rendono obsoleto il sistema che attualmente utilizziamo >>.
Ricordo sempre la strage di sviluppatori quando uscì l’Object Oriented Programming… Ricordo anche di aver fatto un corso con un bravissimo teacher Java (R.I.P. Max Boidi) che ancor prima di iniziare gli argomenti del corso stesso, ha dovuto scontrarsi con programmatori AS400 che affermavano: << Java? Object oriented? No sono cose da “cantinari” che non prenderanno mai piede nell’informatica… >>. Loro erano i cosiddetti resistenti al cambiamento; oggi, che io sappia, qualcuno di questi aggiusta PC in una ditta di micro informatica locale, gli altri sono in pensione o a fare qualche altro lavoro.
Quindi lo sviluppatore evolve e si trasforma in devops, cioè figura centrale nello sviluppo delle cloud native applications. A lui spettano due compiti:
- sviluppare applicazioni e processi (DEV)
- mettere in produzione, scalare e monitorare le applicazioni (OPS)
Poi arriva il turno del sistemista. Ne ho conosciuti e ne conosco veramente troppi e tutti con un “mantra”: << Negare e farsi pretendere >>. Nell’ottica cloud native questo approccio è sicuramente intollerabile e di sciuro, se non volete trovarvi a casa con il vostro ego intatto ma senza lavoro, dovete cambiare e pensare che l’approccio cloud native sia un’opportunità per sgravarvi dagli oneri di monitoraggio e gestione dell’ambito applicativo. Il sistemista quindi diventa un infrastructure manager e deve pensare di essere il provider dei devops (non lo schiavo quando mette in produzione o il super eroe quando ci sono problemi).
Il risultato sarà che il devops non chiederà al sistemista di preparargli un server linux, con particolari release o librerie, ma pretenderà solamente uno spazio infrastrutturale dove poter sviluppare comodamente, senza preclusioni e in completa autonomia. Il sistemista finalmente deve pensare agli approvvigionamenti, a migliorare l’uptime e a investire in innovazione per rendere i sistemi nel datacenter sempre più efficienti.