Modelli di archiviazione dei dati in Kubernetes

Modelli di archiviazione dei dati in Kubernetes
Ehi Habr!

Vi ricordiamo che ne abbiamo rilasciato un altro estremamente interessante e utile книга sui modelli Kubernetes. Tutto è iniziato con "Modelli" Brendan Burns e, a proposito, abbiamo del lavoro in questo segmento bolle. Oggi ti invitiamo a leggere un articolo del blog MinIO che delinea brevemente le tendenze e le specifiche dei modelli di archiviazione dei dati in Kubernetes.

Kubernetes ha cambiato radicalmente i modelli tradizionali di sviluppo e distribuzione delle applicazioni. Ora un team può sviluppare, testare e distribuire un'applicazione in pochi giorni, in più ambienti, tutti all'interno di cluster Kubernetes. Questo lavoro con le generazioni precedenti di tecnologia richiedeva solitamente settimane, se non mesi.

Questa accelerazione è resa possibile dall'astrazione fornita da Kubernetes, ovvero perché Kubernetes stesso interagisce con i dettagli di basso livello delle macchine fisiche o virtuali, consentendo agli utenti di dichiarare il processore desiderato, la quantità di memoria desiderata e il numero di contenitori istanze, tra gli altri parametri. Con un'enorme comunità che supporta Kubernetes e la sua adozione in continua espansione, Kubernetes è con un ampio margine il leader tra tutte le piattaforme di orchestrazione dei container.

Con l’aumento dell’utilizzo di Kubernetes, aumenta anche la confusione sui suoi modelli di archiviazione..

Dato che tutti competono per una fetta della torta Kubernetes (ovvero l'archiviazione dei dati), quando si parla di archiviazione dei dati, il segnale è annegato in un sacco di rumore.
Kubernetes incarna un modello moderno per lo sviluppo, la distribuzione e la gestione delle applicazioni. Questo modello moderno disaccoppia l’archiviazione dei dati dal calcolo. Per comprendere appieno il distacco nel contesto di Kubernetes, è necessario anche capire cosa sono le applicazioni stateful e stateless e come si inserisce l'archiviazione dei dati. È qui che l'approccio API REST utilizzato da S3 presenta chiari vantaggi rispetto all'approccio POSIX/CSI di altre soluzioni.

In questo articolo parleremo dei modelli di archiviazione dei dati in Kubernetes e toccheremo in particolare il dibattito tra applicazioni stateful e stateless per comprendere meglio qual è la differenza tra loro e perché è importante. Il resto del testo esaminerà le applicazioni e i relativi modelli di archiviazione dei dati alla luce delle migliori pratiche per lavorare con contenitori e Kubernetes.

Contenitori apolidi

I contenitori sono per natura leggeri ed effimeri. Possono essere facilmente arrestati, rimossi o distribuiti su un altro nodo, il tutto in pochi secondi. In un sistema di orchestrazione di contenitori di grandi dimensioni, tali operazioni si verificano continuamente e gli utenti non si accorgono nemmeno di tali cambiamenti. Tuttavia gli spostamenti sono possibili solo se il contenitore non ha dipendenze dal nodo su cui si trova. Si dice che tali contenitori funzionino apolide.

Contenitori con stato

Se un contenitore memorizza dati su dispositivi collegati localmente (o su un dispositivo a blocchi), in caso di guasto l'archivio dati su cui risiede dovrà essere spostato su un nuovo nodo, insieme al contenitore stesso. Questo è importante perché altrimenti l'applicazione in esecuzione nel contenitore non sarà in grado di funzionare correttamente poiché dovrà accedere ai dati archiviati sul supporto locale. Si dice che tali contenitori funzionino statale.

Da un punto di vista puramente tecnico i contenitori stateful possono essere spostati anche su altri nodi. Ciò si ottiene in genere utilizzando file system distribuiti o blocchi di archiviazione di rete collegati a tutti i nodi che eseguono contenitori. In questo modo, i contenitori accedono ai volumi per l'archiviazione persistente dei dati e le informazioni vengono archiviate su dischi situati in tutta la rete. Chiamerò questo metodo “approccio con contenitori con stato", e nel resto dell'articolo lo chiamerò così per ragioni di uniformità.

Modelli di archiviazione dei dati in Kubernetes

In un tipico approccio con contenitore con stato, tutti i pod dell'applicazione sono collegati a un singolo file system distribuito, una sorta di spazio di archiviazione condiviso in cui risiedono tutti i dati dell'applicazione. Sebbene siano possibili alcune variazioni, questo è un approccio di alto livello.

Ora vediamo perché l'approccio del contenitore con stato è un anti-modello in un mondo incentrato sul cloud.

Progettazione di applicazioni cloud-native

Tradizionalmente, le applicazioni utilizzavano database per l'archiviazione strutturata di informazioni e dischi locali o file system distribuiti in cui venivano scaricati tutti i dati non strutturati o anche semistrutturati. Man mano che i volumi di dati non strutturati crescevano, gli sviluppatori si sono resi conto che POSIX era troppo loquace, comportava un sovraccarico significativo e, in definitiva, ostacolava le prestazioni delle applicazioni quando si passava a scale veramente grandi.

Ciò ha contribuito principalmente all'emergere di un nuovo standard per l'archiviazione dei dati, ovvero l'archiviazione basata su cloud, che funziona principalmente sulla base dell'API REST e libera l'applicazione dalla gravosa manutenzione di un archivio dati locale. In questo caso, l'applicazione entra effettivamente in modalità stateless (poiché lo stato si trova nell'archiviazione remota). Le applicazioni moderne vengono create da zero tenendo presente questo fattore. Di norma, qualsiasi applicazione moderna che elabora dati di un tipo o dell'altro (log, metadati, blob, ecc.) è costruita secondo un paradigma orientato al cloud, in cui lo stato viene trasferito a un sistema software appositamente dedicato alla sua archiviazione.

L’approccio del contenitore con stato riporta l’intero paradigma esattamente al punto di partenza!

Utilizzando le interfacce POSIX per archiviare i dati, le applicazioni funzionano come se fossero stateful e, per questo motivo, si discostano dai principi più importanti della progettazione incentrata sul cloud, ovvero la capacità di variare la dimensione dei thread di lavoro dell'applicazione a seconda dei flussi in entrata. input.load, sposta su un nuovo nodo non appena il nodo corrente fallisce e così via.

Dando uno sguardo più attento a questa situazione, scopriamo che quando si sceglie un archivio dati, ci troviamo ancora e ancora di fronte al dilemma POSIX vs. API REST, MA con l'ulteriore aggravamento dei problemi POSIX a causa della natura distribuita degli ambienti Kubernetes. In particolare,

  • POSIX è loquace: la semantica POSIX richiede che ogni operazione sia associata a metadati e descrittori di file che aiutano a mantenere lo stato dell'operazione. Ciò si traduce in costi significativi che non hanno alcun valore reale. Le API di object storage, in particolare l'API S3, eliminano questi requisiti, consentendo all'applicazione di attivarsi e quindi di "dimenticarsi" della chiamata. La risposta del sistema di storage indica se l'azione ha avuto esito positivo o meno. Se fallisce, l'applicazione può riprovare.
  • Restrizioni di rete: In un sistema distribuito, è implicito che potrebbero esserci molte applicazioni che tentano di scrivere dati sullo stesso supporto collegato. Pertanto, non solo le applicazioni competeranno tra loro per la larghezza di banda di trasferimento dati (per inviare dati ai media), ma lo stesso sistema di archiviazione competerà per questa larghezza di banda inviando dati su dischi fisici. A causa della loquacità di POSIX, il numero delle chiamate di rete aumenta più volte. D'altra parte, l'API S3 fornisce una chiara distinzione tra le chiamate di rete tra quelle che hanno origine dal client al server e quelle che avvengono all'interno del server.
  • sicurezza: Il modello di sicurezza POSIX è progettato per la partecipazione umana attiva: gli amministratori configurano livelli di accesso specifici per ciascun utente o gruppo. Questo paradigma è difficile da adattare a un mondo incentrato sul cloud. Le applicazioni moderne dipendono da modelli di sicurezza basati su API, in cui i diritti di accesso sono definiti come un insieme di policy, vengono assegnati account di servizio, credenziali temporanee, ecc.
  • controllabilità: i contenitori con stato presentano un sovraccarico di gestione. Stiamo parlando di sincronizzare l'accesso parallelo ai dati, garantendo la coerenza dei dati, tutto ciò richiede un'attenta considerazione di quali modelli di accesso ai dati utilizzare. È necessario installare, monitorare e configurare software aggiuntivo, per non parlare dello sforzo di sviluppo aggiuntivo.

Interfaccia di archiviazione dei dati del contenitore

Sebbene la Container Storage Interface (CSI) sia stata di grande aiuto con la proliferazione del livello di volume Kubernetes, esternalizzandolo parzialmente a fornitori di storage di terze parti, ha anche inavvertitamente contribuito a credere che l'approccio del contenitore con stato sia il metodo consigliato per archiviare i dati in Kubernetes.

CSI è stato sviluppato come standard per fornire sistemi di archiviazione di file e blocchi arbitrari alle applicazioni legacy durante l'esecuzione su Kubernetes. E, come ha dimostrato questo articolo, l'unica situazione in cui un approccio con contenitore con stato (e CSI nella sua forma attuale) ha senso è quando l'applicazione stessa è un sistema legacy in cui non è possibile aggiungere il supporto per l'API di archiviazione degli oggetti. .

È importante capire che utilizzando CSI nella sua forma attuale, ovvero montando volumi quando si lavora con applicazioni moderne, incontreremo approssimativamente gli stessi problemi sorti nei sistemi in cui l'archiviazione dei dati è organizzata in stile POSIX.

Un approccio migliore

In questo caso, è importante comprendere che la maggior parte delle applicazioni non sono intrinsecamente progettate specificamente per il lavoro stateful o stateless. Questo comportamento dipende dall'architettura complessiva del sistema e dalle specifiche scelte progettuali effettuate. Parliamo un po' delle applicazioni stateful.

In linea di principio, tutti i dati della domanda possono essere suddivisi in diversi tipi generali:

  • Registrare i dati
  • Dati di marcatura temporale
  • Dati della transazione
  • metadati
  • Immagini del contenitore
  • Dati BLOB (oggetto binario di grandi dimensioni).

Tutti questi tipi di dati sono molto ben supportati sulle moderne piattaforme di archiviazione ed esistono diverse piattaforme native del cloud su misura per fornire dati in ciascuno di questi formati specifici. Ad esempio, i dati e i metadati delle transazioni possono risiedere in un moderno database nativo del cloud come CockroachDB, YugaByte, ecc. Le immagini del contenitore o i dati BLOB possono essere archiviati in un registro docker basato su MinIO. I dati di timestamp possono essere archiviati in un database di serie temporali come InfluxDB, ecc. Non entreremo nei dettagli su ciascun tipo di dati e sulle sue applicazioni qui, ma l'idea generale è quella di evitare l'archiviazione persistente dei dati che si basa sul montaggio del disco locale.

Modelli di archiviazione dei dati in Kubernetes

Inoltre, è spesso efficace fornire un livello di memorizzazione nella cache temporaneo che funge da archivio di file temporaneo per le applicazioni, ma le applicazioni non dovrebbero dipendere da questo livello come fonte di verità.

Archiviazione delle applicazioni con stato

Sebbene nella maggior parte dei casi sia utile mantenere le applicazioni senza stato, le applicazioni progettate per archiviare dati, ad esempio database, archivi di oggetti e archivi di valori-chiave, devono essere stateful. Diamo un'occhiata al motivo per cui queste applicazioni vengono distribuite su Kubernetes. Prendiamo come esempio MinIO, ma principi simili si applicano a qualsiasi altro sistema di storage nativo del cloud di grandi dimensioni.

Le applicazioni native del cloud sono progettate per sfruttare appieno la flessibilità intrinseca dei contenitori. Ciò significa che non fanno ipotesi sull’ambiente in cui verranno implementati. Ad esempio, MinIO utilizza un meccanismo di codifica di cancellazione interno per fornire al sistema sufficiente resilienza per rimanere operativo anche se metà dei dischi si guastano. MinIO gestisce inoltre l'integrità e la sicurezza dei dati utilizzando l'hashing e la crittografia proprietari lato server.

Per tali applicazioni incentrate sul cloud, i volumi persistenti locali (PV) sono più convenienti come spazio di archiviazione di backup. Il PV locale offre la possibilità di archiviare dati grezzi, mentre le applicazioni in esecuzione su questi PV raccolgono informazioni in modo indipendente per ridimensionare i dati e gestire i crescenti requisiti di dati.

Questo approccio è molto più semplice e significativamente più scalabile rispetto ai PV basati su CSI, che introducono nel sistema i propri livelli di gestione dei dati e ridondanza; il punto è che questi livelli solitamente entrano in conflitto con le applicazioni progettate per essere stateful.

Un forte movimento verso il disaccoppiamento dei dati dai calcoli

In questo articolo abbiamo parlato di come le applicazioni vengono riorientate per funzionare senza salvare lo stato o, in altre parole, l'archiviazione dei dati viene disaccoppiata dall'elaborazione su di essi. In conclusione, diamo un'occhiata ad alcuni esempi reali di questa tendenza.

Scintilla, un'importante piattaforma di analisi dei dati, è stata tradizionalmente stateful e distribuita su HDFS. Tuttavia, man mano che Spark si sposta in un mondo incentrato sul cloud, la piattaforma viene sempre più utilizzata senza stato utilizzando "s3a". Spark utilizza s3a per trasferire lo stato ad altri sistemi, mentre i contenitori Spark stessi operano in modo completamente senza stato. Altri importanti attori aziendali nel campo dell’analisi dei big data, in particolare, Vertica, Teradata, prugna verde Si stanno anche muovendo per lavorare con la separazione dell'archiviazione dei dati e dei calcoli su di essi.

Modelli simili possono essere visti anche su altre grandi piattaforme analitiche, tra cui Presto, Tensorflow to R, Jupyter. Scaricando lo stato su sistemi di archiviazione cloud remoti, diventa molto più semplice gestire e ridimensionare la tua applicazione. Inoltre, facilita la portabilità dell'applicazione in una varietà di ambienti.

Fonte: habr.com

Aggiungi un commento