Creazione di una piattaforma Kubernetes su Pinterest

Nel corso degli anni, i 300 milioni di utenti di Pinterest hanno creato più di 200 miliardi di pin su più di 4 miliardi di bacheche. Per servire questo esercito di utenti e una vasta base di contenuti, il portale ha sviluppato migliaia di servizi, che vanno dai microservizi che possono essere gestiti da poche CPU, ai giganteschi monoliti che funzionano su un'intera flotta di macchine virtuali. E poi arrivò il momento in cui gli occhi dell'azienda caddero sui K8. Perché il “cubo” ha fatto bella figura su Pinterest? Lo imparerai dalla nostra traduzione di un recente articolo di blog Pinterest ingegneria.

Creazione di una piattaforma Kubernetes su Pinterest

Quindi, centinaia di milioni di utenti e centinaia di miliardi di pin. Per servire questo esercito di utenti e una vasta base di contenuti, abbiamo sviluppato migliaia di servizi, che vanno dai microservizi che possono essere gestiti da poche CPU, ai giganteschi monoliti che funzionano su intere flotte di macchine virtuali. Inoltre, disponiamo di una varietà di framework che potrebbero richiedere anche l'accesso a CPU, memoria o I/O.

Nel mantenere questo zoo di strumenti, il team di sviluppo deve affrontare una serie di sfide:

  • Non esiste un modo uniforme in cui gli ingegneri possano gestire un ambiente di produzione. I servizi stateless, i servizi stateful e i progetti in fase di sviluppo attivo si basano su stack tecnologici completamente diversi. Ciò ha portato alla creazione di un intero corso di formazione per ingegneri e complica seriamente anche il lavoro del nostro team infrastrutturale.
  • Gli sviluppatori con il proprio parco macchine virtuali creano un enorme onere per gli amministratori interni. Di conseguenza, operazioni semplici come l'aggiornamento del sistema operativo o dell'AMI richiedono settimane e mesi. Ciò porta ad un aumento del carico di lavoro in situazioni apparentemente assolutamente quotidiane.
  • Difficoltà nel creare strumenti di gestione dell’infrastruttura globale in aggiunta alle soluzioni esistenti. La situazione è ulteriormente complicata dal fatto che trovare i proprietari delle macchine virtuali non è facile. Cioè, non sappiamo se questa capacità possa essere estratta in modo sicuro per operare in altre parti della nostra infrastruttura.

I sistemi di orchestrazione dei container rappresentano un modo per unificare la gestione del carico di lavoro. Aprono la porta ad una maggiore velocità di sviluppo e semplificano la gestione dell’infrastruttura, poiché tutte le risorse coinvolte nel progetto sono gestite da un sistema centralizzato.

Creazione di una piattaforma Kubernetes su Pinterest

Figura 1: priorità dell'infrastruttura (affidabilità, produttività degli sviluppatori ed efficienza).

Il team della piattaforma di gestione del cloud di Pinterest ha scoperto K8 nel 2017. Entro la prima metà del 2017 avevamo documentato la maggior parte delle nostre capacità di produzione, comprese le API e tutti i nostri server web. Successivamente, abbiamo condotto una valutazione approfondita di vari sistemi per orchestrare soluzioni container, creare cluster e lavorare con essi. Verso la fine del 2017 abbiamo deciso di utilizzare Kubernetes. Era abbastanza flessibile e ampiamente supportato nella comunità degli sviluppatori.

Fino ad oggi, abbiamo creato i nostri strumenti di avvio del cluster basati su Kops e migrato i componenti dell'infrastruttura esistenti come rete, sicurezza, metriche, registrazione, gestione delle identità e traffico su Kubernetes. Abbiamo anche implementato un sistema di modellazione del carico di lavoro per la nostra risorsa, la cui complessità è nascosta agli sviluppatori. Ora siamo concentrati nel garantire la stabilità del cluster, nel ridimensionarlo e nel connettere nuovi clienti.

Kubernetes: il metodo Pinterest

Iniziare con Kubernetes su scala di Pinterest come piattaforma che i nostri ingegneri adorerebbero ha comportato molte sfide.

Essendo una grande azienda, abbiamo investito molto negli strumenti infrastrutturali. Gli esempi includono strumenti di sicurezza che gestiscono certificati e distribuzione di chiavi, componenti di controllo del traffico, sistemi di rilevamento dei servizi, componenti di visibilità e componenti di invio di log e metriche. Tutto questo è stato raccolto per un motivo: abbiamo seguito il normale percorso di tentativi ed errori, e quindi volevamo integrare tutte queste apparecchiature nella nuova infrastruttura su Kubernetes invece di reinventare la vecchia ruota su una nuova piattaforma. Questo approccio nel complesso ha semplificato la migrazione, poiché tutto il supporto dell'applicazione esiste già e non è necessario crearlo da zero.

D'altra parte, i modelli di previsione del carico in Kubernetes stesso (come distribuzioni, lavori e set di daemon) non sono sufficienti per il nostro progetto. Questi problemi di usabilità rappresentano enormi ostacoli al passaggio a Kubernetes. Ad esempio, abbiamo sentito sviluppatori di servizi lamentarsi di impostazioni di accesso mancanti o errate. Abbiamo riscontrato anche un utilizzo non corretto dei motori di template, quando venivano create centinaia di copie con le stesse specifiche e attività, il che ha provocato problemi di debug da incubo.

Era anche molto difficile mantenere versioni diverse nello stesso cluster. Immagina la complessità dell'assistenza clienti se hai bisogno di lavorare contemporaneamente su più versioni dello stesso ambiente runtime, con tutti i relativi problemi, bug e aggiornamenti.

Proprietà utente e controller di Pinterest

Per facilitare ai nostri ingegneri l'implementazione di Kubernetes e per semplificare e velocizzare la nostra infrastruttura, abbiamo sviluppato le nostre definizioni di risorse personalizzate (CRD).

I CRD forniscono le seguenti funzionalità:

  1. Combinando diverse risorse Kubernetes native in modo che funzionino come un unico carico di lavoro. Ad esempio, la risorsa PinterestService include una distribuzione, un servizio di accesso e una mappa di configurazione. Ciò consente agli sviluppatori di non preoccuparsi della configurazione del DNS.
  2. Implementare il supporto applicativo necessario. L'utente deve concentrarsi solo sulle specifiche del contenitore in base alla propria logica aziendale, mentre il controller CRD implementa tutti i contenitori init necessari, le variabili di ambiente e le specifiche del pod. Ciò fornisce un livello di comfort fondamentalmente diverso per gli sviluppatori.
  3. I controller CRD gestiscono inoltre il ciclo di vita delle risorse native e migliorano la disponibilità del debug. Ciò include la riconciliazione delle specifiche desiderate con quelle effettive, l'aggiornamento dello stato del CRD, il mantenimento dei registri degli eventi e altro ancora. Senza CRD, gli sviluppatori sarebbero costretti a gestire più risorse, il che non farebbe altro che aumentare la probabilità di errore.

Ecco un esempio di PinterestService e di una risorsa interna gestita dal nostro controller:

Creazione di una piattaforma Kubernetes su Pinterest

Come puoi vedere sopra, per supportare un contenitore personalizzato dobbiamo integrare un contenitore init e diversi componenti aggiuntivi per fornire sicurezza, visibilità e traffico di rete. Inoltre, abbiamo creato modelli di mappa di configurazione e implementato il supporto per modelli PVC per processi batch, oltre al monitoraggio di più variabili di ambiente per tenere traccia dell'identità, del consumo di risorse e della raccolta dei rifiuti.

È difficile immaginare che gli sviluppatori vogliano scrivere questi file di configurazione a mano senza il supporto CRD, per non parlare della manutenzione e del debugging delle configurazioni.

Flusso di lavoro di distribuzione dell'applicazione

Creazione di una piattaforma Kubernetes su Pinterest

L'immagine sopra mostra come distribuire una risorsa personalizzata Pinterest su un cluster Kubernetes:

  1. Gli sviluppatori interagiscono con il nostro cluster Kubernetes tramite la CLI e l'interfaccia utente.
  2. Gli strumenti CLI/UI recuperano i file YAML di configurazione del flusso di lavoro e altre proprietà di build (stesso ID versione) da Artifactory e quindi li inviano al servizio di invio lavori. Questo passaggio garantisce che solo le versioni di produzione vengano consegnate al cluster.
  3. JSS è un gateway per varie piattaforme, incluso Kubernetes. Qui si autentica l'utente, si emettono le quote e si controlla parzialmente la configurazione del nostro CRD.
  4. Dopo aver controllato il CRD sul lato JSS, le informazioni vengono inviate all'API della piattaforma k8s.
  5. Il nostro controller CRD monitora gli eventi su tutte le risorse dell'utente. Converte le CR in risorse k8 native, aggiunge i moduli necessari, imposta le variabili di ambiente appropriate ed esegue altre attività di supporto per garantire che le applicazioni utente containerizzate dispongano di un supporto infrastrutturale sufficiente.
  6. Il controller CRD passa quindi i dati ricevuti all'API Kubernetes in modo che possano essere elaborati dallo scheduler e messi in produzione.

Nota: questo flusso di lavoro pre-release della distribuzione è stato creato per i primi utenti della nuova piattaforma k8s. Stiamo attualmente perfezionando questo processo per integrarlo completamente con il nostro nuovo CI/CD. Ciò significa che non possiamo dirti tutto ciò che riguarda Kubernetes. Non vediamo l'ora di condividere la nostra esperienza e i progressi del team in questa direzione nel nostro prossimo post sul blog, "Costruire una piattaforma CI/CD per Pinterest".

Tipi di risorse speciali

In base alle esigenze specifiche di Pinterest, abbiamo sviluppato i seguenti CRD per adattarsi a diversi flussi di lavoro:

  • PinterestService sono servizi senza stato che funzionano da molto tempo. Molti dei nostri sistemi principali si basano su una serie di tali servizi.
  • PinterestJobSet modella lavori batch a ciclo completo. Uno scenario comune su Pinterest è che più lavori eseguono gli stessi contenitori in parallelo, indipendentemente da altri processi simili.
  • PinterestCronJob è ampiamente utilizzato insieme a piccoli carichi periodici. Si tratta di un wrapper per il lavoro cron nativo con meccanismi di supporto di Pinterest responsabili della sicurezza, del traffico, dei log e delle metriche.
  • PinterestDaemon include demoni dell'infrastruttura. Questa famiglia continua a crescere man mano che aggiungiamo ulteriore supporto ai nostri cluster.
  • PinterestTrainingJob si estende ai processi Tensorflow e Pytorch, fornendo lo stesso livello di supporto runtime di tutti gli altri CRD. Poiché Pinterest utilizza attivamente Tensorflow e altri sistemi di apprendimento automatico, avevamo un motivo per creare un CRD separato attorno ad essi.

Stiamo anche lavorando su PinterestStatefulSet, che sarà presto adattato per data warehouse e altri sistemi stateful.

Supporto in fase di esecuzione

Quando un pod dell'applicazione viene eseguito su Kubernetes, riceve automaticamente un certificato per identificarsi. Questo certificato viene utilizzato per accedere all'archivio segreto o per comunicare con altri servizi tramite mTLS. Nel frattempo, Container Init Configurator e Daemon scaricheranno tutte le dipendenze necessarie prima di eseguire l'applicazione containerizzata. Quando tutto sarà pronto, il sidecar del traffico e Daemon registreranno l'indirizzo IP del modulo con il nostro Zookeeper in modo che i clienti possano scoprirlo. Tutto ciò funzionerà perché il modulo di rete è stato configurato prima dell'avvio dell'applicazione.

Quelli sopra riportati sono esempi tipici di supporto runtime per i carichi di lavoro. Altri tipi di carichi di lavoro potrebbero richiedere un supporto leggermente diverso, ma si presentano tutti sotto forma di sidecar a livello di pod, demoni a livello di nodo o di macchina virtuale. Garantiamo che tutto ciò sia distribuito all'interno dell'infrastruttura di gestione e sia coerente tra le applicazioni, il che, in definitiva, riduce significativamente l'onere in termini di lavoro tecnico e supporto clienti.

Test e QA

Abbiamo creato una pipeline di test end-to-end sull'infrastruttura di test Kubernetes esistente. Questi test si applicano a tutti i nostri cluster. La nostra pipeline ha subito numerose revisioni prima di diventare parte del cluster di prodotti.

Oltre ai sistemi di test, disponiamo di sistemi di monitoraggio e allerta che monitorano costantemente lo stato dei componenti del sistema, il consumo di risorse e altri indicatori importanti, avvisandoci solo quando è necessario l'intervento umano.

alternative

Abbiamo esaminato alcune alternative alle risorse personalizzate, come i controller di accesso alle mutazioni e i sistemi di modelli. Tuttavia, comportano tutte sfide operative significative, quindi abbiamo scelto la strada CRD.

È stato utilizzato un controller di ammissione mutazionale per introdurre sidecar, variabili di ambiente e altro supporto di runtime. Tuttavia, ha dovuto affrontare vari problemi, come il vincolo delle risorse e la gestione del ciclo di vita, laddove tali problemi non si presentano nel CRD.

Nota: Anche i sistemi modello come i grafici Helm sono ampiamente utilizzati per eseguire applicazioni con configurazioni simili. Tuttavia, le nostre applicazioni lavorative sono troppo diverse per essere gestite utilizzando i modelli. Inoltre durante la distribuzione continua si verificheranno troppi errori durante l'utilizzo dei modelli.

Prossimi lavori

Attualmente abbiamo a che fare con un carico misto su tutti i nostri cluster. Per supportare tali processi di diversa tipologia e dimensione, operiamo nelle seguenti aree:

  • Una raccolta di cluster distribuisce applicazioni di grandi dimensioni su diversi cluster per garantire scalabilità e stabilità.
  • Garantire stabilità, scalabilità e visibilità del cluster per creare connettività e SLA delle applicazioni.
  • Gestiamo risorse e quote in modo che le applicazioni non entrino in conflitto tra loro e la dimensione del cluster sia controllata da noi.
  • Una nuova piattaforma CI/CD per supportare e distribuire applicazioni su Kubernetes.

Fonte: habr.com

Aggiungi un commento