Kubernetes o K8s è una piattaforma di orchestrazione di container open source, sviluppata originariamente da Google. È stata progettata per automatizzare il funzionamento dei container Linux, sia che vengano eseguiti su sistemi locali, centri dati o nel cloud.
Dal suo rilascio iniziale nel 2014, Kubernetes ha ottenuto una grande diffusione nelle aziende. Il suo grande punto di forza e la ragione della sua popolarità è la capacità di gestire un gran numero di container. In Kubernetes, l'orchestrazione comporta il monitoraggio, il roll out, la correzione, la copia e la migrazione automatica dei container.
Nonostante la sua popolarità, anche gli esperti non sono in grado di comprendere completamente Kubernetes. Se da un lato ha una chiara gerarchia, dall'altro è composto da molti oggetti e singole funzioni che interagiscono tra loro. Questo lo rende una tecnologia complessa e a più livelli. In questo articolo cercheremo di fornire una panoramica semplificata dell'architettura e dei principali oggetti di K8s. L'utilizzo di Kubernetes inizia sempre con la creazione di un cluster.
Che cos'è un cluster Kubernetes?
Utilizzare Kubernetes significa generalmente gestire uno o più cluster. In genere, un cluster è costituito da un piano di controllo, che controlla tutti gli oggetti del cluster, e da uno o più nodi worker che eseguono le applicazioni containerizzate. Per garantire la ridondanza dell'ambiente Kubernetes, la configurazione predefinita di un cluster consiste spesso in tre nodi del piano di controllo e tre nodi worker.
Per l'orchestrazione dei nodi worker, il piano di controllo in un cluster comprende i seguenti componenti:
- Server API: Il server API funge da front-end del piano di controllo di Kubernetes. Può essere utilizzato per leggere lo stato desiderato del cluster e determinare quali applicazioni K8 devono essere eseguite e come.
- Scheduler: Lo scheduler posiziona i container in base ai requisiti di risorse definiti e assegna i pod liberi a un nodo.
- Controller manager: Il controller manager confronta lo stato effettivo del cluster con le specifiche fornite.
- Etcd: Etcd è uno store coerente e altamente disponibile per la memorizzazione di tutti i dati critici del cluster, come la configurazione, lo stato e i metadati di Kubernetes.
I nodi worker eseguono i due componenti kubelet e kube-proxy, responsabili del controllo dei container e della comunicazione tra i nodi.
Un cluster è quindi composto da diversi nodi. Ma cosa fanno esattamente i nodi?
Cos'è un nodo Kubernetes?
I nodi sono gli elementi centrali di un cluster. Si distingue tra nodi del piano di controllo e nodi worker. Mentre il nodo master è responsabile dell'amministrazione del cluster, i nodi worker forniscono le risorse e i servizi necessari per il funzionamento dei carichi di lavoro.
Suggerimento pratico: Il ruolo di un nodo può essere riconosciuto dalle etichette "control-plane" o "master" utilizzando kubectl get nodes
.
Ospitando i pod, i nodi worker consentono l'esecuzione dei carichi di lavoro effettivi. In questo modo, i nodi agiscono come un pool di risorse CPU e RAM su cui Kubernetes esegue successivamente i carichi di lavoro containerizzati.
Sebbene di solito si debbano ancora gestire le macchine fisiche o virtuali, Kubernetes ti toglie la decisione su quale nodo finirà per essere eseguita l'applicazione e se ci sono risorse sufficienti su quel nodo.
In pratica, se si distribuisce un'applicazione in un cluster, Kubernetes distribuisce il lavoro tra i nodi. In questo modo, può spostare senza problemi i carichi di lavoro tra i nodi del cluster.
È possibile lavorare con i cluster per separare le applicazioni e le risorse di diversi team in Kubernetes. Nelle infrastrutture IT tradizionali, spesso questo viene implementato utilizzando macchine virtuali, reti o ambienti separati. In Kubernetes, tuttavia, esiste uno strumento molto collaudato ed efficiente per dividere i cluster in aree isolate: i namespace.
Cosa sono i namespace in Kubernetes?
I namespace consentono di dividere i cluster Kubernetes in aree logiche isolate. Ogni cluster supporta un numero qualsiasi di namespace, ma i namespace stessi non possono essere annidati.
Possono essere utilizzati, ad esempio, per organizzare le risorse dell'infrastruttura Kubernetes. Pertanto, uno spazio dei nomi può essere considerato come una sorta di sotto-cluster virtuale.
Quasi tutte le risorse di Kubernetes si trovano in uno spazio dei nomi predefinito o in uno spazio dei nomi creato manualmente. Tuttavia, i nodi e i volumi persistenti fanno eccezione. Entrambi sono cosiddetti risorse di basso livello ed esistono al di fuori degli spazi dei nomi, quindi sono sempre visibili a tutti gli spazi dei nomi del cluster.
Suggerimento pratico: tutti gli oggetti non legati a uno spazio dei nomi possono essere trovati da kubectl api-resources --namespaced=false
Perché è consigliabile usare i namespace?
Come già accennato, i namespace consentono a diversi team di lavorare insieme in un proprio cluster virtuale, ad esempio nell'ambito di progetti. Ciò significa che l'ambiente dei singoli team non viene influenzato. Allo stesso tempo, i namespace possono essere utilizzati per condividere le risorse di un cluster tra diversi team e utenti tramite quote di risorse.
I namespace possono anche essere utilizzati per limitare l'accesso degli utenti e dei carichi di lavoro a namespace specifici. Questi spazi rappresentano un modo semplice per separare lo sviluppo, il collaudo e le operazioni delle applicazioni, mappando così l'intero ciclo di vita sullo stesso cluster.
La comunicazione avviene tra i namespace?
I namespace sono separati gli uni dagli altri, ma possono comunicare facilmente tra loro. Il servizio DNS di Kubernetes è in grado di individuare qualsiasi servizio per nome, utilizzando una forma estesa di indirizzamento DNS (svc.cluster.local). L'aggiunta del nome del namespace al nome del servizio consente di accedere ai servizi in qualsiasi namespace del cluster.
Suggerimento pratico: Una query su service.namespace
è identica a service.namespace.svc.cluster.local
Facoltativamente, le policy di rete possono essere utilizzate anche per l'accesso tra namespace, ad esempio per consentire o negare tutto il traffico proveniente da altri namespace.
Finora si è appreso cosa sono i cluster e i nodi e come si possono usare i namespace per dividere i cluster in aree logiche. Abbiamo anche imparato che i nodi worker ospitano i pod senza specificarli ulteriormente. Ora recupereremo sull'argomento nelle prossime sezioni.
Che cos'è un pod Kubernetes?
Un pod è un ambiente che viene distribuito su un nodo ed esegue un container. Anche se è possibile eseguire più container in un pod, di solito è un'eccezione.
I pod possono essere considerati come computer autonomi che eseguono una singola attività. Se si modifica la configurazione del pod, Kubernetes implementa automaticamente le modifiche creando o rimuovendo nuovi pod.
Se un nodo si guasta, Kubernetes distribuisce automaticamente i pod interessati su un altro nodo. Se Kubernetes rileva il guasto di un pod tramite l'health check, lo riavvia. I pod sono raramente specificati in Kubernetes stesso. Di solito vengono creati tramite meccanismi di livello superiore, come deployments, DaemonSets e jobs. Se i pod dipendono da uno stato del sistema, la creazione avviene spesso tramite StatefulSet.
Suggerimento pratico: L'attributo "Controlled By" (controllato da) sull'output via kubectl describe pod [podname]
può essere usato per identificare come è stato creato un pod. Se il campo è vuoto, il pod è stato avviato senza meccanismi di livello superiore.
Cosa sono le distribuzioni in Kubernetes?
I deployment sono una delle prime meccaniche di creazione del carico di lavoro in Kubernetes. Nella descrizione di un deployment, è possibile specificare quali immagini l'applicazione deve utilizzare, quanti pod sono necessari e come Kubernetes deve aggiornarli. In questo modo si semplifica il processo di aggiornamento e i passaggi necessari per farlo, consentendo di automatizzare e ripetere il processo.
In particolare, i deployment consentono di eseguire il provisioning dei pod e di aggiornarli, di tornare alle versioni precedenti del deployment e di scalare, mettere in pausa o riprendere i deployment. Una volta creato un deployment, il piano di controllo di Kubernetes si occupa della pianificazione delle istanze applicative.
I deployment sono adatti soprattutto alle applicazioni stateless. Ciò è dovuto a ragioni storiche, in quanto l'obiettivo originario di Kubernetes era proprio quello di realizzare applicazioni stateless. Nel corso del tempo, tuttavia, è diventato chiaro che Kubernetes deve supportare anche le applicazioni statiche. Di conseguenza, sono stati creati i cosiddetti StatefulSet.
Cosa sono gli StatefulSet?
Kubernetes utilizza StatefulSets per controllare l'esecuzione di applicazioni stateful che richiedono identità e nomi di host persistenti. In pratica, questo significa che gestisce il provisioning e lo scaling dei pod contenuti nell'insieme, garantendo al contempo l'ordine e l'unicità di tali pod.
Ad esempio, con StatefulSets per un database MySQL, scalato a tre repliche in un cluster Kubernetes, è possibile specificare che un'applicazione front-end acceda a tutti e tre i pod per i processi di lettura. Per i processi di scrittura, invece, si rivolge solo al primo pod, sincronizzando successivamente i dati con gli altri due pod.
Gli StatefulSet assegnano un'identità immutabile a ogni pod, a partire da 0 (0 -> n). Un nuovo pod viene creato clonando i dati del pod precedente. L'eliminazione o la terminazione avvengono in ordine inverso (n -> 0). Quindi, se si riduce il numero di repliche da quattro a tre, Kubernetes termina o elimina il pod con il numero 3 per primo.
Gli StatefulSet sono particolarmente adatti alle applicazioni che richiedono almeno uno dei seguenti elementi: identificatori di rete stabili e univoci, storage stabile e persistente, provisioning ordinato e regolamentato e aggiornamenti continui ordinati e automatici.
Uno StatefulSet creato assicura che il numero desiderato di pod sia in esecuzione e disponibile. Sostituisce automaticamente i pod falliti o rimossi dal nodo in base alle specifiche configurate nel set.
L'eliminazione di uno StatefulSet non comporta l'eliminazione automatica dei dati sui volumi associati, per motivi di sicurezza dei dati.
Oltre alle distribuzioni e agli StatefulSet, Kubernetes fornisce un altro meccanismo per l'avvio dei pod sotto forma di DaemonSet.
Cosa sono i DaemonSet?
Con i DaemonSet, si lancia un pod specifico su ogni nodo worker. Questo significa che è adatto alle applicazioni che si desidera eseguire su ogni singolo nodo worker. Ad esempio, potrebbe essere un demone di registrazione che raccoglie i log da tutti i container e li invia a un server di log centrale.
Nella fase successiva vedremo come i vari oggetti e funzioni di Kubernetes comunicano tra loro. Si distingue tra comunicazione interna ed esterna. Per la comunicazione degli oggetti all'interno di un cluster, Kubernetes utilizza i cosiddetti servizi.
Cosa sono i servizi in Kubernetes?
I servizi in Kubernetes sono un'astrazione logica per un gruppo di pod in un cluster che svolgono la stessa funzione. Un servizio assegna un nome e un indirizzo IP univoco (clusterIP) a questo gruppo di pod in modo che sia raggiungibile dagli altri pod. Inoltre, imposta le politiche di accesso e gestisce il bilanciamento automatico del carico di tutte le richieste in arrivo.
Poiché un servizio gestisce la scoperta e l'instradamento tra pod dipendenti, come i componenti front-end e back-end, se un pod muore e viene replicato, l'applicazione non ne risente.
Per collegare i pod in un gruppo, i servizi utilizzano etichette e selettori.
Oltre alla comunicazione interna, tuttavia, le applicazioni devono essere in grado di comunicare con l'esterno. Questo avviene tramite Ingress.
Che cos'è Kubernetes Ingress?
Kubernetes Ingress è un'interfaccia che consente agli utenti esterni di accedere ai servizi di un cluster Kubernetes tramite HTTP/HTTPS. Ingress consente anche di creare regole per l'instradamento del traffico senza dover creare bilanciatori di carico o esporre tutti i servizi su un nodo.
Ora hai imparato a conoscere i principali oggetti di Kubernetes. Ciò che manca ora è la conoscenza di come avviare un'applicazione su Kubernetes.
Come si fa il roll-out delle applicazioni in Kubernetes?
Per lanciare un'applicazione in Kubernetes, è necessario creare ed eseguire un manifest. Un manifest è un file JSON o YAML in cui si specificano gli oggetti (distribuzioni, servizi, pod, ecc.) che si desidera creare, il modo in cui devono essere eseguiti nel cluster, l'immagine del container da utilizzare o il numero di repliche che Kubernetes deve creare. Il manifest viene poi distribuito al cluster tramite la riga di comando (kubectl) o tramite un CI.
Per la sua facilità d'uso, la maggior parte dei neofiti di Kubernetes scrive i propri manifest utilizzando YAML. Tuttavia, un manifesto ha lo svantaggio di essere molto statico e poco flessibile. Per questo motivo, a un certo punto gli utenti di Kubernetes passano solitamente ai grafici Helm. Helm è un gestore di pacchetti di Kubernetes e facilita in particolare la distribuzione di applicazioni altamente ripetibili. Un diagramma Helm è un pacchetto di uno o più manifesti rielaborati in modelli con variabili. Le variabili possono essere comodamente specificate tramite un altro YAML che può essere fornito all'Helm. Sfortunatamente, questo di solito comporta che i template stessi diventino quasi illeggibili.
Un altro metodo per il roll-out delle applicazioni è il cosiddetto operatore Kubernetes. Si tratta di un controller che automatizza ulteriormente questo processo. In pratica, ciò significa codificare le conoscenze sul ciclo di vita di un'applicazione. Di conseguenza, gli operatori consentono di gestire e scalare applicazioni stateless, come applicazioni web o servizi API, senza doverne conoscere il funzionamento. In questo modo, un operatore riduce le attività manuali necessarie per gestire i carichi di lavoro Kubernetes. Tuttavia, la programmazione di un operatore richiede le competenze adeguate.
DOMANDE FREQUENTI
Per distribuire le applicazioni, di solito si usano i deployments o gli StatefulSets. La differenza tra deployments e StatefulSets può essere spiegata storicamente: Agli inizi, K8s era limitato alle applicazioni stateless. Col tempo, tuttavia, si è capito che le applicazioni statiche non potevano essere mappate con le distribuzioni. Di conseguenza, sono stati introdotti gli StatefulSet.
Le applicazioni stateful sono applicazioni che memorizzano e tengono traccia dei dati. Ad esempio, i database come MySQL, Oracle e PostgeSQL sono esempi di applicazioni di questo tipo. Le applicazioni stateless, invece, non memorizzano i dati, ma li elaborano di volta in volta con ogni richiesta, ad esempio passandoli a un'applicazione stateful.
Le distribuzioni possono essere create e gestite utilizzando YAML o JSON con kubectl. L'interfaccia a riga di comando comunica con l'API di Kubernetes per interagire con il cluster. Una volta creato un pod del deployment, un controller del deployment Kubernetes monitora continuamente le istanze. Se un nodo che esegue un'istanza si guasta, il controller sostituisce l'istanza con una nuova su un altro nodo del cluster. In questo modo, Kubernetes fornisce un processo di auto-riparazione progettato per evitare guasti al sistema.
Come suggerisce il nome, l'Horizontal Pod Autoscaler (HPA) scala automaticamente il numero di pod, ad esempio, da una distribuzione. Per l'autoscaling utilizza l'utilizzo medio della CPU del target assegnato o le metriche fornite dall'applicazione. In questo modo, l'HPA garantisce che vengano lanciati pod aggiuntivi durante i picchi di prestazioni e che l'applicazione continui a funzionare. L'HPA rende Kubernetes particolarmente efficace durante i picchi di carico di lavoro e fornisce una protezione contro i guasti del sistema.
Importante: è necessario specificare il valore al quale l'HPA deve avviare nuovi pod o eliminare quelli esistenti quando si crea l'installazione client.
Esistono diversi modi per monitorare Kubernetes. Lo stato delle applicazioni può essere facilmente controllato utilizzando gli endpoint di salute. Se si verifica un problema, Kubernetes offre, ad esempio, con kubectl, uno strumento di bordo per interrogare i log dei container per la risoluzione dei problemi tramite l'API.
Chi ha bisogno di approfondimenti sul consumo di risorse deve implementare strumenti aggiuntivi. Ad esempio, con Kubernetes Dashboard esiste un modo semplice per visualizzare le metriche. Chi ha bisogno di un quadro olistico di tutti gli aspetti dell'ambiente Kubernetes, nonché di un rilevamento automatico di uno stato problematico e di un avviso intelligente, è consigliabile che utilizzi un software di monitoraggio Kubernetes come Checkmk.