
Con l'aumentare dell'esperienza nel settore IT, inizi a notare che i sistemi hanno un loro carattere. Possono essere docili, silenziosi, capricciosi, severi. Possono attrarre o respingere. In un modo o nell'altro, bisogna 'contrattare' con loro, districarsi tra 'pietre miliari' e costruire catene di interazione.
Ebbene, anche a noi è toccato l'onore di costruire una piattaforma cloud, e per questo è stato necessario 'convincere' un paio di sottosistemi a lavorare con noi. Fortunatamente, abbiamo 'il linguaggio API', mani esperte e un sacco di entusiasmo.
In questo articolo non ci saranno dettagli tecnici hardcore, ma descriverò i problemi con cui ci siamo trovati ad affrontare durante la costruzione del cloud. Ho deciso di raccontare il nostro percorso sotto forma di una leggenda tecnica leggera su come abbiamo cercato un linguaggio comune con i sistemi e cosa ne è venuto fuori.
Benvenuti sotto il tag.
Inizio del percorso
Qualche tempo fa, al nostro team è stato assegnato il compito di avviare una piattaforma cloud per i nostri clienti. Avevamo a disposizione il supporto della direzione, risorse, una infrastruttura hardware e libertà nella scelta delle tecnologie per realizzare la parte software del servizio.
C'erano anche alcuni requisiti:
- il servizio ha bisogno di un'interfaccia utente comoda;
- la piattaforma deve essere integrata con il sistema di billing esistente;
- parte software e hardware: OpenStack + Tungsten Fabric (Open Contrail), che i nostri ingegneri hanno imparato a 'preparare' abbastanza bene.
Racconteremo di come è stata formata la squadra, è stato sviluppato l'interfaccia dell'area personale e sono state prese decisioni di design in un'altra occasione, se ci sarà interesse da parte della comunità di Habra.
Strumenti che abbiamo deciso di utilizzare:
- Python + Flask + Swagger + SQLAlchemy - un set Python piuttosto standard;
- Vue.js per il frontend;
- l'interazione tra componenti e servizi è stata realizzata tramite Celery sopra AMQP.
Anticipando le domande sulla scelta di Python, spiego. Il linguaggio ha trovato la sua nicchia nella nostra azienda e intorno ad esso si è sviluppata una piccola, ma pur sempre presente, cultura. Pertanto, è stato deciso di iniziare a costruire il servizio proprio su di esso. Del resto, in queste situazioni, la velocità di sviluppo spesso fa la differenza.
Dunque, iniziamo la nostra conoscenza.
Bill il silenzioso - billing
Con questo ragazzo ci conoscevamo da tempo. Si sedeva sempre vicino e contava qualcosa in silenzio. A volte ci inoltrava le richieste degli utenti, gestiva le fatture dei clienti e amministrava i servizi. Un ragazzo normale e lavoratore. Tuttavia, ci sono state delle difficoltà. Era silenzioso, a volte pensieroso e spesso — pensava per conto suo.

Il billing è stato il primo sistema con cui abbiamo cercato di fare amicizia. E il primo problema che abbiamo incontrato è stato durante l'elaborazione dei servizi.
Ad esempio, quando creiamo o eliminiamo, il compito finisce in una coda interna di billing. Così è stata implementata una sistema di lavoro asincrono con i servizi. Per elaborare i nostri tipi di servizio, dovevamo "mettere" le nostre attività in questa coda. E qui ci siamo imbattuti in un problema: la mancanza di documentazione.

A giudicare dalla descrizione dell'API software, alla fine, è possibile risolvere questo problema, ma non avevamo tempo per dedicarci al reverse engineering, quindi abbiamo estratto la logica all'esterno e organizzato una coda di compiti sopra RabbitMQ. L'operazione sul servizio è avviata dal cliente dal pannello di controllo, avvolta in un "compito" Celery sul backend e eseguita dal billing e da OpenStack. Celery consente di gestire molto comodamente i compiti, organizzare i ripetizioni e monitorare lo stato. Ulteriori informazioni su "celery" possono essere lette, ad esempio, .
Inoltre, il billing non ha fermato il progetto in cui i soldi erano finiti. Parlando con gli sviluppatori, abbiamo scoperto che nel conteggio della statistica (e noi abbiamo bisogno di implementare esattamente questa logica) c'è una complessa interrelazione delle regole di arresto. Ma questi modelli non si adattano bene alle nostre realtà. Abbiamo anche implementato attraverso compiti su Celery, portando sul lato del backend la logica di gestione dei servizi.
Entrambi i problemi sopra menzionati hanno portato a un po' di espansione del codice e in futuro dovremo dedicarci al refactoring, per estrarre in un servizio separato la logica di lavoro con i compiti. Dobbiamo anche conservare parte delle informazioni sugli utenti e sui loro servizi nei nostri database, per mantenere questa logica.
Un altro problema è il silenzio.
In risposta a parte delle richieste all'API, Billy risponde silenziosamente "Ok". Ad esempio, è successo quando abbiamo effettuato accrediti di pagamenti promessi durante il test (di cui parlerò più avanti). Le richieste sono state eseguite correttamente e non abbiamo visto errori.

Ho dovuto esaminare i log mentre lavoravo con il sistema tramite l'interfaccia utente. Si è scoperto che la stessa fatturazione esegue tali richieste, cambiando il scope su un utente specifico, ad esempio, admin, passando il parametro su di esso.
In generale, nonostante le lacune nella documentazione e alcuni piccoli difetti nell'API, tutto è andato piuttosto bene. I log sono leggibili anche sotto carichi elevati, se si capisce come sono strutturati e cosa cercare. La struttura del database è complessa, ma abbastanza logica e persino attraente in alcune cose.
Quindi, per riassumere, i principali problemi che abbiamo incontrato durante l'interazione sono legati alle peculiarità dell'implementazione di un sistema specifico:
- funzioni non documentate che ci hanno colpito in un modo o nell'altro;
- codici sorgente chiusi (la fatturazione è scritta in C++), di conseguenza, impossibilità di risolvere il problema 1 in alcun modo, tranne che con il "metodo dell'approccio e degli errori".
Per fortuna, il prodotto ha un API piuttosto ampia e abbiamo integrato nel nostro pannello personale i seguenti sottomoduli:
- modulo di supporto tecnico — le richieste dal pannello personale vengono "proxificate" nella fatturazione in modo trasparente per i clienti del servizio;
- modulo finanziario — consente di emettere fatture ai clienti attuali, effettuare addebiti e generare documenti di pagamento;
- modulo di gestione dei servizi — per questo abbiamo dovuto implementare il nostro gestore. L'espandibilità del sistema ci ha aiutato e abbiamo "formato" Billy a un nuovo tipo di servizi.
Ci è voluto un po' di impegno, ma penso che con Billy ci troveremo bene.
Passeggiate nei campi di tungsteno — Tungsten Fabric
Campi di tungsteno, disseminati di centinaia di cavi, che fanno passare attraverso di loro migliaia di bit di informazioni. Le informazioni vengono raccolte in "pacchetti", analizzate, costruendo percorsi complessi, come per magia.

Questo è il dominio del secondo sistema, con cui abbiamo dovuto interagire — Tungsten Fabric (TF), precedentemente OpenContrail. Il suo compito è gestire l'hardware di rete, fornendo un'astrazione software a noi, come utenti. TF — SDN, incapsula in sé una logica complessa di interazione con l'hardware di rete. Ci sono articoli decenti sulla tecnologia stessa, ad esempio, .
Il sistema è integrato con OpenStack (di cui parleremo più avanti) tramite il plugin di Neutron.

Interazione dei servizi OpenStack.
Questo sistema ci è stato presentato dai ragazzi del dipartimento operativo. Utilizziamo l'API del sistema per gestire lo stack di rete dei nostri servizi. Finora non ci ha causato seri problemi o inconvenienti (non mi prenderò la responsabilità di parlare per i ragazzi dell'OE), ma ci sono stati alcuni eventi curiosi durante l'interazione.
Il primo si è presentato così: i comandi che richiedevano di stampare un grande volume di dati sulla console dell'istanza durante la connessione SSH semplicemente 'congelavano' la connessione, mentre su VNC tutto funzionava correttamente.

Per coloro che non sono familiari con il problema, sembra piuttosto divertente: ls /root funziona correttamente, mentre, ad esempio, top 'si blocca' completamente. Per fortuna, abbiamo già affrontato problemi simili. Si è risolto ottimizzando il MTU sul percorso dai nodi di calcolo ai router. A proposito, questo non è un problema di TF.
Il problema successivo ci aspettava dietro l'angolo. In un 'bellissimo' momento, la magia della routing è scomparsa, così, all'improvviso. TF ha smesso di gestire il routing sulle apparecchiature.

Abbiamo lavorato con OpenStack a livello di admin e successivamente siamo passati al livello dell'utente necessario. Sembra che SDN 'catturi' lo scope dell'utente con cui vengono eseguite le azioni. Il fatto è che questo stesso account da admin è utilizzato per la comunicazione tra TF e OpenStack. Durante il passaggio al conto dell'utente, la 'magia' svaniva. È stato deciso di creare un account separato per lavorare con il sistema. Questo ha permesso di lavorare senza compromettere la funzionalità dell'integrazione.
Forme di vita siliconiche — OpenStack
Una creatura siliconica di forma bizzarra vive vicino ai campi di tungsteno. Assomiglia a un bambino cresciuto, che con un solo colpo potrebbe schiacciarci, ma non mostra aggressività evidente. Non incute paura, ma le sue dimensioni destano preoccupazione. Così come la complessità di ciò che accade intorno.

OpenStack è il nucleo della nostra piattaforma.
OpenStack ha diversi sottosistemi, dei quali al momento utilizziamo principalmente Nova, Glance e Cinder. Ognuno di essi ha la propria API. Nova si occupa delle risorse di calcolo e della creazione di istanze, Cinder gestisce i volumi e le loro istantanee, Glance è il servizio di immagini che gestisce i modelli del sistema operativo e le relative informazioni meta.
Ogni servizio viene eseguito in un contenitore, con RabbitMQ come broker dei messaggi.
Questo sistema ci ha causato più grattacapi inaspettati.
E il primo problema non ha tardato ad arrivare, quando abbiamo cercato di collegare un volume aggiuntivo al server. L'API di Cinder si è categoricamente rifiutata di eseguire questa operazione. Piuttosto, se si crede a OpenStack stesso, la connessione viene stabilita, tuttavia all'interno del server virtuale il dispositivo disco è assente.

Abbiamo deciso di "andare per le lunghe" e abbiamo richiesto la stessa azione all'API di Nova. Risultato: il dispositivo viene connesso correttamente ed è accessibile all'interno del server. Sembra che il problema sorga quando lo storage block non risponde a Cinder.
Un'altra difficoltà ci aspettava nel lavoro con i dischi. Non siamo riusciti a scollegare il volume di sistema dal server.
Ancora una volta, OpenStack "giura" di aver distrutto la connessione e ora è possibile lavorare correttamente con il volume separatamente. Ma l'API categoricamente non desiderava eseguire operazioni sul disco.

Qui abbiamo deciso di non combattere particolarmente, ma di cambiare il nostro modo di vedere la logica di funzionamento del servizio. Se c'è un'istanza, deve esserci anche un volume di sistema. Pertanto, l'utente al momento non può eliminare o disattivare il "disco" di sistema senza prima eliminare il "server".
OpenStack è un complesso sistema piuttosto difficile con la propria logica di interazione e un'API tortuosa. Ci aiuta una documentazione abbastanza dettagliata e, naturalmente, il metodo di prova ed errore (dove andremmo senza di esso?).
Esecuzione del test
Abbiamo condotto l'esecuzione del test a dicembre dello scorso anno. L'obiettivo principale era verificare, dal punto di vista tecnico e dell'UX, il nostro progetto in modalità operativa. Abbiamo invitato un pubblico selezionato e il test è stato chiuso. Tuttavia, abbiamo anche lasciato la possibilità di richiedere l'accesso al test sul nostro sito.
Il test stesso, naturalmente, non è passato senza momenti curiosi, poiché le nostre avventure cominciano qui.
Innanzitutto, abbiamo sottovalutato l'interesse per il progetto e abbiamo dovuto aggiungere nodi di calcolo rapidamente durante il test. Un caso normale per un cluster, tuttavia anche qui ci sono state delle peculiarità. Nella documentazione per la versione specifica di TF è indicata una versione specifica del kernel su cui è stata testata la funzionalità con vRouter. Abbiamo deciso di avviare nodi con kernel più recenti. Il risultato: TF non ha ricevuto rotte dai nodi. Abbiamo dovuto tornare indietro ai kernel precedenti.

Un altro momento curioso riguarda la funzionalità del pulsante "cambia password" nel pannello personale.
Abbiamo deciso di utilizzare JWT per gestire l'accesso all'area riservata, evitando di lavorare con sessioni. Poiché i sistemi sono molto diversi e ampiamente distribuiti, gestiamo il nostro token, nel quale "incapsuliamo" le sessioni di billing e il token da OpenStack. Quando viene cambiata la password, il token, ovviamente, "scade", poiché i dati dell'utente non sono più validi e deve essere riemesso.

Abbiamo trascurato questo aspetto, e ci sono stati semplicemente pochi risorse per completare rapidamente questo pezzo. Abbiamo dovuto tagliare funzionalità giusto prima del lancio del test.
Attualmente eseguiamo il logout dell'utente se la password è stata cambiata.
Nonostante queste sfide, il test è andato bene. In poche settimane, circa 300 persone ci hanno visitato. Siamo riusciti a vedere il prodotto attraverso gli occhi degli utenti, a testarlo in azione e a raccogliere feedback di qualità.
Continua
Per molti di noi, questo è il primo progetto di tale portata. Abbiamo appreso diverse lezioni preziose su come lavorare in team, prendere decisioni architettoniche e di design. Come integrare sistemi complessi con risorse limitate e portarli in produzione.
Naturalmente, c'è molto su cui lavorare sia nel codice che nei punti di integrazione tra i sistemi. Il progetto è ancora giovane, ma siamo pieni di ambizioni di farne un servizio affidabile e comodo.
Siamo già riusciti a convincere i sistemi. Bill si occupa diligentemente dei calcoli, delle fatturazioni e delle richieste degli utenti nel suo angolo. La "magia" dei campi di tungsteno ci fornisce una connessione stabile. E solo OpenStack a volte si fa difficile, gridando qualcosa come "'WSREP non ha ancora preparato il nodo per l'uso delle applicazioni". Ma questa è un'altra storia...
Recentemente abbiamo lanciato il servizio.
Puoi scoprire tutti i dettagli sul nostro .

Team di sviluppo CLO
Link utili
OpenStack
Tungsten Fabric
Fonte: habr.com
