Cos'è Kubernetes? Una guida alla containerizzazione e alla distribuzione
Pubblicato: 2022-03-11Poco tempo fa abbiamo utilizzato l'applicazione web monolito: enormi basi di codice che sono cresciute in nuove funzioni e caratteristiche fino a trasformarsi in giganti enormi, lenti e difficili da gestire. Ora, un numero crescente di sviluppatori, architetti ed esperti di DevOps sta arrivando all'opinione che sia meglio utilizzare i microservizi rispetto a un gigantesco monolite. In genere, l'utilizzo di un'architettura basata su microservizi significa suddividere il monolito in almeno due applicazioni: l'app front-end e un'app back-end (l'API). Dopo la decisione di utilizzare i microservizi, sorge una domanda: in quale ambiente è meglio eseguire i microservizi? Cosa devo scegliere per rendere il mio servizio stabile e facile da gestire e distribuire? La risposta breve è: Usa Docker!
In questo articolo ti presenterò ai container, spiegherò Kubernetes e ti insegnerò come containerizzare e distribuire un'app in un cluster Kubernetes usando CircleCI.
Docker? Cos'è Docker?
Docker è uno strumento progettato per semplificare DevOps (e la tua vita). Con Docker, uno sviluppatore può creare, distribuire ed eseguire applicazioni in container . I container consentono a uno sviluppatore di impacchettare un'applicazione con tutte le parti di cui ha bisogno, come librerie e altre dipendenze, e spedire il tutto come un unico pacchetto.
Utilizzando i container, gli sviluppatori possono facilmente (ri)distribuire un'immagine su qualsiasi sistema operativo. Installa Docker, esegui un comando e la tua applicazione è attiva e funzionante. Oh, e non preoccuparti di eventuali incoerenze con la nuova versione delle librerie nel sistema operativo host. Inoltre, puoi avviare più container sullo stesso host: sarà la stessa app o un'altra? Non importa.
Sembra che Docker sia uno strumento fantastico. Ma come e dove devo lanciare i container?
Esistono molte opzioni su come e dove eseguire i container: AWS Elastic Container Service (AWS Fargate o un'istanza riservata con ridimensionamento automatico orizzontale e verticale); un'istanza cloud con un'immagine Docker predefinita in Azure o Google Cloud (con modelli, gruppi di istanze e ridimensionamento automatico); sul tuo server con Docker; o, naturalmente, Kubernetes! Kubernetes è stato creato appositamente per la virtualizzazione e i container dagli ingegneri di Google nel 2014.
Kubernete? Cos'è quello?
Kubernetes è un sistema open source che consente di eseguire container, gestirli, automatizzare distribuzioni, scalare distribuzioni, creare e configurare ingressi, distribuire applicazioni stateless o stateful e molte altre cose. Fondamentalmente, puoi avviare una o più istanze e installare Kubernetes per gestirle come un cluster Kubernetes. Quindi ottieni l'endpoint API del cluster Kubernetes, configura kubectl
(uno strumento per la gestione dei cluster Kubernetes) e Kubernetes è pronto per essere utilizzato.
Allora perché dovrei usarlo?
Con Kubernetes puoi utilizzare al massimo le risorse di calcolo. Con Kubernetes, sarai il capitano della tua nave (infrastruttura) con Kubernetes che riempirà le tue vele. Con Kubernetes, il tuo servizio sarà HA. E, soprattutto, con Kubernetes risparmierai un bel po' di soldi.
Sembra promettente! Soprattutto se farà risparmiare denaro! Parliamone di più!
Kubernetes sta guadagnando popolarità giorno dopo giorno. Andiamo più a fondo e indaghiamo cosa c'è sotto il cofano.
Sotto il cofano: cos'è Kubernetes?
Kubernetes è il nome dell'intero sistema, ma come la tua auto, ci sono molti piccoli pezzi che lavorano insieme in perfetta armonia per far funzionare Kubernetes. Impariamo quali sono.
Master Node – Un pannello di controllo per l'intero cluster Kubernetes. I componenti del master possono essere eseguiti su qualsiasi nodo del cluster. I componenti chiave sono:
- Server API: il punto di ingresso per tutti i comandi REST, l'unico componente del Master Node accessibile dall'utente.
- Datastore: storage per valori-chiave solido, coerente e ad alta disponibilità utilizzato dal cluster Kubernetes.
- Utilità di pianificazione: controlla i pod appena creati e li assegna ai nodi. La distribuzione di pod e servizi sui nodi avviene a causa dello scheduler.
- Gestore controller: esegue tutti i controller che gestiscono le attività di routine nel cluster.
- Nodi di lavoro: agente del nodo primario, chiamato anche nodi minion. I pod vengono eseguiti qui. I nodi di lavoro contengono tutti i servizi necessari per gestire il networking tra i container, comunicare con il nodo master e assegnare risorse ai container pianificati.
- Docker: viene eseguito su ogni nodo di lavoro e scarica le immagini e avvia i contenitori.
- Kubelet: monitora lo stato di un pod e assicura che i container siano attivi e funzionanti. Comunica inoltre con l'archivio dati, ottenendo informazioni sui servizi e scrivendo dettagli su quelli appena creati.
- Kube-proxy: un proxy di rete e un servizio di bilanciamento del carico per un servizio su un singolo nodo di lavoro. È responsabile dell'instradamento del traffico.
- Kubectl: uno strumento CLI per consentire agli utenti di comunicare con il server API Kubernetes.
Cosa sono i pod e i servizi?
I baccelli sono l'unità più piccola del cluster Kubernetes, è come un mattone nel muro di un enorme edificio. Un pod è un insieme di contenitori che devono essere eseguiti insieme e possono condividere risorse (spazi dei nomi Linux, cgroup, indirizzi IP). I baccelli non sono destinati a vivere a lungo.
I servizi sono un'astrazione sopra un certo numero di pod, che in genere richiedono un proxy sopra per altri servizi per comunicare con esso tramite un indirizzo IP virtuale.
Esempio di distribuzione semplice
Userò una semplice applicazione Ruby on Rails e GKE come piattaforma per eseguire Kubernetes. In realtà, puoi utilizzare Kubernetes in AWS o Azure o persino creare un cluster nel tuo hardware o eseguire Kubernetes localmente usando minikube
, tutte opzioni che troverai in questa pagina.
I file di origine per questa app possono essere trovati in questo repository GitHub.
Per creare una nuova app Rails, esegui:
rails new blog
Per configurare la connessione MySQL per la produzione nel config/database.yml file
:
production: adapter: mysql2 encoding: utf8 pool: 5 port: 3306 database: <%= ENV['DATABASE_NAME'] %> host: 127.0.0.1 username: <%= ENV['DATABASE_USERNAME'] %> password: <%= ENV['DATABASE_PASSWORD'] %>
Per creare un modello di articolo, un controller, viste e una migrazione, eseguire:
rails g scaffold Article title:string description:text
Per aggiungere gemme al Gemfile:
gem 'mysql2', '< 0.6.0', '>= 0.4.4' gem 'health_check'
Per creare l'immagine Docker, prendi il mio Dockerfile ed esegui:
docker build -t REPO_NAME/IMAGE_NAME:TAG . && docker push REPO_NAME/IMAGE_NAME:TAG
È ora di creare un cluster Kubernetes. Apri la pagina GKE e crea il cluster Kubernetes. Quando il cluster è stato creato, fai clic sul "pulsante Connetti" e copia il comando: assicurati di avere lo strumento gCloud CLI (come fare per) e kubectl installato e configurato. Esegui il comando copiato sul tuo PC e verifica la connessione al cluster Kubernetes; esegui kubectl cluster-info
.
L'app è pronta per la distribuzione nel cluster k8s. Creiamo un database MySQL. Apri la pagina SQL nella console di gCloud e crea un'istanza database MySQL per l'applicazione. Quando l'istanza è pronta, crea l'utente e il DB e copia il nome della connessione dell'istanza .
Inoltre, è necessario creare una chiave dell'account di servizio nella pagina API e servizi per accedere a un DB MySQL da un contenitore sidecar. Puoi trovare maggiori informazioni su questo processo qui. Rinominare il file scaricato in service-account.json
. Torneremo più tardi su quel file.

Siamo pronti per distribuire la nostra applicazione su Kubernetes, ma prima dobbiamo creare dei segreti per la nostra applicazione, un oggetto segreto in Kubernetes creato per l'archiviazione di dati sensibili. Carica il file service-account.json
scaricato in precedenza:
kubectl create secret generic mysql-instance-credentials \ --from-file=credentials.json=service-account.json
Crea segreti per l'applicazione:
kubectl create secret generic simple-app-secrets \ --from-literal=username=$MYSQL_PASSWORD \ --from-literal=password=$MYSQL_PASSWORD \ --from-literal=database-name=$MYSQL_DB_NAME \ --from-literal=secretkey=$SECRET_RAILS_KEY
Non dimenticare di sostituire i valori o di impostare le variabili di ambiente con i tuoi valori.
Prima di creare una distribuzione, diamo un'occhiata al file di distribuzione. Ho concatenato tre file in uno; la prima parte è un servizio che esporrà la porta 80 e inoltrerà tutte le connessioni che arrivano alla porta 80 a 3000. Il servizio ha un selettore con cui il servizio sa a quali pod deve inoltrare le connessioni.
La parte successiva del file è la distribuzione, che descrive la strategia di distribuzione: contenitori che verranno avviati all'interno del pod, variabili di ambiente, risorse, sonde, montaggi per ogni contenitore e altre informazioni.
L'ultima parte è la scalabilità automatica del pod orizzontale. HPA ha una configurazione piuttosto semplice. Tieni presente che se non imposti le risorse per il contenitore nella sezione di distribuzione, HPA non funzionerà.
Puoi configurare Vertical Autoscaler per il tuo cluster Kubernetes nella pagina di modifica di GKE. Ha anche una configurazione piuttosto semplice.
È ora di spedirlo al cluster GKE! Prima di tutto, dovremmo eseguire le migrazioni tramite job. Eseguire:
kubectl apply -f rake-tasks-job.yaml
– Questo lavoro sarà utile per il processo CI/CD.
kubectl apply -f deployment.yaml
– per creare servizi, distribuzione e HPA.
E quindi controlla il tuo pod eseguendo il comando: kubectl get pods -w
NAME READY STATUS RESTARTS AGE sample-799bf9fd9c-86cqf 2/2 Running 0 1m sample-799bf9fd9c-887vv 2/2 Running 0 1m sample-799bf9fd9c-pkscp 2/2 Running 0 1m
Ora creiamo un ingresso per l'applicazione:
- Crea un IP statico:
gcloud compute addresses create sample-ip --global
- Crea l'ingresso (file):
kubectl apply -f ingress.yaml
- Verifica che l'ingresso sia stato creato e prendi l'IP:
kubectl get ingress -w
- Crea il dominio/sottodominio per la tua applicazione.
CI/CD
Creiamo una pipeline CI/CD usando CircleCI. In realtà, è facile creare una pipeline CI/CD utilizzando CircleCI, ma tieni presente che un processo di distribuzione completamente automatizzato rapido e sporco senza test come questo funzionerà per piccoli progetti, ma per favore non farlo per niente di serio perché , se un nuovo codice presenta problemi in produzione, perderai denaro. Ecco perché dovresti pensare a progettare un solido processo di distribuzione, avviare attività di Canary prima dell'implementazione completa, controllare gli errori nei log dopo l'avvio di Canary e così via.
Al momento, abbiamo un progetto piccolo e semplice, quindi creiamo un processo di distribuzione CI/CD completamente automatizzato, senza test. Innanzitutto, dovresti integrare CircleCI con il tuo repository: puoi trovare tutte le istruzioni qui. Quindi dovremmo creare un file di configurazione con le istruzioni per il sistema CircleCI. La configurazione sembra piuttosto semplice. I punti principali sono che ci sono due rami nel repository GitHub: master
e production
.
- Il ramo principale è per lo sviluppo, per il codice fresco. Quando qualcuno invia un nuovo codice al ramo principale, CircleCI avvia un flusso di lavoro per il ramo principale: creare e testare il codice.
- Il ramo di produzione serve per distribuire una nuova versione nell'ambiente di produzione. Il flusso di lavoro per il ramo di produzione è il seguente: inviare nuovo codice (o, meglio ancora, aprire PR dal ramo principale alla produzione) per attivare un nuovo processo di compilazione e distribuzione; durante la compilazione, CircleCI crea nuove immagini Docker, le invia al GCR e crea un nuovo rollout per la distribuzione; se il rollout non riesce, CircleCI attiva il processo di rollback.
Prima di eseguire qualsiasi build, dovresti configurare un progetto in CircleCI. Crea un nuovo account di servizio nell'API e una pagina Servizi in GCloud con questi ruoli: accesso completo a GCR e GKE, apri il file JSON scaricato e copia i contenuti, quindi crea una nuova variabile di ambiente nelle impostazioni del progetto in CircleCI con il nome GCLOUD_SERVICE_KEY
e incolla il contenuto del file dell'account di servizio come valore. Inoltre, devi creare le successive env vars: GOOGLE_PROJECT_ID
(puoi trovarlo nella home page della console di GCloud), GOOGLE_COMPUTE_ZONE
(una zona per il tuo cluster GKE) e GOOGLE_CLUSTER_NAME
(nome del cluster GKE).
L'ultimo passaggio (distribuzione) in CircleCI sarà simile a:
kubectl patch deployment sample -p '{"spec":{"template":{"spec":{"containers":[{"name":"sample","image":"gcr.io/test-d6bf8/simple:'"$CIRCLE_SHA1"'"}]}}}}' if ! kubectl rollout status deploy/sample; then echo "DEPLOY FAILED, ROLLING BACK TO PREVIOUS" kubectl rollout undo deploy/sample # Deploy failed -> notify slack else echo "Deploy succeeded, current version: ${CIRCLE_SHA1}" # Deploy succeeded -> notify slack fi deployment.extensions/sample patched Waiting for deployment "sample" rollout to finish: 2 out of 3 new replicas have been updated... Waiting for deployment "sample" rollout to finish: 2 out of 3 new replicas have been updated... Waiting for deployment "sample" rollout to finish: 2 out of 3 new replicas have been updated... Waiting for deployment "sample" rollout to finish: 1 old replicas are pending termination... Waiting for deployment "sample" rollout to finish: 1 old replicas are pending termination... Waiting for deployment "sample" rollout to finish: 1 old replicas are pending termination... Waiting for deployment "sample" rollout to finish: 2 of 3 updated replicas are available... Waiting for deployment "sample" rollout to finish: 2 of 3 updated replicas are available... deployment "sample" successfully rolled out Deploy succeeded, current version: 512eabb11c463c5431a1af4ed0b9ebd23597edd9
Conclusione
Sembra che il processo di creazione del nuovo cluster Kubernetes non sia così difficile! E il processo CI/CD è davvero fantastico!
Sì! Kubernetes è fantastico! Con Kubernetes, il tuo sistema sarà più stabile, facilmente gestibile e ti renderà il capitano del tuo sistema. Per non parlare del fatto che Kubernetes gamifica un po' il sistema e darà +100 punti per il tuo marketing!
Ora che hai le basi in basso, puoi andare oltre e trasformarlo in una configurazione più avanzata. Sto pianificando di trattare di più in un articolo futuro, ma nel frattempo, ecco una sfida: creare un robusto cluster Kubernetes per la tua applicazione con un DB stateful situato all'interno del cluster (incluso il pod sidecar per eseguire i backup), installare Jenkins all'interno del stesso cluster Kubernetes per la pipeline CI/CD e consenti a Jenkins di utilizzare i pod come slave per le build. Usa certmanager per aggiungere/ottenere un certificato SSL per il tuo ingresso. Crea un sistema di monitoraggio e avviso per la tua applicazione utilizzando Stackdriver.
Kubernetes è eccezionale perché si adatta facilmente, non c'è alcun blocco del fornitore e, dal momento che stai pagando per le istanze, risparmi denaro. Tuttavia, non tutti sono esperti di Kubernetes o hanno il tempo di creare un nuovo cluster: per una visione alternativa, il collega Toptaler Amin Shah Gilani sostiene l'uso di Heroku, GitLab CI e una grande quantità di automazione che ha già capito per scrivere più codice ed eseguire meno attività operative in Come creare una pipeline di distribuzione iniziale efficace .
- Fai i conti: ridimensionamento automatico delle applicazioni di microservizi con gli orchestrator
- K8s/Kubernetes: AWS vs GCP vs Azure
- Un confronto della mesh del servizio Kubernetes