Kubernetes vs Docker: qual è la differenza?
La virtualizzazione hardware offre una serie di vantaggi quali scalabilità, sicurezza, isolamento, ecc. utilizzando hypervisor per condividere l’hardware fisico con VM. Attualmente, le VM non sono l’unica forma di virtualizzazione, poiché anche i contenitori sono diventati piuttosto popolari. Mentre le VM condividono l’hardware fisico delle macchine sottostanti, i contenitori condividono il kernel del sistema operativo sottostante. I contenitori non sono VM leggere, ma pacchetti eseguibili standardizzati utilizzati per fornire applicazioni, comprese quelle sviluppate utilizzando l’architettura software basata su microservizi, e includono tutti i componenti necessari per eseguire le applicazioni.
Il motore Docker è la piattaforma più popolare per l’esecuzione dei contenitori. Kubernetes è un termine che potreste sentire sempre più spesso nel campo della containerizzazione e del cloud computing. Ma cosa è meglio: Docker o Kubernetes? È un argomento di dibattito molto popolare, ma formularlo in questo modo non è tecnicamente corretto. Ad esempio, non si può chiedere: “Cosa è meglio: il caldo o il freddo?”
Che cos’è Docker?
Docker è un’applicazione standalone open source che funziona come motore utilizzato per eseguire applicazioni containerizzate. Viene installato sul sistema operativo (OS), preferibilmente su Linux, ma può essere installato anche su Windows e macOS, che a sua volta funziona su una macchina fisica o una VM.
Un’applicazione in esecuzione in un contenitore è isolata dal resto del sistema e dagli altri contenitori, ma dà l’illusione di essere in esecuzione nella propria istanza del sistema operativo. È possibile eseguire più contenitori Docker contemporaneamente su un unico sistema operativo; è possibile gestire tali contenitori con Docker, che può funzionare senza Kubernetes. Se si dispone di più host per l’esecuzione dei contenitori, la loro gestione manuale può risultare difficile ed è generalmente preferibile selezionare uno strumento di gestione centralizzato o una soluzione di orchestrazione.

Docker Compose è uno strumento di orchestrazione di contenitori di base utilizzato per l’esecuzione di applicazioni Docker multi-container. È possibile configurare un file di configurazione YAML (yml) Docker Compose per definire applicazioni multi-container invece di configurare manualmente file Dockerfile separati per ogni contenitore. Dopo aver configurato il singolo file YAML, è possibile eseguire tutti i contenitori necessari con un unico comando nella console Linux. L’utilizzo di Docker Compose è un modo per effettuare l’orchestrazione dei contenitori Docker, ma esiste una potente alternativa a Docker Compose chiamata Kubernetes.
Che cos’è Kubernetes?
Kubernetes è una soluzione open source per l’orchestrazione dei container utilizzata per gestire software e servizi containerizzati con un elevato grado di automazione.
Kubernetes è un progetto di Google volto ad automatizzare l’implementazione, la scalabilità e la disponibilità delle applicazioni in esecuzione nei contenitori. È possibile aumentare il numero di host che eseguono contenitori fino a 11 o più host. Inoltre, è possibile creare un cluster di contenitori Docker con Kubernetes al fine di garantire un’elevata disponibilità e il bilanciamento del carico.
Gli host utilizzati in un cluster sono chiamati nodi. Il tipo di architettura di Kubernetes è master-slave: il cluster è costituito da nodi master e nodi di lavoro. Il numero minimo di nodi consigliato da Kubernetes è quattro. Sebbene sia possibile creare un cluster con una sola macchina, per eseguire tutti gli esempi e i test necessari sono necessari almeno quattro nodi. Un cluster Kubernetes che gestisce il traffico di produzione dovrebbe avere almeno tre nodi attivi/i. L’utilizzo di due nodi master protegge il cluster dal guasto di un nodo master. Se necessario, è possibile utilizzare più di due nodi master.
- I nodi master vengono utilizzati per la gestione dello stato di un cluster, che include l’accettazione delle richieste dei client, la pianificazione delle operazioni con i contenitori, l’esecuzione dei cicli di controllo, ecc. Una copia del database etcd che memorizza tutti i dati del cluster deve essere eseguita su ciascun nodo master. Il nodo master esegue una serie di tre processi: kube-apiserver, kube-controller-manager e kube-scheduler.
- I nodi di lavoro vengono utilizzati per eseguire le cargas de trabajo delle applicazioni tramite l’esecuzione di contenitori. I due processi Kubernetes vengono eseguiti sul nodo non master: kubelet (per comunicare con i nodi master) e kube-proxy (per riflettere i servizi di rete Kubernetes su ciascun nodo).
- Replication Controller è un componente utilizzato per garantire che le repliche dei Pod il cui numero è specificato siano sempre in esecuzione in un dato momento. In questo modo è possibile assicurarsi che i Pod siano sempre disponibili quando necessario.
Se si utilizza Kubernetes, per la comunicazione tra i servizi vengono utilizzate diverse CLI e API. Esistono anche termini specifici utilizzati per dare un nome agli oggetti e alle risorse dell’API RESTful che sono componenti del cluster costruito con Kubernetes. - Pod è un’unità di pianificazione di base in Kubernetes. Si tratta di un gruppo di risorse in cui possono operare più contenitori. I contenitori appartenenti a un Pod possono essere eseguiti sullo stesso host e utilizzare le stesse risorse e la stessa rete locale. I contenitori nel Pod sono isolati ma possono comunicare tra loro abbastanza facilmente. Pertanto, i Pod sono generalmente utilizzati in Kubernetes, ma se si utilizza un’applicazione Docker autonoma, sono disponibili solo pool di contenitori.
- Il servizio è un insieme di contenitori che lavorano insieme fornendo, ad esempio, il funzionamento di un’applicazione multilivello. Kubernetes supporta la denominazione dinamica e il bilanciamento del carico dei Pod utilizzando astrazioni. Questo approccio garantisce una connessione trasparente tra i servizi in base al nome e consente di monitorarne lo stato attuale.
- Le etichette sono coppie chiave/valore associate ai Pod e ad altri oggetti o servizi, oltre a consentire di creare dei gruppi e assegnare loro dei compiti.
- Spazi dei nomi è un metodo che consente di dividere logicamente il cluster Kubernetes unito in più cluster virtuali. Ogni cluster virtuale può esistere all’interno di un ambiente virtuale limitato da quote senza avere alcun impatto sugli altri cluster virtuali.
Kubernetes può essere utilizzato con Docker, anche se Docker non è l’unica piattaforma contenitore con cui è possibile utilizzare Kubernetes. Kubernetes può anche funzionare in combinazione con contenitori Windows, contenitori Linux, rkt, ecc. K8s è il nome di Kubernetes che a volte si trova nella documentazione tecnica.
Kubernetes vs Docker: Confronto delle reti
Esaminiamo le opzioni di rete per ciascuna soluzione.
Docker offre tre modalità di rete per la comunicazione tra contenitori.
Bridge. Questa modalità è utilizzata di default e crea un bridge virtuale di livello 3. Il nome di rete sul tuo host è docker0 per questa rete. Docker crea automaticamente un bridge di rete di livello 3 e configura le regole di mascheramento per l’interfaccia di rete esterna, utilizzando il principio della traduzione degli indirizzi di rete (NAT), che consente ai contenitori di comunicare tra loro e di connettersi alle reti esterne. È possibile configurare il port forwarding per l’interfaccia di rete della macchina host se si desidera connettersi a un contenitore da altri host e reti esterne. In questo modo, collegandosi alla porta appropriata della macchina host, si viene inoltrati alla porta necessaria del contenitore Docker. Se necessario, è possibile creare più di un’interfaccia di rete per un contenitore Docker.
Host. In questa modalità, un driver di rete host garantisce che un contenitore non sia isolato dall’host Docker. Il contenitore condivide lo stack di rete host e il nome host del contenitore è lo stesso del nome host del sistema operativo host. Se si esegue un contenitore su cui è in ascolto la porta TCP 8080, l’applicazione del contenitore è disponibile sulla porta TCP 8080 dell’indirizzo IP della macchina host. Il driver di rete host è disponibile solo per le macchine Linux.
Nessuno. Non sono configurati indirizzi IP per l’interfaccia di rete di un determinato contenitore, ad eccezione dell’indirizzo 127.0.0.1 per l’interfaccia di loopback. Non è possibile accedere a reti esterne se è impostata la modalità di rete Nessuno .

Rete multi-host per contenitori Docker. Se i contenitori sono in esecuzione su host diversi, possono comunicare tra loro dopo aver configurato il networking overlay. Per creare tali reti è necessario configurare un servizio di archiviazione chiave-valore valido (Consul, Etcdo ZooKeeper) deve essere configurato per la creazione di tali reti.
Kubernetes. Se si utilizzano contenitori Docker autonomi, ogni contenitore può essere considerato come un’unità di base che comunica tramite la rete utilizzando l’interfaccia di rete appropriata. Se si utilizza Kubernetes, i pod sono le unità di base del cluster di contenitori. Ogni pod ha un proprio indirizzo IP ed è costituito da almeno un contenitore. Un pod può essere composto da più contenitori utilizzati per attività correlate. I contenitori dello stesso pod non possono aprire contemporaneamente la stessa porta. Questo tipo di restrizione viene utilizzata perché un pod composto da più contenitori ha comunque un unico indirizzo IP.
Inoltre, Kubernetes crea uno speciale contenitore di pausa per ogni pod. Questo contenitore speciale ha lo scopo di fornire un’interfaccia di rete (per la comunicazione interna ed esterna) per altri contenitori ed è solitamente in pausa (in modalità sleep). Questi contenitori in pausa si attivano quando Kubernetes invia un segnale “SIGTERM”.

Flannel è tipicamente utilizzato come struttura di rete per connettere i contenitori in Kubernetes utilizzando i principi della sovrapposizione di rete. Il networking overlay consente di eseguire i contenitori comunicando tramite la rete logica diversi host fisici del cluster (denominati nodi). L’archivio chiave/valore open source etcd viene utilizzato per salvare le mappature tra gli indirizzi IP reali assegnati ai contenitori dagli host su cui sono in esecuzione i contenitori e gli indirizzi IP nella rete overlay.

Il networking Kubernetes può essere integrato con VMware NSX-T utilizzando il plugin NSX Container. Questa integrazione consente di utilizzare una topologia di rete multi-tenant che non è disponibile “pronta all’uso” in Kubernetes.
Il modello di rete Kubernetes offre le seguenti funzioni:
- Tutti i contenitori possono comunicare con qualsiasi altro contenitore all’interno di un cluster senza NAT.
- Tutti i nodi del cluster possono comunicare con tutti i contenitori all’interno di un cluster senza NAT. Viceversa, tutti i contenitori possono comunicare con tutti i nodi del cluster.
- I contenitori vedono i propri indirizzi IP e tali indirizzi IP sono visibili agli altri componenti di Kubernetes.
Ingress è un oggetto API di Kubernetes utilizzato per la gestione dell’accesso ai servizi nel cluster dall’esterno (principalmente HTTP e HTTPS). È possibile configurare Ingress per eseguire l’accesso esterno ai servizi containerizzati, per il bilanciamento del carico, la terminazione SSL e l’hosting virtuale basato sul nome. Per far funzionare le regole di ingresso, è necessario distribuire un controller di ingresso sul nodo master.

Casi d’uso
L’utilizzo di Docker come software autonomo è utile per lo sviluppo di applicazioni, poiché gli sviluppatori possono eseguire le loro applicazioni in ambienti isolati. Inoltre, i tester possono anche utilizzare Docker per eseguire applicazioni in ambienti sandbox. Se desideri utilizzare Docker per eseguire un numero elevato di contenitori nell’ambiente di produzione, potresti incontrare alcune complicazioni lungo il percorso. Ad esempio, alcuni contenitori possono facilmente sovraccaricarsi o andare in errore. È possibile riavviare manualmente il contenitore sulla macchina appropriata, ma la gestione manuale può richiedere molto tempo ed energia.
Kubernetes consente di risolvere questi problemi fornendo funzioni chiave quali alta disponibilità, bilanciamento del carico, strumenti di orchestrazione dei contenitori, ecc. Di conseguenza, Kubernetes è particolarmente adatto per ambienti di produzione altamente caricati con un numero elevato di contenitori Docker. L’implementazione di Kubernetes è più difficile rispetto all’installazione di un’applicazione Docker autonoma, motivo per cui Kubernetes potrebbe non essere sempre utilizzato per lo sviluppo e il collaudo.
Kubernetes vs Docker Swarm
Docker Swarm è uno strumento di clustering nativo per Docker che può trasformare un pool di host Docker in un unico host virtuale. Docker Swarm è completamente integrato con Docker Engine e consente di utilizzare API e processi di rete standard; è progettato per effettuare l’implementazione, la gestione e la scalabilità dei contenitori Docker.
Swarm è un cluster di host Docker chiamati nodi. Prima di confrontare l’implementazione del cluster con Kubernetes e Docker Swarm, consideriamo i seguenti componenti principali di un cluster quando si utilizza Docker Swarm:
I nodi manager vengono utilizzati per eseguire l’orchestrazione del controllo, la gestione del cluster e la distribuzione delle attività.
I nodi worker sono utilizzati per l’esecuzione dei container i cui task sono assegnati dai nodi manager. Ogni nodo può essere configurato come nodo manager, nodo worker o entrambi, in modo da svolgere sia le funzioni di nodo manager che quelle di nodo worker. Si noti che i nodi worker eseguono i servizi swarm.
Servizi. Un servizio di Docker Swarm definisce lo stato ottimale richiesto per ogni servizio containerizzato. Un servizio controlla parametri quali il numero di repliche, le risorse di rete disponibili, le porte che devono essere rese accessibili dalle reti esterne, ecc. La configurazione del servizio, come la configurazione di rete, può essere modificata e applicata a un contenitore senza richiedere il riavvio manuale del servizio con il contenitore.
Attività. Un’attività è uno slot in cui è in esecuzione un singolo contenitore. Le attività sono le parti di un servizio Swarm.

Pertanto, Docker Swarm e Kubernetes sono due piattaforme diverse utilizzate per scopi simili. È ora il momento di confrontarle in una serie di categorie appropriate.
Implementazione del cluster
Docker Swarm. Un’API Docker standard consente di distribuire un cluster con Swarm utilizzando una CLI (interfaccia a riga di comando) Docker standard che semplifica l’implementazione, soprattutto quando viene utilizzata per la prima volta. La facilità di implementazione di Swarm rispetto a Kubernetes è ottenuta anche grazie alla capacità di un singolo master Docker di decidere come distribuire i servizi. In Docker Swarm non vengono utilizzati pod.
Kubernetes richiede l’uso di comandi specifici che sono diversi dai comandi Docker standard. In Kubernetes vengono utilizzate API specifiche, il che significa che anche se si conoscono i comandi per la gestione di Docker, potrebbe essere necessario imparare a utilizzare un set aggiuntivo di strumenti per l’implementazione di Kubernetes. I nodi devono essere definiti manualmente nel cluster Kubernetes: è necessario selezionare il nodo master, definire il controller, lo scheduler, ecc.
Scalabilità
Docker Swarm. Grazie alla semplice API fornita da Docker, l’implementazione dei contenitori e l’aggiornamento dei servizi in cluster grandi e piccoli può essere eseguita più rapidamente. L’interfaccia a riga di comando (CLI) è piuttosto semplice e intuitiva. Di conseguenza, Swarm può essere considerato una soluzione più scalabile rispetto a Kubernetes.
Kubernetes fornisce API relativamente unificate e una serie di funzioni che spesso rallentano l’implementazione. Esistono tre tipi di componenti che devono essere configurati: Pod, Deploy e Service. Quando si tratta di auto-scalabilità, Kubernetes è preferibile grazie alla sua capacità di analizzare i carichi del server, oltre a fornire la possibilità di scalare automaticamente in base ai requisiti specificati. Kubernetes è la scelta ottimale per reti distribuite di grandi dimensioni e sistemi complessi.
Alta disponibilità
Le due opzioni di soluzione possiedono entrambe meccanismi simili di replica dei servizi e ridondanza, e in entrambi i casi il sistema è autoregolato e non richiede una riconfigurazione manuale dopo che un nodo guasto è tornato nel cluster.
Docker Swarm. I nodi manager gestiscono le risorse dei nodi worker e dell’intero cluster. I nodi del cluster Swarm partecipano alla replica dei servizi.
Kubernetes. I nodi non funzionanti vengono rilevati dai servizi di bilanciamento del carico di Kubernetes e vengono eliminati dal cluster. Tutti i pod sono distribuiti tra i nodi, garantendo così un’elevata disponibilità nel caso in cui un nodo su cui è in esecuzione un’applicazione containerizzata dovesse guastarsi.
Bilanciamento del carico
Docker Swarm. Il bilanciamento del carico è una funzione integrata e può essere eseguita automaticamente utilizzando la rete interna Swarm. Tutte le richieste al cluster vengono distribuite e reindirizzate ai nodi del cluster; qualsiasi nodo può connettersi a qualsiasi contenitore. Docker Swarm utilizza un elemento DNS per distribuire le richieste in entrata ai nomi dei servizi.
Kubernetes. I criteri definiti nei Pod vengono utilizzati per il bilanciamento del carico in Kubernetes. In questo caso, i Pod dei contenitori devono essere definiti come servizi. È necessario configurare manualmente le impostazioni di bilanciamento del carico, mentre Ingress può essere utilizzato per il bilanciamento del carico.
Creazione ed esecuzione di contenitori
Docker Swarm. La stragrande maggioranza dei comandi disponibili per la CLI di Docker può essere utilizzata quando si utilizza Docker Swarm, grazie all’API standardizzata di Docker Swarm. Docker Compose definisce il lavoro con i volumi e le reti utilizzate, oltre a definire quali contenitori devono essere raggruppati in gruppi. Il numero esatto di repliche può essere impostato con Docker Compose per Docker Swarm.
Kubernetes. Kubernetes ha una propria API, un proprio client e richiede file YAML per essere configurato. Questa è una delle differenze principali, poiché in questo caso non è possibile utilizzare Docker Compose e Docker CLI per effettuare l’implementazione dei contenitori. In Kubernetes, il sistema per definire i servizi segue un principio di funzionamento simile a quello di Docker Compose, ma è più complesso. La funzionalità di Docker Compose viene eseguita utilizzando Pod, implementazioni e Servizi in Kubernetes, all’interno dei quali ogni livello viene utilizzato per il proprio scopo specifico. I Pod sono responsabili dell’interazione dei contenitori, mentre le implementazioni sono responsabili dell’alta disponibilità e della rete per un singolo nodo nel cluster (molto simile a Docker Compose per un’applicazione Docker standalone senza Swarm), e i servizi Kubernetes sono responsabili della configurazione del funzionamento dei servizi all’interno del cluster, della tolleranza ai guasti, ecc.
Reti
Docker Swarm. Esiste una rete interna predefinita per la comunicazione dei contenitori all’interno di un cluster, alla quale è possibile aggiungere altre reti se necessario. Le reti sono protette con certificati TLS generati. La generazione manuale dei certificati è supportata per la crittografia del traffico dati dei contenitori.
Kubernetes. Il modello di rete di Kubernetes è piuttosto diverso ed è implementato utilizzando plugin, uno dei quali è Flannel, l’opzione più popolare. I pod interagiscono tra loro e questa interazione può essere limitata da criteri. Esiste una rete interna gestita dal servizio etcd. È disponibile anche la crittografia TLS, ma deve essere configurata manualmente. Il modello di rete Kubernetes presuppone la configurazione di due CIDR, Classless Inter-Domain Routing, noto anche come supernetting.
Monitoraggio
Docker Swarm. Non ci sono strumenti integrati per il monitoraggio e la registrazione, ma è possibile configurare manualmente strumenti di monitoraggio di terze parti. A questo scopo è possibile utilizzare ELK o Reimann.
Kubernetes. Kubernetes fornisce strumenti integrati per la registrazione e il monitoraggio. Elasticsearch e Kibana (ELK) possono essere utilizzati per monitorare lo stato dell’intero cluster, mentre Heapster, Grafana e Influx hanno supporto per il monitoraggio dei servizi di contenitore.
Interfaccia grafica utente (GUI)
Docker Swarm. La GUI può essere abilitata con strumenti di terze parti come Portainer.io, che fornisce un’interfaccia web intuitiva. In alternativa, è possibile utilizzare l’Edizione Enterprise di Docker, che fornisce un’interfaccia grafica per la gestione dei cluster.
Kubernetes. La GUI fornita da Kubernetes è una dashboard affidabile accessibile tramite un’interfaccia web che consente di controllare facilmente il proprio cluster. La GUI può essere uno strumento molto utile per gli utenti con esperienza minima nella gestione di Kubernetes con la CLI.
Conclusione
Docker Swarm è una soluzione Docker nativa che utilizza principalmente l’API e la CLI di Docker. Kubernetes, al contrario, è un progetto di Google utilizzato per l’implementazione di un cluster su cui vengono eseguiti i contenitori.
Sia Docker Swarm che Kubernetes offrono funzionalità di alta disponibilità, bilanciamento del carico, overlay networking e scalabilità. Docker Swarm è il più facile da implementare dei due, poiché la maggior parte delle sue funzioni è automatizzata e consuma poche risorse hardware. Tuttavia, la funzionalità è limitata dall’API Docker e mancano strumenti di monitoraggio nativi.
Kubernetes, invece, è una soluzione modulare con un alto livello di flessibilità che è stata supportata dalla maggior parte delle grandi aziende per diversi anni. Per Kubernetes sono disponibili strumenti integrati per il monitoraggio dei servizi e dell’intero cluster, anche se l’implementazione e la configurazione sono più difficili, rendendo questa risorsa una soluzione più impegnativa. Kubernetes non è compatibile con Docker CLI e Docker Compose. L’uso di Kubernetes è preferibile in ambienti di grandi dimensioni in cui sono in esecuzione applicazioni multi-container altamente caricate.