Guida Rubrica KUBE 2: Architettura di Kubernetes

Kode

Utente Emerald
10 Dicembre 2013
1,226
81
371
623

kube_1.jpg


All'interno di questo capitolo della rubrica dedicata a Kubernetes, andremo a discutere della sua architettura andandoci a soffermare sulle varie componenti, su cosa rappresentano e su come vengano messe in relazioni con il sistema in modo da poter garantire servizi e funzionalità. Ci soffermeremo su concetti come Pods, Clusters, Container, Storage per poi andare a descrivere strumenti di gestione come Admin Cluster e Scheduling e tanto altro ancora!

Non segui la nostra rubrica? Leggi il primo capitolo sulla Introduzione a Kubernetes!

I. Capitoli
1.
Introduzione a Kubernetes: cos'è, infrastruttura su cui si basa, vantaggi, caratteristiche e nomenclatura.
2. Architettura di Kubernetes: Architettura Cluster, Container, Pods, Admin Cluster, Storage e Scheduling.
3.
Configurazione di un ambiente Kubernetes: Set up, configurazione dei container, dei pods ed esecuzione di applicazioni.
4. Creazione della prima applicazione su Kubernetes: Hello MiniKube!
5. Creazione di un'applicazione stateless su Kubernetes
(*) La rubrica potrebbe subire delle estensioni in caso il progetto riceva un buon feedback.

1. Il concetto del Cloud Controller Manager (CCM)

L' architettura di Kubernetes si basa sulla struttura del Cloud Controller Manager. Tale concetto è stato originariamente creato per poter sviluppare Kubernetes in maniera indipendente dal Cloud Provider che utilizza.

Il cloud controller manager viene eseguito insieme ad altri componenti principali come il Kubernetes controller manager, il server API e lo scheduler. Può anche essere avviato come add-on di Kubernetes, nel qual caso viene eseguito su Kubernetes.

Il design del cloud controller manager è basato su un meccanismo di plug-in che consente ai nuovi provider cloud di integrarsi facilmente con Kubernetes creando un plug-in. Sono in atto programmi per l'aggiunta di nuovi provider di cloud su Kubernetes e per la migrazione dei provider che usano il vecchio metodo a questo nuovo metodo.


2. Componenti di interazione con il CCM

1600848300121.png


Da come si può evincere dal diagramma precedente, le componenti che interagiscono e che integrano il Cloud Provider con il resto dell'architettura Kubernetes sono:
  1. Kubelet
  2. Kubernetes Controller Manager (KCM)
  3. Kubernetes API Server
Le connessioni che si creano con il Cloud Provider sono poi state semplificate andando ad integrare il CP con il solo Kubernetes Controller Manager che, tramite le Kubernetes API Server, riescono a far interagire in maniera implicita il Cloud Provider con le kubelet e i proxy annessi.

Di seguito viene presentata la "nuova" architettura basata su CCM in cui il ponte di connessione tra Cloud Provider e le componenti Kubernetes è rappresentato dal solo KCM.

1600848693556.png


3. Componenti del CCM

Il CCM divide alcune funzionalità del Kubernetes controller manager (KCM) e le esegue in un differente processo. In particolare, toglie dal KCM le integrazioni con il cloud specifico. Il KCM ha i seguenti controller che dipendono dal cloud specifico:
  • Node controller
  • Volume controller
  • Route controller
  • Service controller
Nota: Nelle versioni 1.9+, il CCM provvede alla gestione di tutti i controller tranne per il Volume Controller per la sua complessità in relazione ai vari Cloud Provider annessi.

Il piano originale per supportare i volumi utilizzando il CCM era di utilizzare Flex per supportare volumi collegabili. Tuttavia, una implementazione parallela, nota come CSI (Container Storage Interface, che espone una interfaccia capace di far interagire lo storage distribuito con i vari container) è stata designata per sostituire Flex.

Le componenti di Kubernetes sono rappresentate dalle componenti del Cloud Controller Manager, dato che esso dipende dal Cloud Provider scelto in fase di configurazione di sistema, andremo a parlarne in maniera generica senza soffermarci su esempi pratici verso una particolare piattaforma Cloud.

3.1 Kubernetes Controller Manager

Come abbiamo detto prima, questa componente ha come funzionalità principale quella di gestire le varie operazioni che collegano Kubernetes stesso al Cloud Provider. Poiché alla base del KCM si trova la gestione dei 3 controller sopra elencati, semplifichiamo tale spiegazione andando a parlare direttamente dei controller che gestisce.

3.3.1 Node Controller

Il Node controller è responsabile per l'inizializzazione di un nodo ottenendo informazioni sui nodi in esecuzione nel cluster dal provider cloud. Il controller del nodo esegue le seguenti funzioni:
  1. Inizializzare un nodo con le label zone/region specifiche per il cloud in uso.
  2. Inizializzare un nodo con le specifiche, ad esempio, tipo e dimensione specifiche del cloud in uso.
  3. Ottenere gli indirizzi di rete del nodo e l'hostname.
  4. Nel caso in cui un nodo non risponda, controlla il cloud per vedere se il nodo è stato cancellato dal cloud. Se il nodo è stato eliminato dal cloud, elimina l'oggetto Nodo di Kubernetes.
3.3.2 Route Controller

Quando si parla di route, si fa sempre riferimento ad una comunicazione remota. Infatti questo controller si occupa della gestione della comunicazione nel cloud riferita ai vari container localizzati in nodi differenti del cluster.
Il Route controller è utilizzabile solo dai cluster su Google Compute Engine.

3.3.3 Service Controller

Gestisce l'inserimento, l'aggiornamento o la rimozione di un servizio. In base allo stato attuale dei servizi in Kubernetes, configura i bilanciatori di carico forniti dal cloud (come gli ELB, i Google LB, o gli Oracle Cloud Infrastructure LB) per riflettere lo stato dei servizi in Kubernetes. Inoltre, assicura che i back-end dei bilanciatori di carico forniti dal cloud siano aggiornati.

3.2 Kubelet

Il Node Controller contiene l'implementazione dipendente dal cloud della kubelet. Prima dell'introduzione del CCM, la kubelet era responsabile dell'inizializzazione di un nodo con dettagli dipendenti dallo specifico cloud come gli indirizzi IP, le label region/zone e le informazioni sul tipo di istanza. L'introduzione del CCM ha spostato questa operazione di inizializzazione dalla kubelet al CCM.

In questo nuovo modello, la kubelet inizializza un nodo senza informazioni specifiche del cloud. Tuttavia, aggiunge un blocco al nodo appena creato che rende il nodo non selezionabile per eseguire container finché il CCM non inizializza il nodo con le informazioni specifiche del cloud. Il CCM rimuove quindi questo blocco.

3.3 Sistema a plug-in

Il cloud controller manager utilizza le interfacce di Go per consentire l'implementazione di implementazioni di qualsiasi cloud. In particolare, utilizza l'interfaccia CloudProvider definita qui (non vi preoccupate, vedremo nelle lezioni successive come utilizzare questa interfaccia).

L'implementazione dei quattro controller generici evidenziati sopra, alcune strutture, l'interfaccia cloud provider condivisa rimarranno nel core di Kubernetes. Le implementazioni specifiche per i vari cloud saranno costruite al di fuori del core e implementeranno le interfacce definite nel core.

Se si vuole approfondire il concetto di Sistema a plug-in, vi rimando al link della documentazione ufficiale: Developing Cloud Controller Manager.

3.4 Nodi

Kubernetes esegue il carico di lavoro inserendo i contenitori nei pod da eseguire sui nodi. Un nodo può essere una macchina virtuale o fisica, a seconda del cluster. Ogni nodo contiene i servizi necessari per eseguire i Pod, gestiti dal piano di controllo.

In genere si hanno diversi nodi in un cluster; in un ambiente di apprendimento o con risorse limitate, potresti averne solo uno.

I componenti su un nodo includono il kubelet, un runtime del contenitore e il kube-proxy.

3.5 Container

Un Container non è altro che un contenitore in cui vengono eseguiti particolari istanze di un programma prelevato partendo da una sua immagine. Notiamo che i container sono ripetibili, standarizzabili e distribuiti. Questo garantisce maggior gestione da parte di Kubernetes (e di altre architetture basata su container come, ad esempio, Docker) che può gestire il carico di lavoro in maniera ottimale.

Ricordiamo che i Container vengono eseguiti dentro un Pods di un Nodo. Un Pods per definizione è un working-set formato da una serie di applicazioni eseguite in container paralleli su uno stesso nodo.

Passiamo ora all'analisi dell'ambiente interno del container, in esso ci sono 3 tipi di informazioni:
1. Filesystem: che comprende una serie di immagini e di volumi caricati all'interno del container adibiti all'esecuzione di applicazioni.
2. Informazioni del container
3. Informazioni sul cluster in cui si trova il nodo a cui appartiene

Per quanto riguarda un hostname del container, esso è uguale a quello del pods. Per visualizzarlo basta accedere dentro la CLI del pods (vedremo in seguito come) e digitare il comando hostname.

3.6 Storage

Poichè l'architettura Kubernetes si basa su un livello di storage su più fronti, andreemo a descriverne alcuni dei principali.

3.6.1 Volumi

I file su disco in un contenitore sono temporanei, il che presenta alcuni problemi per le applicazioni non banali quando vengono eseguite nei contenitori. Innanzitutto, quando un contenitore si arresta in modo anomalo, kubelet lo riavvia, ma i file andranno persi: il contenitore inizia con uno stato pulito. In secondo luogo, quando si eseguono i contenitori insieme in un pod è spesso necessario condividere i file tra questi contenitori. L'astrazione del volume Kubernetes risolve entrambi questi problemi.

Se si vuole approfondire il concetto di volume, quali sono i tipi e come configurarli, vi rimando al link della documentazione ufficiale cliccando qui.

3.6.2 Volumi Persistenti

La gestione dello storage è un problema distinto dalla gestione delle istanze di calcolo. Il sottosistema PersistentVolume fornisce un'API per utenti e amministratori che astrae i dettagli di come lo storage viene fornito da come viene consumato. Per fare ciò, introduciamo due nuove risorse API: PersistentVolume e PersistentVolumeClaim.

Un PersistentVolume (PV) è una parte di archiviazione nel cluster che è stata fornita da un amministratore o sottoposta a provisioning dinamico utilizzando le classi di archiviazione. È una risorsa nel cluster proprio come un nodo è una risorsa del cluster. I PV sono plug-in di volume come i Volumi del paragrafo precedente, ma hanno un ciclo di vita indipendente da ogni singolo Pod che utilizza il PV. Questo oggetto API acquisisce i dettagli dell'implementazione dello storage, sia esso NFS, iSCSI o un sistema di storage specifico del provider di cloud.

Un PersistentVolumeClaim (PVC) è una richiesta di archiviazione da parte di un utente. È simile a un pod. I pod consumano risorse del nodo e i PVC consumano risorse PV. I pod possono richiedere livelli specifici di risorse (CPU e memoria). Le attestazioni possono richiedere dimensioni e modalità di accesso specifiche (ad esempio, possono essere montate ReadWriteOnce, ReadOnlyMany o ReadWriteMany...).

Sebbene PersistentVolumeClaims consenta a un utente di consumare risorse di archiviazione astratte, è comune che gli utenti abbiano bisogno di PersistentVolumes con proprietà diverse, ad esempio prestazioni, per problemi diversi. Gli amministratori del cluster devono essere in grado di offrire una varietà di PersistentVolume che differiscono in più modi oltre alle dimensioni e alle modalità di accesso, senza esporre gli utenti ai dettagli di come tali volumi vengono implementati. Per queste esigenze è disponibile la risorsa StorageClass.

3.6.3 Storage Classes

Una StorageClass fornisce agli amministratori un modo per descrivere le "classi" di archiviazione che si offrono. Classi diverse potrebbero essere mappate a livelli di qualità del servizio, a policy di backup o a policy arbitrarie determinate dagli amministratori del cluster. Kubernetes stesso non ha opinioni su ciò che rappresentano le classi. Questo concetto è talvolta chiamato "profili" in altri sistemi di archiviazione.

3.7 Kube-Scheduler

kube-scheduler è lo scheduler predefinito per Kubernetes e viene eseguito come parte del piano di controllo. kube-scheduler è progettato in modo che, se lo desideri e ne hai bisogno, puoi scrivere il tuo componente di pianificazione e usarlo direttamente.

Per ogni pod appena creato o altri pod non pianificati, kube-scheduler seleziona un nodo ottimale su cui eseguirli. Tuttavia, ogni contenitore nei pod ha requisiti diversi per le risorse e ogni pod ha anche requisiti diversi. Pertanto, i nodi esistenti devono essere filtrati in base ai requisiti di pianificazione specifici.

In un cluster, i nodi che soddisfano i requisiti di pianificazione per un pod sono chiamati nodi ammissibili. Se nessuno dei nodi è adatto, il pod rimane non pianificato finché lo scheduler non è in grado di posizionarlo.

Lo scheduler trova i Nodi ammissibili per un Pod, quindi esegue una serie di funzioni per assegnare il punteggio ai Nodi ammissibili e seleziona un Nodo con il punteggio più alto tra quelli fattibili per eseguire il Pod. Lo scheduler notifica quindi al server API questa decisione in un processo chiamato binding.

I fattori che devono essere presi in considerazione per le decisioni di pianificazione includono requisiti di risorse individuali e collettive, vincoli hardware / software / criteri, specifiche di affinità e anti-affinità, località dei dati, interferenza tra carichi di lavoro e così via.

4. Criteri di Scheduling

kube-scheduler seleziona un nodo per il pod in un'operazione in due fasi:

1. Filtraggio
2. Punteggio


La fase di filtraggio trova l'insieme di nodi in cui è possibile programmare il pod. Ad esempio, il filtro PodFitsResources controlla se un nodo candidato dispone di risorse disponibili sufficienti per soddisfare le richieste di risorse specifiche di un pod. Dopo questo passaggio, l'elenco dei nodi contiene tutti i nodi adatti; spesso ce ne saranno più di uno. Se l'elenco è vuoto, quel pod non è (ancora) pianificabile.

Nella fase di assegnazione del punteggio, lo scheduler classifica i nodi rimanenti per scegliere il posizionamento del Pod più adatto. Lo scheduler assegna un punteggio a ciascun nodo che è sopravvissuto al filtraggio, basando questo punteggio sulle regole di punteggio attive.

Infine, kube-scheduler assegna il Pod al Nodo con il punteggio più alto. Se c'è più di un nodo con punteggi uguali, kube-scheduler seleziona uno di questi a caso.

Esistono due modi supportati per configurare il comportamento di filtraggio e punteggio dello scheduler:

1. I criteri di pianificazione consentono di configurare i predicati per il filtro e le priorità per il punteggio.
2. I profili di pianificazione consentono di configurare plug-in che implementano diverse fasi di pianificazione, tra cui: QueueSort, Filter, Score, Bind, Reserve, Permit e altri. Puoi anche configurare kube-scheduler per eseguire diversi profili.

5. Conclusioni


L' architettura di Kubernetes può risultare complessa, ma se si è appresi in questo capitolo come lavorano le varie componenti, si avrà ancora più chiarezza con degli esempi pratici di utilizzo su un particolare Cloud Provider. Inoltre, invito a chiunque sia interessato a Kubernetes di leggere sempre la documentazione ufficiale, questo perché mentre nella rubrica si parla in grandi linee, è possibile tramite la kubedoc, focalizzarsi in maniera approfondita su un particolare concetto.

Link del capitolo precedente: https://www.inforge.net/forum/resources/rubrica-kube-1-introduzione-a-kubernetes.15363/
Link del primo capitolo: https://www.inforge.net/forum/resources/rubrica-kube-1-introduzione-a-kubernetes.15363/
 
  • Mi piace
Reazioni: Cirone