Si avvicinava il Capodanno. I bambini di tutto il paese avevano già inviato le lettere a Babbo Natale o avevano espresso i loro desideri di regali, e il principale esecutore — uno dei grandi rivenditori — si stava preparando per l'apice delle vendite. A dicembre, il carico sul suo data center aumenta notevolmente. Pertanto, l'azienda ha deciso di modernizzare il centro dati e di mettere in funzione decine di nuovi server a sostituzione di attrezzature il cui ciclo di vita era giunto al termine. A questo punto la favola sullo sfondo dei fiocchi di neve volanti finisce, e inizia il thriller.

L'attrezzatura è arrivata sul sito diversi mesi prima del picco delle vendite. Il servizio operativo, ovviamente, sa come e cosa configurare sui server per metterli in produzione. Ma dovevamo automatizzare questo processo ed escludere il fattore umano. Inoltre, i server sostituivano un insieme di sistemi SAP, critici per l'azienda, prima della migrazione.
L'implementazione dei nuovi server era rigidamente legata a scadenze. Spostarla significava mettere a rischio sia la consegna di un miliardo di regali sia la migrazione dei sistemi. La data non poteva essere cambiata nemmeno dalla squadra composta da Babbo Natale e Santa Claus: il trasferimento del sistema SAP per la gestione del magazzino può avvenire solo una volta all'anno. Dal 31 dicembre al 1 gennaio, enormi magazzini del rivenditore, complessivamente grandi come 20 campi da calcio, fermano le loro operazioni per 15 ore. E questo è l'unico intervallo di tempo per il trasferimento del sistema. Non avevamo margine d'errore nell'implementazione dei server.
Spiego subito: il mio racconto riflette gli strumenti e il processo di gestione delle configurazioni utilizzati dal nostro team.
Il complesso di gestione delle configurazioni è composto da diversi livelli. Il componente chiave è il sistema CMS. In un'operazione industriale, l'assenza di uno dei livelli porterebbe inevitabilmente a spiacevoli sorprese.
Gestione dell'installazione del sistema operativo
Il primo livello è il sistema di gestione dell'installazione dei sistemi operativi su server fisici e virtuali. Esso crea configurazioni base del sistema operativo, eliminando il fattore umano.
Con questo sistema abbiamo ottenuto esemplari di server con sistema operativo già configurati e pronti per ulteriore automazione. Durante il "deployment", venivano creati un numero minimo di utenti locali e chiavi pubbliche SSH, oltre a una configurazione coerente del sistema operativo. Potevamo gestire i server in modo garantito tramite CMS e eravamo certi che non ci fossero sorprese a livello di sistema operativo.
L'obiettivo massimo per il sistema di gestione delle installazioni è configurare automaticamente i server dal livello BIOS/Firmware fino al sistema operativo. Molto dipende dall'hardware e dalle esigenze di configurazione. Per hardware eterogeneo, si può considerare . Se tutto l'hardware proviene dallo stesso fornitore, spesso è più utile utilizzare strumenti di gestione già pronti (ad esempio, HP ILO Amplifier, DELL OpenManage, ecc.).
Per l'installazione del sistema operativo sui server fisici, abbiamo utilizzato il ben noto Cobbler, in cui è definito un insieme di profili di installazione concordati con il servizio operativo. Quando un nuovo server viene aggiunto all'infrastruttura, l'ingegnere associa l'indirizzo MAC del server al profilo richiesto in Cobbler. Al primo avvio tramite rete, il server riceve un indirizzo temporaneo e un sistema operativo aggiornato. Viene quindi trasferito nella VLAN/indirizzamento IP di destinazione e si continua a lavorare da lì. Sì, cambiare VLAN richiede tempo e approvazione, ma fornisce una protezione aggiuntiva contro l'installazione accidentale del server nell'ambiente di produzione.
I server virtuali sono stati creati sulla base di modelli preparati con HashiCorp Packer. La ragione è la medesima: prevenire possibili errori umani nell'installazione del sistema operativo. Tuttavia, a differenza dei server fisici, Packer consente di non utilizzare PXE, l'avvio di rete e il cambio della VLAN. Questo ha reso più semplice e pratico il processo di creazione dei server virtuali.

Fig. 1. Gestione dell'installazione dei sistemi operativi.
Gestione dei segreti
Qualsiasi sistema di gestione della configurazione contiene dati che devono essere nascosti agli utenti comuni, ma sono necessari per la preparazione dei sistemi. Questi includono le password degli utenti locali e degli account di servizio, le chiavi dei certificati, vari token API e così via. Di solito sono chiamati "segreti".
Se non si definisce fin dall'inizio dove e come memorizzare questi segreti, a seconda della severità dei requisiti di sicurezza, le modalità di memorizzazione potrebbero essere le seguenti:
- direttamente nel codice di gestione della configurazione o in file nel repository;
- in strumenti specializzati di gestione della configurazione (ad esempio, Ansible Vault);
- in sistemi CI/CD (Jenkins/TeamCity/GitLab ecc.) o in sistemi di gestione della configurazione (Ansible Tower/Ansible AWX);
- i segreti possono anche essere gestiti manualmente. Ad esempio, vengono pubblicati in un luogo concordato, per poi essere utilizzati dai sistemi di gestione della configurazione;
- diverse combinazioni delle modalità sopra descritte.
Ogni metodo ha i suoi svantaggi. Il principale è l'assenza di politiche di accesso ai segreti: non è possibile o è difficile determinare chi può utilizzare determinati segreti. Un altro svantaggio è la mancanza di audit dell'accesso e di un ciclo di vita completo. Quanto è semplice sostituire, ad esempio, una chiave pubblica che è scritta nel codice e in vari sistemi collegati?
Abbiamo utilizzato un archivio centralizzato per i segreti, HashiCorp Vault. Questo ci ha permesso di:
- archiviare i segreti in sicurezza. Sono crittografati e anche se qualcuno dovesse avere accesso al database dell'archivio Vault (ad esempio, recuperandolo da un backup), non sarebbe in grado di leggere i segreti ivi conservati;
- organizzare politiche di accesso ai segreti. Gli utenti e le applicazioni hanno accesso solo ai segreti 'assegnati' loro;
- condurre audit dell'accesso ai segreti. Qualsiasi azione relativa ai segreti viene registrata nel registro audit di Vault;
- gestire un 'ciclo di vita' completo per l'uso dei segreti. È possibile crearli, revocarli, impostare una scadenza, ecc.;
- integrarsi facilmente con altri sistemi che necessitano di accesso ai segreti;
- e inoltre applicare la crittografia end-to-end, le password usa e getta per il sistema operativo e il database, i certificati delle autorità di certificazione, ecc.
Passiamo ora al sistema centrale di autenticazione e autorizzazione. Si poteva fare a meno di esso, ma amministrare gli utenti in molteplici sistemi correlati è troppo complesso. Abbiamo configurato l'autenticazione e l'autorizzazione tramite il servizio LDAP. Altrimenti, in Vault si sarebbe dovuto emettere e gestire continuamente i token di autenticazione per gli utenti. E l'aggiunta e la rimozione degli utenti sarebbero diventate una quest 'ho creato/eliminato questa utenza ovunque?'
Aggiungiamo un ulteriore livello al nostro sistema: gestione dei segreti e autenticazione/ autorizzazione centralizzata:

Fig. 2. Gestione dei segreti.
Gestione delle configurazioni
Siamo arrivati al cuore — al sistema CMS. Nel nostro caso, si tratta della combinazione Ansible e Red Hat Ansible AWX.
Al posto di Ansible può essere usato Chef, Puppet, SaltStack. Abbiamo scelto Ansible per diversi criteri.
- In primo luogo, la sua versatilità. Il set di moduli già pronti per la gestione . E se non basta, si può cercare su GitHub e Galaxy.
- In secondo luogo, non è necessario installare e mantenere agenti su hardware gestito, dimostrare che non interferiscono con il carico e confermare l'assenza di "backdoor".
- In terzo luogo, Ansible ha una bassa barriera d'ingresso. Un ingegnere competente scriverà un playbook funzionante letteralmente il primo giorno di utilizzo del prodotto.
Tuttavia, un solo Ansible non era sufficiente in un ambiente industriale. Altrimenti, sarebbero sorti diversi problemi relativi al controllo degli accessi e all'audit delle azioni degli amministratori. Come delimitare l'accesso? Era necessario che ogni divisione gestisse (ovvero eseguisse il playbook di Ansible) il proprio insieme di server. Come consentire l'esecuzione di specifici playbook di Ansible solo a determinati dipendenti? O come tracciare chi ha eseguito il playbook, senza creare molteplici account locali sui server e sull'hardware gestito da Ansible?
La maggior parte di queste questioni è risolta da Red Hat , o dal suo progetto upstream open-source . Pertanto, lo abbiamo preferito per il cliente.
E un ulteriore dettaglio sul profilo del nostro sistema CMS. Il playbook di Ansible deve essere archiviato nei sistemi di gestione del repository di codice. Noi utilizziamo .
Quindi, le configurazioni sono gestite da un insieme di Ansible/Ansible AWX/GitLab (cfr. Figura 3). Ovviamente, AWX/GitLab sono integrati con un sistema di autenticazione unificato e il playbook di Ansible è con HashiCorp Vault. Le configurazioni entrano nell'ambiente di produzione solo tramite Ansible AWX, dove sono stabilite tutte le "regole del gioco": chi e cosa può configurare, da dove attingere il codice di gestione delle configurazioni per il CMS, ecc.

Figura 3. Gestione delle configurazioni.
Gestione dei test
La nostra configurazione è presentata sotto forma di codice. Pertanto, dobbiamo seguire le stesse regole degli sviluppatori software. È stato necessario organizzare i processi di sviluppo, test continuo, distribuzione e applicazione del codice di configurazione sui server di produzione.
Se non lo si fa immediatamente, i ruoli scritti per la configurazione smetterebbero di essere mantenuti e modificati, oppure smetterebbero di essere eseguiti in produzione. La soluzione a questo problema è nota e ha dato buoni risultati in questo progetto:
- ogni ruolo è coperto da test modulari;
- i test vengono eseguiti automaticamente ad ogni modifica del codice che gestisce le configurazioni;
- Le modifiche al codice di gestione delle configurazioni vengono trasferite nell'ambiente di produzione solo dopo aver superato con successo tutti i test e la revisione del codice.
Lo sviluppo del codice e la gestione delle configurazioni sono diventati più tranquilli e prevedibili. Per organizzare test continui, abbiamo utilizzato gli strumenti di GitLab CI/CD, e come framework per l'organizzazione dei test abbiamo scelto .
Ogni volta che c'è una modifica nel codice di gestione delle configurazioni, GitLab CI/CD invoca Molecule:
- esso verifica la sintassi del codice,
- innalza un contenitore Docker,
- applica il codice modificato nel contenitore creato,
- verifica il ruolo per l'idempotenza e esegue i test per quel codice (la granularità qui è a livello del ruolo Ansible, vedi Fig. 4).
Abbiamo consegnato le configurazioni nell'ambiente di produzione utilizzando Ansible AWX. Gli ingegneri responsabili della gestione applicavano le modifiche alla configurazione tramite modelli predefiniti. AWX richiedeva autonomamente la versione più recente del codice dal ramo master di GitLab ad ogni applicazione. In questo modo abbiamo escluso l'uso di codice non verificato o obsoleto nell'ambiente di produzione. Naturalmente, il codice arrivava al ramo master solo dopo test, revisione e approvazione.

Fig. 4. Test automatici dei ruoli in GitLab CI/CD.
C'è un altro problema legato alla gestione delle sistemi di produzione. Nella realtà, è molto difficile apportare modifiche alla configurazione solo attraverso il codice CMS. Si verificano situazioni impreviste in cui l'ingegnere deve modificare la configurazione 'qui e ora', senza attendere la revisione del codice, i test, l'approvazione, ecc.
Di conseguenza, a causa delle modifiche manuali, ci sono discrepanze nella configurazione su hardware simile (ad esempio, le impostazioni di sysctl sui nodi di un cluster HA sono diverse). Oppure la configurazione reale sull'hardware differisce da quella definita nel codice CMS.
Pertanto, oltre al test continuo, controlliamo gli ambienti di produzione per eventuali discrepanze nelle configurazioni. Abbiamo scelto l'opzione più semplice: eseguire il codice di configurazione CMS in modalità 'dry run', ossia senza applicare modifiche, ma notificando tutte le discrepanze tra la configurazione pianificata e quella reale. Abbiamo implementato ciò attraverso esecuzioni periodiche di tutti gli Ansible playbook con l'opzione '—check' sui server di produzione. Come sempre, Ansible AWX si occupa dell'esecuzione e della validità dei playbook (vedi Fig. 5):

Fig. 5. Controlli delle discrepanze di configurazione in Ansible AWX.
Dopo i controlli, AWX invia un rapporto sulle discrepanze agli amministratori. Essi esaminano la configurazione problematica e poi la correggono tramite playbook aggiornati. In questo modo, manteniamo la configurazione nell'ambiente di produzione e il CMS rimane sempre aggiornato e sincronizzato. Questo elimina sgradevoli 'sorpresi' quando il codice CMS viene applicato su server 'live'.
Ora abbiamo un livello di testing importante, composto da Ansible AWX/GitLab/Molecule (Fig. 6).

Fig. 6. Gestione del testing.
Difficile? Non lo nego. Ma questo complesso di gestione delle configurazioni rappresenta una risposta esaustiva a molte delle domande legate all'automazione della configurazione dei server. Ora, per un rivenditore, i server standard hanno sempre una configurazione rigorosamente definita. La CMS, a differenza dell'ingegnere, non dimenticherà di aggiungere le impostazioni necessarie, creare utenti e completare decine o centinaia di impostazioni richieste.
Oggi, nelle impostazioni dei server e degli ambienti, non ci sono più "conoscenze segrete". Tutte le caratteristiche necessarie sono riflesse nel playbook. Niente più creatività e istruzioni vaghe: "imposta come un normale Oracle, ma bisogna scrivere un paio di impostazioni sysctl e aggiungere utenti con il UID appropriato. Chiedi ai ragazzi dell'operatività, loro lo sanno».
La possibilità di rilevare le discrepanze nelle configurazioni e di correggerle in anticipo offre tranquillità. Senza un sistema di gestione delle configurazioni, di solito la situazione è diversa. I problemi si accumulano fino a quando non "esplodono" in produzione. Poi si fa un'analisi, si controllano e si correggono le configurazioni. E il ciclo si ripete di nuovo.
E naturalmente, abbiamo ridotto il tempo di avvio dei server da giorni a ore.
E nella notte di Capodanno, quando i bambini aprivano felicemente i regali e gli adulti esprimevano desideri al suono delle campane, i nostri ingegneri hanno migrato il sistema SAP su nuovi server. Anche Babbo Natale dirà che i migliori miracoli sono ben preparati.
P.S. Il nostro team si trova spesso di fronte alla situazione in cui i clienti vogliono risolvere il compito della gestione delle configurazioni nel modo più semplice possibile. L'ideale sarebbe che fosse come per magia — con uno strumento solo. Ma nella vita la situazione è più complicata (sì, di nuovo non sono arrivate le pallottole d'argento): è necessario creare un intero processo utilizzando strumenti comodi per il team del cliente.
Autore: Sergey Artemov, architetto del reparto «Infocom Systems Jet»
Fonte: habr.com
