Dopo aver trattato le nozioni di base dei container e la containerizzazione delle applicazioni, vedremo dove si applica Kubernetes. Kubernetes è uno strumento di orchestrazione open source per i container che consente di gestire e scalare meglio le applicazioni. Kubernetes offre un'API che permette a chi è autorizzato di controllare il suo funzionamento mediante numerose utilità. Vedremo tra poco una di queste utilità: il comando "kubectl". Kubernetes consente di eseguire il deployment di container in un "cluster" di nodi. Che cos'è un cluster? È un insieme di componenti master che controllano l'intero sistema e una serie di nodi che eseguono i container. In Kubernetes, un "nodo" è un'istanza di elaborazione. In Google Cloud i nodi sono VM in esecuzione in Compute Engine. Per usare Kubernetes, puoi descrivere una serie di applicazioni e il modo in cui devono interagire tra loro. Kubernetes determinerà come farlo. Kubernetes semplifica l'esecuzione di applicazioni containerizzate, come quella creata nell'ultima lezione. Ma come si ottiene un cluster Kubernetes? È possibile crearlo da soli, sul proprio hardware, o in un ambiente che dispone di VM. Ma ciò richiede molto lavoro e, se lo crei tu, devi anche gestirlo tu. Ancora più lavoro. Poiché non sempre lo sforzo vale l'impiego del proprio tempo, Google Cloud offre Kubernetes Engine, Kubernetes come servizio gestito nel cloud. Con Kubernetes Engine puoi creare un cluster Kubernetes utilizzando la console GCP, o il comando "gcloud" fornito da Cloud SDK. I cluster GKE possono essere personalizzati e supportano diversi tipi di macchine, numeri di nodi e impostazioni di rete. Ecco un esempio di comando per la creazione di un cluster Kubernetes mediante GKE: "gcloud container clusters create k1". Quando questo comando viene completato, il risultato è un cluster "k1" completo, configurato e pronto all'uso. Puoi verificarne lo stato nella console GCP. Quando Kubernetes esegue il deployment di uno o più container correlati, ciò avviene in un'astrazione chiamata "pod". Un "pod" è l'unità più piccola di cui eseguire il deployment in Kubernetes. Pensa al pod come se fosse un processo in esecuzione nel cluster. Può essere un'intera applicazione o solo un componente. In genere si ha un solo container per pod, ma se hai più container con una hard dependency, puoi riunirli in un singolo pod. Condivideranno automaticamente le reti e lo spazio di archiviazione su disco. Ogni pod in Kubernetes riceve un indirizzo IP univoco e una serie di porte per i container. Poiché i container in un pod possono comunicare tra loro mediante l'interfaccia di rete host locale, non devono sapere su quali nodi sono implementati. Un modo di eseguire un container in un pod in Kubernetes è utilizzare il comando "kubectl run". Più avanti scopriremo un modo migliore, ma così puoi cominciare subito. L'esecuzione del comando "kubectl run" dà inizio a un deployment con un container in esecuzione in un pod. In questo esempio, il container in esecuzione nel pod è un'immagine del popolare server web open source Nginx. Il comando kubectl è abbastanza intelligente da recuperare un'immagine di Nginx, della versione che richiediamo, da un Container Registry. Che cos'è un "deployment"? Un deployment rappresenta un gruppo di repliche dello stesso pod. Mantiene attivi i pod anche in caso di problemi del nodo in cui vengono eseguiti. Puoi usare un deployment per contenere l'intera applicazione o solo un componente. In questo caso, il server web Nginx. Per visualizzare i pod Nginx in esecuzione, esegui il comando "kubectl get pods". Per impostazione predefinita, i pod in un deployment sono accessibili solo nel cluster. Vuoi consentire a chi si trova in Internet di accedere ai contenuti del tuo server web Nginx? Per rendere disponibili al pubblico i pod del tuo deployment, puoi connettervi un bilanciatore del carico eseguendo il comando "kubectl expose". Kubernetes crea quindi un servizio con un indirizzo IP fisso per i tuoi pod. Un servizio è il modo in cui Kubernetes rappresenta il bilanciamento del carico. Nello specifico, hai richiesto a Kubernetes di collegare un bilanciatore del carico esterno con un indirizzo IP pubblico al tuo servizio, per consentire l'accesso pubblico al cluster. In GKE questo tipo di bilanciatore del carico è un bilanciatore del carico di rete. È uno dei servizi gestiti di bilanciamento del carico che Compute Engine offre alle VM. GKE ne semplifica l'uso con i container. Un client che usa questo indirizzo IP viene indirizzato a un pod associato al servizio. In questo caso, esiste solo un pod: il tuo pod Nginx. Che cos'è un servizio? Un servizio raggruppa un insieme di pod e offre loro un endpoint stabile. Nel nostro caso, un indirizzo IP pubblico gestito da un bilanciatore del carico di rete anche se sono possibili altre scelte. Ma perché è necessario un servizio? Perché non usare gli indirizzi IP dei pod? Ad esempio, se la tua applicazione è composta da un frontend e da un backend, il frontend può accedere al backend usando gli indirizzi IP interni dei pod, senza dover ricorrere a un servizio? Sì, ma avresti un problema di gestione. Man mano che i deployment li creano e li distruggono, i pod ricevono un proprio indirizzo IP, che però non resta stabile nel tempo. I servizi offrono l'endpoint stabile necessario. Imparando a conoscere Kubernetes, scoprirai altri tipi di servizi adatti ai backend interni dell'applicazione. Il comando "kubectl get services" mostra l'indirizzo IP pubblico del tuo servizio. I client possono usare questo indirizzo per raggiungere il container Nginx in remoto. E se hai bisogno di maggiore potenza? Per scalare un deployment, esegui il comando "kubectl scale". Il nostro deployment ha tre server web Nginx, ma sono tutti associati al servizio e disponibili tramite un indirizzo IP fisso. Puoi usare anche la funzione di scalabilità automatica, che ha molti parametri utili. Ad esempio, ecco come scalare automaticamente un deployment in base all'uso della CPU. Nel comando visualizzato, viene specificato un numero minimo di 10 pod, un numero massimo di 15 pod e i criteri di scalabilità. In questo caso, Kubertnetes fa lo scale up del numero di pod quando l'uso della CPU raggiunge l'80% della capacità. Finora ho mostrato come eseguire comandi imperativi come "expose" and "scale". Questo è utile per scoprire e testare Kubernetes progressivamente. Ma Kubernetes dimostra tutta la sua potenza quando si lavora in modo dichiarativo. Invece di lanciare comandi, si fornisce un file di configurazione che indica a Kubernetes il tipo di stato richiesto e Kubernetes pensa a come ottenerlo. I file di configurazione diventano i tuoi strumenti di gestione. Per fare cambiamenti, modifica il file e mostra a Kubernetes la versione modificata. Il comando nella diapositiva è un punto di partenza per uno di questi file, in base al lavoro già svolto. L'output del comando avrebbe questo aspetto. Questi file possono essere scoraggianti quando li vedi per la prima volta perché sono lunghi e contengono una sintassi che ancora non capisci. Ma conoscendoli meglio, scoprirai che sono facili da usare e puoi salvarli in un sistema di controllo della versione per tenere traccia delle modifiche apportate all'infrastruttura. In questo caso, il file Deployment Configuration dichiara che vuoi tre repliche del tuo pod Nginx. Definisce un campo selettore, così che il deployment sappia come raggruppare pod specifici come repliche. Funziona perché tutti questi pod specifici condividono un'etichetta. La loro app è taggata come "nginx". Per dimostrare la flessibilità di questo metodo dichiarativo, ed eseguire cinque repliche invece di tre, devi modificare il file di configurazione del deployment, sostituendo tre con cinque, quindi eseguire il comando "kubectl apply" e usare il file di configurazione aggiornato. Usa il comando "kubectl get replica sets" per visualizzare le repliche e il loro stato aggiornato. Quindi usa il comando "kubectl get pods" per guardare i pod che si collegano online. In questo caso, tutti e cinque sono in esecuzione. Infine, controlliamo il deployment per verificare il numero di repliche in esecuzione con "kubectl get deployments". In questo caso, tutti e cinque i pod sono disponibili e i client possono ancora raggiungere il tuo endpoint, come prima. Il comando "kubectl get services" conferma che l'IP esterno del servizio non è interessato. Ora hai cinque copie del tuo pod Nginx in esecuzione in GKE e un solo servizio che esegue il proxy del traffico su tutti e cinque i pod. Con questa tecnica puoi condividere il carico e scalare il servizio in Kubernetes. Ricordi l'applicazione Python containerizzata nella precedente lezione? Avresti potuto sostituirla a Nginx e usare gli stessi strumenti per eseguirne il deployment e scalarla. L'ultima domanda a cui risponderemo è: cosa accade quando vuoi aggiornare la versione della tua applicazione? Ti conviene aggiornare il tuo container e pubblicare il nuovo codice per gli utenti il prima possibile, ma troppi cambiamenti in una sola volta potrebbero essere rischiosi. Non vuoi tempi di inattività per gli utenti mentre l'applicazione viene ricreata e sottoposta nuovamente a deployment. Ecco perché un attributo di un deployment è la sua strategia di aggiornamento. Ecco un esempio: l'aggiornamento in sequenza. Quando scegli l'aggiornamento in sequenza per un deployment e gli fornisci una nuova versione del software che gestisce, Kubernetes crea uno per uno i pod della nuova versione e attende che ciascun pod della nuova versione sia disponibile prima di distruggere i pod della versione precedente. Con l'aggiornamento in sequenza pubblichi subito la nuova versione dell'applicazione evitando tempi di inattività per gli utenti.