Anthos Service Mesh è un potente strumento per gestire e monitorare le applicazioni distribuite. Per ottenere il massimo da Anthos Service Mesh, è utile comprendere le sue astrazioni sottostanti, inclusi container e Kubernetes. Questo tutorial spiega come preparare un'applicazione per Anthos Service Mesh dal codice sorgente a un container in esecuzione su GKE, fino al momento precedente l'installazione di Anthos Service Mesh.
Se hai già familiarità con i concetti di Kubernetes e mesh di servizi, puoi saltare questo tutorial e andare direttamente alla guida all'installazione di Anthos Service Mesh.
Obiettivi
In questo tutorial imparerai a:
- Esplora una semplice applicazione multi-servizio "hello world".
- Esegui l'applicazione dall'origine
- Containerizzare l'applicazione.
- Creare un cluster Kubernetes.
- Eseguire il deployment dei container nel cluster.
Prima di iniziare
Svolgi i seguenti passaggi per abilitare l'API Anthos Service Mesh:- Visita la pagina di Kubernetes Engine nella console Google Cloud.
- Crea o seleziona un progetto.
- Attendi che l'API e i relativi servizi siano abilitati. Questa operazione può richiedere alcuni minuti.
-
Assicurati che la fatturazione sia attivata per il tuo progetto Cloud. Scopri come verificare se la fatturazione è abilitata su un progetto.
Puoi seguire questo tutorial utilizzando Cloud Shell, che esegue il provisioning di una macchina virtuale (VM) Google Compute Engine g1-small che esegue un sistema operativo Linux basato su Debian o del tuo computer che esegue Linux o macOS.
Opzione A: utilizza Cloud Shell
I vantaggi di utilizzare Cloud Shell sono:
- Entrambi gli ambienti di sviluppo Python 2 e Python 3 (incluso
virtualenv
) sono tutti configurati. - Gli strumenti a riga di comando
gcloud
,docker
,git
ekubectl
utilizzati in questo tutorial sono già installati. Hai la possibilità di scegliere editor di testo:
Editor di codice, a cui puoi accedere facendo clic su nella parte superiore della finestra di Cloud Shell.
Emacs, Vim o Nano, a cui puoi accedere dalla riga di comando in Cloud Shell.
Per utilizzare Cloud Shell:
- Vai alla console Google Cloud.
Fai clic sul pulsante Attiva Cloud Shell nella parte superiore della finestra della console Google Cloud.
Viene aperta una sessione di Cloud Shell all'interno di un nuovo frame nella parte inferiore della console Google Cloud e mostra un prompt della riga di comando.
Opzione B: utilizza gli strumenti a riga di comando localmente
Se preferisci seguire questo tutorial su computer Linux o macOS, devi configurare e installare quanto segue:
- Configurare un ambiente di sviluppo Python 3 e Python 2.
- Installa Google Cloud CLI.
Installa anche
kubectl
, una riga di comando che utilizzi per comunicare con Kubernetes.gcloud components install kubectl
Installa Docker Community Edition (CE). Puoi utilizzare lo strumento a riga di comando
docker
per creare le immagini container dell'applicazione di esempio.Installare lo strumento di controllo dell'origine Git in modo da poter recuperare l'applicazione di esempio da GitHub.
Scarica il codice campione
Scarica il codice sorgente di
helloserver
:git clone https://github.com/GoogleCloudPlatform/istio-samples
Passa alla directory del codice di esempio:
cd istio-samples/sample-apps/helloserver
Esplora l'applicazione multiservizio
L'applicazione di esempio è scritta in Python e ha due componenti che comunicano utilizzando REST:
server
: un server semplice con un endpointGET
,/
, che stampa "hello world" sulla console.loadgen
: uno script che invia traffico aserver
, con un numero configurabile di richieste al secondo (RPS).
Esegui l'applicazione dall'origine
Per acquisire familiarità con l'applicazione di esempio, eseguila in Cloud Shell o sul computer.
Dalla directory
sample-apps/helloserver
, esegui il comandoserver
:python3 server/server.py
All'avvio,
server
mostra quanto segue:INFO:root:Starting server...
Apri un'altra finestra del terminale per inviare le richieste a
server
. Se utilizzi Cloud Shell, fai clic su per aprire un'altra sessione.Invia una richiesta a
server
:curl http://localhost:8080
server
risponde:Hello World!
Dalla directory in cui hai scaricato il codice campione, passa alla directory che contiene
loadgen
:cd YOUR_WORKING_DIRECTORY/istio-samples/sample-apps/helloserver/loadgen
Crea le seguenti variabili di ambiente:
export SERVER_ADDR=http://localhost:8080 export REQUESTS_PER_SECOND=5
Avvia
virtualenv
:virtualenv --python python3 env
Attiva l'ambiente virtuale:
source env/bin/activate
Installa i requisiti per
loadgen
:pip3 install -r requirements.txt
Esegui
loadgen
:python3 loadgen.py
All'avvio,
loadgen
genera un messaggio simile al seguente:Starting loadgen: 2019-05-20 10:44:12.448415 5 request(s) complete to http://localhost:8080
Nell'altra finestra del terminale,
server
scrive i messaggi nella console in modo simile al seguente:127.0.0.1 - - [21/Jun/2019 14:22:01] "GET / HTTP/1.1" 200 - INFO:root:GET request, Path: / Headers: Host: localhost:8080 User-Agent: python-requests/2.22.0 Accept-Encoding: gzip, deflate Accept: */*
Dal punto di vista del networking, l'intera applicazione è ora in esecuzione sullo stesso host (il computer locale o la VM Cloud Shell). Per questo motivo puoi utilizzare le
localhost
per inviare richieste alserver
.Per interrompere
loadgen
eserver
, inserisciCtrl-c
in ogni finestra del terminale.Nella finestra del terminale
loadgen
, disattiva l'ambiente virtuale:deactivate
Containerizzare l'applicazione
Per eseguire l'applicazione su GKE, devi pacchettizzare l'applicazione
di esempio, sia server
che loadgen
, in container. Un container è un modo per pacchettizzare un'applicazione in modo che sia isolato dall'ambiente sottostante.
Per containerizzare l'applicazione, è necessario Dockerfile
. Un Dockerfile
è un file di testo che definisce i comandi necessari all'assemblaggio del codice sorgente dell'applicazione e delle sue dipendenze in unDocker immagine. Dopo aver creato l'immagine, la carichi in un Container Registry, come Docker Hub o Container Registry.
L'esempio include un Dockerfile
per server
e loadgen
con tutti i comandi necessari per creare le immagini. Di seguito è riportato il
Dockerfile
di server
:
- Il comando
FROM python:3-slim as base
indica a Docker di utilizzare l'ultima immagine Python 3 come immagine di base. - Il comando
COPY . .
copia i file di origine nella directory di lavoro attuale (in questo caso, soloserver.py
) nel file system del container. ENTRYPOINT
definisce il comando utilizzato per eseguire il container. In questo caso, il comando è quasi uguale a quello utilizzato per eseguireserver.py
dal codice sorgente.- Il comando
EXPOSE
specifica cheserver
rimane in ascolto sulla porta8080
. Questo comando non espone alcuna porta, ma funge da documentazione necessaria per aprire la porta8080
quando esegui il container.
Prepararsi a containerizzare l'applicazione
Imposta le seguenti variabili di ambiente. Sostituisci
PROJECT_ID
con l'ID del tuo progetto Cloud.export PROJECT_ID="PROJECT_ID"
export GCR_REPO="asm-ready"
Utilizzi il valore
PROJECT_ID
eGCR_REPO
per codificare l'immagine Docker quando crei questa e poi eseguirne il push su Container Registry privato.Imposta il progetto Cloud predefinito per Google Cloud CLI.
gcloud config set project $PROJECT_ID
Imposta la zona predefinita per Google Cloud CLI.
gcloud config set compute/zone us-central1-b
Assicurati che il servizio Container Registry sia abilitato nel tuo progetto Cloud.
gcloud services enable containerregistry.googleapis.com
Containerizza l'server
Passa alla directory in cui si trova l'esempio
server
:cd YOUR_WORKING_DIRECTORY/istio-samples/sample-apps/helloserver/server/
Crea l'immagine utilizzando
Dockerfile
e le variabili di ambiente che hai definito in precedenza:docker build -t gcr.io/$PROJECT_ID/$GCR_REPO/helloserver:v0.0.1 .
Il flag
-t
rappresenta il tag Docker. Questo è il nome dell'immagine che utilizzi quando esegui il deployment del container.Esegui il push dell'immagine a Container Registry:
docker push gcr.io/$PROJECT_ID/$GCR_REPO/helloserver:v0.0.1
Containerizza l'loadgen
Passa alla directory in cui si trova l'esempio
loadgen
:cd ../loadgen
Crea l'immagine:
docker build -t gcr.io/$PROJECT_ID/$GCR_REPO/loadgen:v0.0.1 .
Esegui il push dell'immagine a Container Registry:
docker push gcr.io/$PROJECT_ID/$GCR_REPO/loadgen:v0.0.1
Elenca le immagini
Scarica un elenco delle immagini nel repository per confermare che siano state trasferite:
gcloud container images list --repository gcr.io/$PROJECT_ID/asm-ready
Il comando risponde con i nomi delle immagini di cui hai appena eseguito il push:
NAME gcr.io/PROJECT_ID/asm-ready/helloserver gcr.io/PROJECT_ID/asm-ready/loadgen
crea un cluster GKE
Puoi eseguire questi container sulla VM Cloud Shell o sulla tua workstation utilizzando il comando docker run
. Ma in produzione è necessario orchestrare i container in modo più unificato. Ad esempio, ti serve un sistema che garantisca l'esecuzione continua dei container e ti serve un modo per fare lo scale up e avviare istanze aggiuntive di un container per gestire gli aumenti del traffico.
Puoi utilizzare GKE per eseguire applicazioni containerizzate. GKE è una piattaforma di orchestrazione dei container che connette le VM a un cluster. Ogni VM viene definita nodo. I cluster GKE sono basati sul sistema open source di gestione dei cluster Kubernetes. Kubernetes fornisce i meccanismi attraverso i quali interagisci con il tuo cluster.
Per creare un cluster GKE:
Crea il cluster:
gcloud container clusters create asm-ready \ --cluster-version latest \ --machine-type=n1-standard-4 \ --num-nodes 4
Il comando
gcloud
crea un cluster nel progetto e nella zona Cloud impostati in precedenza. Per eseguire Anthos Service Mesh, ti consigliamo almeno 4 nodi e il tipo di macchina n1-standard-4.Il comando per creare il cluster richiede alcuni minuti. Quando il cluster è pronto, il comando restituisce un messaggio simile al seguente:
NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS asm-ready us-central1-b 1.13.5-gke.10 203.0.113.1 n1-standard-2 1.13.5-gke.10 4 RUNNING
Fornisci le credenziali allo strumento a riga di comando
kubectl
in modo da poterlo utilizzare per gestire il cluster:gcloud container clusters get-credentials asm-ready
Ora puoi utilizzare
kubectl
per comunicare con Kubernetes. Ad esempio, puoi eseguire il comando seguente per ottenere lo stato dei nodi:kubectl get nodes
Il comando risponde con un elenco di nodi, simile al seguente:
NAME STATUS ROLES AGE VERSION gke-asm-ready-default-pool-dbeb23dc-1vg0 Ready <none> 99s v1.13.6-gke.13 gke-asm-ready-default-pool-dbeb23dc-36z5 Ready <none> 100s v1.13.6-gke.13 gke-asm-ready-default-pool-dbeb23dc-fj7s Ready <none> 99s v1.13.6-gke.13 gke-asm-ready-default-pool-dbeb23dc-wbjw Ready <none> 99s v1.13.6-gke.13
Comprendere i concetti chiave di Kubernetes
Il seguente diagramma mostra l'applicazione in esecuzione su GKE:
Prima di eseguire il deployment dei container in GKE, ti consigliamo di rivedere alcuni concetti chiave di Kubernetes. La fine di questo tutorial fornisce i link per aiutarti a scoprire ogni concetto.
Nodi e cluster: in GKE, un nodo è una VM. Su altre piattaforme Kubernetes, un nodo può essere una macchina fisica o virtuale. Un cluster è un insieme di nodi che possono essere trattati insieme come una singola macchina, in cui eseguire il deployment di un'applicazione containerizzata.
Pod: in Kubernetes, i container vengono eseguiti all'interno di un pod. Un pod è l'unità atomica in Kubernetes. Un pod contiene uno o più container. Esegui il deployment dei container
server
eloadgen
nel rispettivo pod. Quando un pod esegue più container (ad esempio, un server applicazioni e un server proxy), i container vengono gestiti come una singola entità e condividono le risorse del pod.Deployment: un deployment è un oggetto Kubernetes che rappresenta un insieme di pod identici. Un deployment esegue più repliche dei pod distribuiti tra i nodi di un cluster. Un deployment sostituisce automaticamente qualsiasi pod in errore o che non risponde.
Servizio Kubernetes: l'esecuzione del codice dell'applicazione in GKE cambia il networking tra
loadgen
eserver
. Quando hai eseguito i servizi in una VM Cloud Shell o sul computer, puoi inviare richieste aserver
utilizzando l'indirizzolocalhost:8080
. Dopo il deployment su GKE, i pod sono pianificati per essere eseguiti sui nodi disponibili. Per impostazione predefinita, non puoi controllare su quale nodo è in esecuzione il pod, per cui i pod non hanno indirizzi IP stabili.Per ottenere un indirizzo IP per
server
, devi definire un'astrazione di rete sopra i pod chiamati servizio Kubernetes. Un servizio Kubernetes fornisce un endpoint di rete stabile per un insieme di pod. Esistono diversi tipi di servizi.server
utilizza unLoadBalancer
, che espone un indirizzo IP esterno per consentirti di raggiungereserver
dall'esterno del cluster.Kubernetes ha anche un sistema DNS integrato, che assegna nomi DNS (ad esempio,
helloserver.default.cluster.local
) ai servizi. In questo modo, i pod all'interno del cluster possono raggiungere altri pod nel cluster con un indirizzo stabile. Non puoi utilizzare questo nome DNS all'esterno del cluster, ad esempio da Cloud Shell o dal computer.
I manifest di Kubernetes
Quando hai eseguito l'applicazione dal codice sorgente, hai utilizzato un comando imperativo: python3 server.py
Imperativo significa "verbi".
Al contrario, Kubernetes utilizza un modello dichiarativo. Ciò significa che, invece di indicare a Kubernetes esattamente cosa fare, fornisci a Kubernetes uno stato desiderato. Ad esempio, Kubernetes avvia e termina i pod in base alle necessità in modo che l'effettivo stato del sistema corrisponda a quello desiderato.
Specifica lo stato desiderato in un insieme di manifest o file YAML. Un file YAML contiene la specifica di uno o più oggetti Kubernetes.
L'esempio contiene un file YAML per server
e loadgen
. Ogni file YAML specifica lo stato desiderato per l'oggetto e il servizio Kubernetes Deployment.
Server
kind
indica il tipo di oggetto.metadata.name
specifica il nome del deployment.- Il primo campo
spec
contiene una descrizione dello stato desiderato. spec.replicas
specifica il numero di pod desiderati.- La sezione
spec.template
definisce un modello di pod. Nella specifica per i pod è incluso il campoimage
, che è il nome dell'immagine di cui eseguire il pull da Container Registry.
Il Servizio è definito come segue:
LoadBalancer
: i client inviano richieste all'indirizzo IP di un bilanciatore del carico di rete, che ha un indirizzo IP stabile ed è raggiungibile all'esterno del cluster.targetPort
: ricorda che il comandoEXPOSE 8080
inDockerfile
non espone effettivamente alcuna porta. Esponi la porta8080
in modo da poter raggiungere il containerserver
al di fuori del cluster. In questo caso,hellosvc.default.cluster.local:80
(nome breve:hellosvc
) è mappato alla porta8080
dell'IP del podhelloserver
.port
: questo è il numero di porta utilizzato da altri servizi nel cluster per l'invio di richieste.
Generatore di carico
L'oggetto Deployment in loadgen.yaml
è simile a server.yaml
. Una differenza significativa è che l'oggetto Deployment contiene una sezione chiamata env
. Questa sezione definisce le variabili di ambiente richieste da loadgen
, che hai impostato in precedenza quando hai eseguito l'applicazione dall'origine.
Poiché loadgen
non accetta richieste in entrata, il campo type
è impostato su ClusterIP
. Questo tipo fornisce un indirizzo IP stabile che può essere utilizzato dai servizi nel cluster, ma non è esposto a client esterni.
Esegui il deployment dei container in GKE
Passa alla directory in cui si trova l'esempio
server
:cd YOUR_WORKING_DIRECTORY/istio-samples/sample-apps/helloserver/server/
Apri
server.yaml
in un editor di testo.Sostituisci il nome nel campo
image
con il nome della tua immagine Docker.image: gcr.io/PROJECT_ID/asm-ready/helloserver:v0.0.1
Sostituisci
PROJECT_ID
con il tuo ID progetto Cloud.Salva e chiudi
server.yaml
.Esegui il deployment del file YAML in Kubernetes:
kubectl apply -f server.yaml
In caso di esito positivo, il comando risponde con quanto segue:
deployment.apps/helloserver created service/hellosvc created
Passa alla directory in cui si trova
loadgen
.cd ../loadgen
Apri
loadgen.yaml
in un editor di testo.Sostituisci il nome nel campo
image
con il nome della tua immagine Docker.image: gcr.io/PROJECT_ID/asm-ready/loadgen:v0.0.1
Sostituisci
PROJECT_ID
con il tuo ID progetto Cloud.Salva e chiudi
loadgen.yaml
, quindi chiudi l'editor di testo.Esegui il deployment del file YAML in Kubernetes:
kubectl apply -f loadgen.yaml
In caso di esito positivo, il comando risponde con quanto segue:
deployment.apps/loadgenerator created service/loadgensvc created
Controlla lo stato dei pod:
kubectl get pods
Il comando risponde con lo stato simile al seguente:
NAME READY STATUS RESTARTS AGE helloserver-69b9576d96-mwtcj 1/1 Running 0 58s loadgenerator-774dbc46fb-gpbrz 1/1 Running 0 57s
Recupera i log dell'applicazione dal pod
loadgen
. SostituisciPOD_ID
con l'identificatore dell'output precedente.kubectl logs loadgenerator-POD_ID
Ottieni gli indirizzi IP esterni di
hellosvc
:kubectl get service
La risposta del comando è simile alla seguente:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE hellosvc LoadBalancer 10.81.15.158 192.0.2.1 80:31127/TCP 33m kubernetes ClusterIP 10.81.0.1 <none> 443/TCP 93m loadgensvc ClusterIP 10.81.15.155 <none> 80/TCP 4m52s
Invia una richiesta al
hellosvc
. SostituisciEXTERNAL_IP
con l'indirizzo IP esterno del tuo dispositivohellosvc
.curl http://EXTERNAL_IP
Pronto per Anthos Service Mesh
Ora hai eseguito il deployment dell'applicazione in GKE. loadgen
può utilizzare il DNS di Kubernetes (hellosvc:80
) per inviare richieste a server
, mentre tu puoi inviare richieste a server
con un indirizzo IP esterno. Sebbene Kubernetes fornisca molte funzionalità, alcune informazioni sui servizi mancano:
- Come interagiscono i servizi? Qual è la relazione tra i servizi? Come passa il traffico tra i servizi? Sai che
loadgen
invia richieste aserver
, ma immagina di non conoscere l'applicazione. Non puoi rispondere a queste domande nell'elenco dei pod in esecuzione su GKE. - Metriche: quanto tempo impiega
server
per rispondere alle richieste in arrivo? Quante richieste al secondo (RPS) sono in entrata inserver
? Sono presenti risposte di errore? - Informazioni di sicurezza: il traffico tra
loadgen
eserver
è normaleHTTP
o mTLS?
Anthos Service Mesh può fornire risposte a queste domande. Anthos Service Mesh è una versione gestita da Google Cloud del progetto open source Istio. Anthos Service Mesh funziona inserendo un proxy sidecar Envoy in ogni pod. Il proxy Envoy intercetta tutto il traffico in entrata e in uscita verso i container dell'applicazione. Ciò
significa che server
e loadgen
ricevono ciascuno un proxy sidecar Envoy e tutto
il traffico da loadgen
a server
è mediato dai proxy Envoy. Le connessioni tra questi proxy Envoy formano il mesh di servizi. Questa architettura di mesh di servizi fornisce un livello di controllo su Kubernetes.
Poiché i proxy Envoy vengono eseguiti nei propri container, puoi installare Anthos Service Mesh su un cluster GKE senza modifiche significative al codice dell'applicazione. Tuttavia, ci sono alcuni modi chiave in cui hai preparato l'applicazione per essere strumentata con Anthos Service Mesh:
- Servizi per tutti i container: sia il deployment
server
cheloadgen
hanno un servizio Kubernetes collegato. Anche illoadgen
, che non riceve richieste in entrata, ha un servizio. - Le porte nei servizi devono essere denominate: anche se GKE ti consente di definire le porte di servizio senza nome, Anthos Service Mesh richiede che tu fornisca un nome per una porta che corrisponda al protocollo della porta. Nel file YAML, la porta per
server
è denominatahttp
perchéserver
utilizza il protocollo di comunicazioneHTTP
. Seservice
utilizzavagRPC
, assegnavi il nomegrpc
. - I deployment sono etichettati: questo consente di utilizzare le funzionalità di gestione del traffico di Anthos Service Mesh, come la suddivisione del traffico tra versioni dello stesso servizio.
Installazione di Anthos Service Mesh
Consulta la guida all'installazione di Anthos Service Mesh e segui le istruzioni per installare Anthos Service Mesh sul tuo cluster.
Esegui la pulizia
Per evitare che al tuo Account Google Cloud vengano addebitati costi relativi alle risorse utilizzate in questo tutorial, elimina il progetto che contiene le risorse oppure mantieni il progetto ed elimina le singole risorse.
Per eseguire la pulizia, elimina il cluster GKE. L'eliminazione del cluster elimina tutte le risorse che compongono il cluster del container, come le istanze di calcolo, i dischi e le risorse di rete.
gcloud container clusters delete asm-ready
Passaggi successivi
Scopri di più sulle tecnologie utilizzate in questo tutorial:
Scopri di più sugli strumenti:
Scopri di più sui concetti di Kubernetes: