Cloud Service Mesh è un potente strumento per la gestione e il monitoraggio diverse applicazioni. Per ottenere il massimo da Cloud Service Mesh, è utile comprendere dalle astrazioni sottostanti, tra cui container e Kubernetes. Questo tutorial spiega come preparare un'applicazione per Cloud Service Mesh dal codice sorgente a un contenitore in esecuzione su GKE, fino al punto immediatamente precedente all'installazione di Cloud Service Mesh.
Se hai già familiarità con i concetti di Kubernetes e del mesh di servizi, puoi salta questo tutorial e vai direttamente alla Cloud Service Mesh guida all'installazione.
Obiettivi
- Esplora un semplice "Hello World" multi-servizio un'applicazione.
- Esegui l'applicazione dall'origine
- Containerizza l'applicazione.
- Crea un cluster Kubernetes.
- Eseguire il deployment dei container nel cluster.
Prima di iniziare
Segui questi passaggi per abilitare l'API Cloud 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. L'operazione può richiedere diversi minuti.
-
Make sure that billing is enabled for your Google Cloud project.
Questo tutorial utilizza Cloud Shell, che esegue il provisioning di una macchina virtuale (VM) Compute Engine g1-small che esegue un sistema operativo Linux basato su Debian.
Prepara Cloud Shell
I vantaggi dell'utilizzo di Cloud Shell sono:
- Gli ambienti di sviluppo Python 2 e Python 3 (incluso
virtualenv
) sono configurati. - Gli strumenti a riga di comando
gcloud
,docker
,git
ekubectl
utilizzati in questo tutorial sono già installati. Puoi scegliere tra diversi 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 si accede dalla riga di comando in Cloud Shell.
In the Google Cloud console, activate Cloud Shell.
At the bottom of the Google Cloud console, a Cloud Shell session starts and displays a command-line prompt. Cloud Shell is a shell environment with the Google Cloud CLI already installed and with values already set for your current project. It can take a few seconds for the session to initialize.
Scarica il codice campione
Scarica il codice sorgente di
helloserver
:git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-samples
Passa alla directory codice campione:
cd anthos-service-mesh-samples/docs/helloserver
Esplora l'applicazione multiservizio
L'applicazione di esempio è scritta in Python e ha due componenti comunicare tramite REST:
server
: un semplice server con un endpointGET
,/
, che stampa "ciao mondo" alla console.loadgen
: uno script che invia il traffico aserver
, con un parametro di richieste al secondo (RPS).
Esegui l'applicazione dall'origine
Per acquisire familiarità con l'applicazione di esempio, eseguila in Cloud Shell.
Dalla directory
sample-apps/helloserver
, eseguiserver
:python3 server/server.py
All'avvio,
server
mostra quanto segue:INFO:root:Starting server...
Apri un'altra finestra del terminale per poter inviare richieste al
server
. Fai clic su per aprire un'altra sessione.Invia una richiesta al
server
:curl http://localhost:8080
server
risponde:Hello World!
Dalla directory in cui hai scaricato il codice di esempio, vai alla directory che contiene il file
loadgen
:cd YOUR_WORKING_DIRECTORY/anthos-service-mesh-samples/docs/helloserver/loadgen
Crea le seguenti variabili di ambiente:
export SERVER_ADDR=http://localhost:8080 export REQUESTS_PER_SECOND=5
Avvio
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
restituisce 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 messaggi nella console simili ai seguenti: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 lo stesso host. Per questo motivo, puoi utilizzare
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
Containerizza l'applicazione
Per eseguire l'applicazione su GKE, devi pacchettizzare l'esempio
server
e loadgen
in container. Un
container è un modo per pacchettizzare un'applicazione in modo che sia isolata dall'ambiente di base.
Per containerizzare l'applicazione, è necessario un Dockerfile
. Un Dockerfile
è un file di testo che definisce i comandi necessari per assemblare il codice sorgente dell'applicazione e le relative dipendenze in un'immagine Docker. Dopo aver creato l'immagine, la carichi in un registry dei container, ad esempio Docker Hub o
Container Registry.
L'esempio include un valore Dockerfile
sia per server
sia per loadgen
con tutti i comandi necessari per creare le immagini. Di seguito sono riportate le
Dockerfile
per server
:
- Il comando
FROM python:3-slim as base
indica a Docker di utilizzare la versione più recente immagine Python 3 come l'immagine di base. - Il comando
COPY . .
copia i file di origine nella directory di lavoro corrente (in questo caso soloserver.py
) nel file system del contenitore. ENTRYPOINT
definisce il comando utilizzato per eseguire il container. Nella in questo caso il comando è quasi uguale a quello usato per eseguireserver.py
dal codice sorgente.- Il comando
EXPOSE
specifica cheserver
ascolta sulla porta8080
. Questo comando esporre eventuali porte, ma serve da documentazione che ti serve per aprire la porta8080
quando esegui containerizzato.
Prepararsi a containerizzare l'applicazione
Imposta le seguenti variabili di ambiente. Sostituisci
PROJECT_ID
con l'ID del tuo progetto Google Cloud.export PROJECT_ID="PROJECT_ID"
export GCR_REPO="asm-ready"
Utilizzerai i valori
PROJECT_ID
eGCR_REPO
per taggare l'immagine Docker quando crei ed esegui il push sul tuo Container Registry privato.Imposta il progetto Google 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 progetto Google Cloud.
gcloud services enable containerregistry.googleapis.com
Containerizza server
Passa alla directory in cui si trova l'esempio
server
:cd YOUR_WORKING_DIRECTORY/anthos-service-mesh-samples/docs/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. Si tratta del nome dell'immagine che utilizzi per 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 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
Visualizza un elenco delle immagini nel repository per verificare che siano state pushate:
gcloud container images list --repository gcr.io/$PROJECT_ID/asm-ready
Il comando risponde con i nomi delle immagini che 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 utilizzando
Comando docker run
. Tuttavia, in produzione devi orchestrare i container in modo più unificato. Ad esempio, hai bisogno di un sistema che garantisca che i contenitori siano sempre in esecuzione e di un modo per eseguire l'upgrade e avviare istanze aggiuntive di un contenitore per gestire gli aumenti del traffico.
Puoi utilizzare GKE per eseguire applicazioni containerizzate. GKE è un servizio di orchestrazione che funziona collegando le VM a un cluster. Ogni VM è indicata come nodo. I cluster GKE sono basati sul sistema di gestione dei cluster open source Kubernetes. Kubernetes fornisce i meccanismi che consentono di interagire con il 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 Google Cloud impostati in precedenza. Per eseguire Cloud Service Mesh, consigliamo almeno 4 nodi e il tipo di macchina n1-standard-4.Il completamento del comando per creare il cluster richiede alcuni minuti. Quando 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 seguente comando 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 esaminare alcuni concetti chiave di Kubernetes. Alla fine di questo tutorial vengono forniti i link per poter conoscere meglio ogni concetto.
Nodi e cluster: in GKE, un nodo è una VM. Su altro su piattaforme Kubernetes, un nodo può essere sia una macchina fisica che una macchina virtuale. Un cluster è un insieme di nodi che possono essere trattati insieme come una singola macchina su cui esegui il deployment di un'applicazione containerizzata.
Pod: in Kubernetes, i container vengono eseguiti all'interno di un pod. Un pod è dell'unità atomica in Kubernetes. Un pod contiene uno o più container. Esegui il deployment dei container
server
eloadgen
ciascuno nel proprio pod. Quando un pod esegue più container (ad esempio un server di applicazioni e un server proxy), i container vengono gestiti come un'unica entità e condividono le risorse del pod.Deployment: un deployment è un oggetto Kubernetes che rappresenta un insieme di di pod identici. Un deployment esegue più repliche dei pod distribuiti tra i nodi di un cluster. Un deployment sostituisce automaticamente qualsiasi pod che non rispondono o non rispondono del tutto.
Servizio Kubernetes: l'esecuzione del codice dell'applicazione in GKE modifica la rete tra
loadgen
eserver
. Quando hai eseguito i servizi in una VM Cloud Shell, potevi inviare richieste aserver
utilizzando l'indirizzolocalhost:8080
. Dopo il deployment in GKE, i pod vengono pianificati per l'esecuzione sui nodi disponibili. Per impostazione predefinita, non puoi controllare su quale nodo è in esecuzione il pod, pertanto i pod non hanno indirizzi IP stabili.Per ottenere un indirizzo IP per
server
, devi definire una rete in cima ai pod, chiamata Servizio Kubernetes. Un servizio Kubernetes fornisce un endpoint di networking stabile per un insieme di pod. Esistono diversi tipi di Servizi.server
utilizza unLoadBalancer
, che espone un indirizzo IP esterno che puoi raggiungereserver
dall'esterno del cluster.Kubernetes ha anche un sistema DNS integrato, che assegna nomi DNS (ad ad esempio
helloserver.default.cluster.local
) ai Servizi. Ciò permette ai pod per raggiungere altri pod del cluster con un indirizzo stabile. Non puoi utilizzare questo nome DNS all'esterno del cluster, ad esempio da in Cloud Shell.
Manifest di Kubernetes
Quando hai eseguito l'applicazione dal codice sorgente, hai utilizzato un
comando imperativo: python3 server.py
Il linguaggio imperativo è basato sui verbi: "fai questo".
Al contrario, Kubernetes opera su una modello dichiarativo. Ciò significa che, invece di dire esattamente a Kubernetes cosa fare, Kubernetes con lo stato desiderato. Ad esempio, Kubernetes avvia e termina i pod secondo necessità, in modo che lo stato effettivo del sistema corrisponda a quello desiderato.
Puoi specificare lo stato desiderato in un insieme di manifest. YAML. Un file YAML contiene la specifica per uno o più oggetti Kubernetes.
L'esempio contiene un file YAML per server
e loadgen
. Ogni codice YAML
specifica lo stato desiderato per l'oggetto Kubernetes Deployment
assistenza.
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. Incluso nel specifica per i pod è il campoimage
, ovvero il nome l'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 dall'esterno del cluster.targetPort
: ricorda che il comandoEXPOSE 8080
inDockerfile
non espone effettivamente alcuna porta. Esponi la porta8080
in modo da poter raggiungere il contenitoreserver
all'esterno del cluster. In questo caso,hellosvc.default.cluster.local:80
(nome breve:hellosvc
) si mappa alla porta8080
dell'IP del podhelloserver
.port
: questo è il numero di porta utilizzato dagli altri servizi del cluster quando inviano richieste.
Generatore di carico
L'oggetto Deployment in loadgen.yaml
è simile a server.yaml
. Una differenza significativa è che l'oggetto Deployment contiene una sezione denominata env
. Questa
sezione definisce le variabili di ambiente richieste da loadgen
, che hai impostato
in precedenza quando hai eseguito l'applicazione dal codice sorgente.
Poiché loadgen
non accetta richieste in arrivo, il campo type
è impostato su ClusterIP
. Questo tipo fornisce un indirizzo IP stabile che può essere utilizzato dai servizi nel
cluster, ma l'indirizzo IP non è esposto ai client esterni.
Esegui il deployment dei container in GKE
Passa alla directory in cui si trova l'esempio
server
:cd YOUR_WORKING_DIRECTORY/anthos-service-mesh-samples/docs/helloserver/server/
Apri
server.yaml
in un editor di testo.Sostituisci il nome nel campo
image
con il nome dell'immagine Docker.image: gcr.io/PROJECT_ID/asm-ready/helloserver:v0.0.1
Sostituisci
PROJECT_ID
con l'ID del tuo progetto Google Cloud.Salva e chiudi
server.yaml
.Esegui il deployment del file YAML in Kubernetes:
kubectl apply -f server.yaml
Se l'operazione riesce, 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 dell'immagine Docker.image: gcr.io/PROJECT_ID/asm-ready/loadgen:v0.0.1
Sostituisci
PROJECT_ID
con il tuo progetto Google Cloud ID.Salva e chiudi
loadgen.yaml
, quindi chiudi l'editor di testo.Esegui il deployment del file YAML in Kubernetes:
kubectl apply -f loadgen.yaml
Se l'operazione riesce, 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
Recupera 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 tuohellosvc
.curl http://EXTERNAL_IP
Pronti per Cloud Service Mesh
Ora l'applicazione è stata dispiata in GKE. loadgen
puoi utilizzare il DNS di Kubernetes (hellosvc:80
) per inviare richieste a server
, e
puoi inviare richieste a server
con un indirizzo IP esterno. Sebbene
Kubernetes offre molte funzionalità. Alcune informazioni sui servizi
mancanti:
- In che modo i servizi interagiscono? Qual è la relazione tra i servizi? Come avviene il flusso di traffico tra i servizi? Sai che le
loadgen
invia richieste alserver
, ma immagina che tu non abbia familiarità con l'applicazione. Non puoi rispondere a queste domande guardando il dei pod in esecuzione su GKE. - Metriche: quanto tempo impiega
server
per rispondere alle richieste in arrivo? Quante richieste al secondo (RPS) vengono inviate aserver
? Ci sono risposte di errore? - Informazioni sulla sicurezza: il traffico tra
loadgen
eserver
è in testo normaleHTTP
o mTLS?
Cloud Service Mesh può fornire risposte a queste domande. Cloud Service Mesh è una versione gestita da Google Cloud del progetto open source Istio. Cloud 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 delle applicazioni. Questo
significa che server
e loadgen
ricevono ciascuno un proxy sidecar Envoy e tutti
il traffico da loadgen
a server
è mediato dai proxy Envoy. Le connessioni tra questi proxy Envoy costituiscono il mesh di servizi. Questo servizio
architettura mesh fornisce un livello di controllo su Kubernetes.
Poiché i proxy Envoy vengono eseguiti nei propri container, puoi installare Cloud Service Mesh su un cluster GKE senza modifiche sostanziali al codice dell'applicazione. Tuttavia, esistono alcuni modi chiave per preparare l'applicazione in modo che possa essere strumentata con Cloud Service Mesh:
- Servizi per tutti i container: sia i deployment
server
sialoadgen
hanno un servizio Kubernetes collegato. Ancheloadgen
, che non riceve richieste in entrata, ha un servizio. - Le porte nei servizi devono essere denominate: anche se GKE ti consente di definire porte di servizio senza nome, Cloud Service Mesh richiede che tu fornisca un nome per una porta corrispondente al protocollo della porta. Nel file YAML, la porta per
server
è denominatahttp
perchéserver
utilizza il protocollo di comunicazioneHTTP
. Seservice
utilizzagRPC
, la porta deve essere denominatagrpc
. - I deployment sono etichettati: questo consente di utilizzare la gestione del traffico di Cloud Service Mesh come la suddivisione del traffico tra le versioni dello stesso servizio.
Installa Cloud Service Mesh
Consulta la guida all'installazione di Cloud Service Mesh e segui le istruzioni per installare Cloud Service Mesh sul 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 comporta l'eliminazione di tutte le risorse che lo compongono, ad esempio 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 base di Kubernetes: