
Istio è uno strumento pratico per connettere, proteggere e monitorare applicazioni distribuite. In Istio vengono utilizzate diverse tecnologie per l'esecuzione su scala di software e la sua gestione, inclusi i contenitori per impacchettare il codice dell'applicazione e le dipendenze per il deployment e Kubernetes, per gestire questi contenitori. Pertanto, per lavorare con Istio, dovete sapere come funziona un'applicazione basata su servizi multipli utilizzando queste tecnologie. senza Istio. Se questi strumenti e concetti vi sono già familiari, sentitevi liberi di saltare questa guida e passare direttamente alla sezione. o installazione dell'estensione. .
Questa è una guida passo passo, in cui esamineremo l'intero processo dal codice sorgente al contenitore su GKE, per darvi una base per comprendere queste tecnologie attraverso un esempio. Vedrete anche come Istio sfrutta le capacità di queste tecnologie. Si presume che non sappiate nulla riguardo ai contenitori, Kubernetes, service mesh o Istio.
Problemi
In questa guida eseguirete le seguenti attività:
- Esplorare una semplice applicazione hello world con più servizi.
- Eseguire l'applicazione dal codice sorgente.
- Imballare l'applicazione in contenitori.
- Creare un cluster Kubernetes.
- Distribuire i contenitori nel cluster.
Prima di iniziare
Seguite le istruzioni per abilitare l'API di Kubernetes Engine:
- Visitate la nella console di Google Cloud Platform.
- Create o selezionate un progetto.
- Aspettate che l'API e i servizi correlati vengano abilitati. Questo potrebbe richiedere alcuni minuti.
- Assicuratevi che la fatturazione sia attivata per il progetto Google Cloud Platform. .
In questa guida potete utilizzare Cloud Shell, che prepara una macchina virtuale con Linux basato su Debian, o un computer con Linux o macOS.
Opzione A: utilizzo di Cloud Shell
Vantaggi dell'utilizzo di Cloud Shell:
- Ambienti di sviluppo per Python 2 e Python 3 (incluso virtualenv) completamente configurati.
- Gli strumenti della riga di comando gcloud, docker, git e kubectl, che utilizzeremo, sono già installati.
- Hai a disposizione diversi :
- , che si apre con l'icona di modifica nella parte superiore della finestra di Cloud Shell.
- Emacs, Vim o Nano, che si aprono dalla riga di comando in Cloud Shell.
Per utilizzare :
- Visitate la console di GCP.
- Fate clic sul pulsante Attiva Cloud Shell (Attivare Cloud Shell) nella parte superiore della finestra della console GCP.
![]()
Nella parte inferiore si aprirà una sessione Cloud Shell con la riga di comando in una nuova finestra.

Opzione B: utilizzo degli strumenti da riga di comando localmente
Se lavori su un computer con Linux o macOS, devi configurare e installare i seguenti componenti:
Configura .
con lo strumento da riga di comando gcloud.
Installare kubectl — lo strumento da riga di comando per lavorare con .
gcloud components install kubectlInstallare . Userai lo strumento da riga di comando docker, per creare immagini dei contenitori per l'esempio dell'applicazione.
Installa lo strumento , per ottenere l'esempio dell'applicazione da GitHub.
Download dell'esempio di codice
Scarica il codice sorgente helloserver:
git clone https://github.com/GoogleCloudPlatform/istio-samplesPassa alla cartella dell'esempio di codice:
cd istio-samples/sample-apps/helloserver
Esplorare l'applicazione con più servizi
L'esempio di applicazione è scritto in Python e consiste in due componenti che interagiscono tramite :
- server: un semplice server con un endpoint GET, /, che restituisce 'hello world' nella console.
- loadgen: uno script che invia traffico a server, con un numero configurabile di richieste al secondo.

Eseguire l'applicazione dal codice sorgente
Per esplorare l'esempio di applicazione, eseguilo in Cloud Shell o sul computer.
1) Nella cartella istio-samples/sample-apps/helloserver esegui server:
python3 server/server.pyQuando viene avviato server viene visualizzato il seguente:
INFO:root:Avvio server...2) Apri un'altra finestra del terminale per inviare richieste a server. Se utilizzi Cloud Shell, fai clic sull'icona aggiungi per aprire un'altra sessione.
3) Invia una richiesta a server:
curl http://localhost:8080il server risponde:
Hello World!4) Nella cartella in cui hai scaricato l'esempio di codice, passa alla cartella che contiene loadgen:
cd YOUR_WORKING_DIRECTORY/istio-samples/sample-apps/helloserver/loadgen5) Crea le seguenti variabili di ambiente:
export SERVER_ADDR=http://localhost:8080
export REQUESTS_PER_SECOND=56) Esegui virtualenv:
virtualenv --python python3 env7) Attiva l'ambiente virtuale:
source env/bin/activate8) Installa i requisiti per loadgen:
pip3 install -r requirements.txt9) Esegui loadgen:
python3 loadgen.pyQuando viene avviato loadgen restituisce un messaggio simile a questo:
Avvio loadgen: 2019-05-20 10:44:12.448415
5 richiesta(e) completate a http://localhost:8080In un'altra finestra del terminale server restituisce nella console messaggi simili a questi:
127.0.0.1 - - [21/Giu/2019 14:22:01] "GET / HTTP/1.1" 200 -
INFO:root:Richiesta GET,
Path: /
Headers:
Host: localhost:8080
User-Agent: python-requests/2.22.0
Accept-Encoding: gzip, deflate
Accept: */*Dal punto di vista della rete, l'intera applicazione funziona su un unico host (computer locale o macchina virtuale Cloud Shell). Pertanto, è possibile utilizzare localhost, per inviare richieste a server.
10) Per fermare loadgen e server, digita Ctrl-c in ogni finestra del terminale.
11) Nella finestra del terminale loadgen disattiva l'ambiente virtuale:
deactivateContenere l'applicazione in contenitori
Per eseguire l'applicazione su GKE, è necessario contenere l'esempio dell'applicazione — server e loadgen — in . Un contenitore è un modo per imballare un'applicazione in modo da isolarla dall'ambiente.
Per imballare l'applicazione in un contenitore, è necessario Dockerfile. Dockerfile — un file di testo che definisce i comandi per costruire il codice sorgente dell'applicazione e le sue dipendenze in Dopo la costruzione, carichi l'immagine in un registro di contenitori, ad esempio Docker Hub o .
Nell'esempio ci sono già Dockerfile per server e loadgen con tutti i comandi necessari per costruire le immagini. Di seguito — Dockerfile per server:
FROM python:3-slim as base
FROM base as builder
RUN apt-get -qq update
&& apt-get install -y --no-install-recommends
g++
&& rm -rf /var/lib/apt/lists/*
# Abilita il logging non bufferizzato
FROM base as final
ENV PYTHONUNBUFFERED=1
RUN apt-get -qq update
&& apt-get install -y --no-install-recommends
wget
WORKDIR /helloserver
# Ottieni i pacchetti dal builder
COPY --from=builder /usr/local/lib/python3.7/ /usr/local/lib/python3.7/
# Aggiungi l'applicazione
COPY . .
EXPOSE 8080
ENTRYPOINT [ "python", "server.py" ]- Team FROM python:3-slim as base consente a Docker di utilizzare l'ultimo come base.
- Team COPY. . copia i file sorgente nella directory di lavoro corrente (in questo caso solo server.py) nel file system del contenitore.
- ENTRYPOINT definisce il comando che viene utilizzato per avviare il contenitore. In questo caso, questo comando è quasi identico a quello che hai usato per eseguire server.py dal codice sorgente.
- Team EXPOSE indica che server si aspetta dati attraverso la porta 8080. Questo comando non . È qualcosa di simile alla documentazione necessaria per aprire la porta 8080 al momento dell'avvio del contenitore.
Preparazione alla containerizzazione dell'applicazione
1) Imposta le seguenti variabili ambientali. Sostituisci PROJECT_ID con l'identificativo del tuo progetto GCP.
export PROJECT_ID="PROJECT_ID"export GCR_REPO="preparing-istio"Con i valori PROJECT_ID e GCR_REPO etichetti l'immagine Docker quando la costruisci e la invii al registro Container privato.
2) Imposta il progetto GCP predefinito per lo strumento da riga di comando gcloud.
gcloud config set project $PROJECT_ID3) Imposta la zona predefinita per lo strumento da riga di comando gcloud.
gcloud config set compute/zone us-central1-b4) Assicurati che il servizio Container Registry sia abilitato nel progetto GCP.
gcloud services enable containerregistry.googleapis.comContenitorizzazione server
Vai alla cartella in cui si trova l'esempio server:
cd YOUR_WORKING_DIRECTORY/istio-samples/sample-apps/helloserver/server/Crea l'immagine usando Dockerfile e le variabili di ambiente che hai definito in precedenza:
docker build -t gcr.io/$PROJECT_ID/$GCR_REPO/helloserver:v0.0.1 .
Parametro -t rappresenta il tag Docker. È il nome dell'immagine che utilizzi per il deployment del contenitore.
- Spedisci l'immagine nel Container Registry:
docker push gcr.io/$PROJECT_ID/$GCR_REPO/helloserver:v0.0.1
Contenitorizzazione loadgen
1) Vai alla cartella in cui si trova l'esempio loadgen:
cd ../loadgen2) Crea l'immagine:
docker build -t gcr.io/$PROJECT_ID/$GCR_REPO/loadgen:v0.0.1 .3) Spedisci l'immagine nel Container Registry:
docker push gcr.io/$PROJECT_ID/$GCR_REPO/loadgen:v0.0.1Visualizzazione dell'elenco delle immagini
Controlla l'elenco delle immagini nel repository e assicurati che le immagini siano state spedite:
gcloud container images list --repository gcr.io/$PROJECT_ID/preparing-istioIl comando restituisce i nomi delle immagini appena spedite:
NOME
gcr.io/PROJECT_ID/preparing-istio/helloserver
gcr.io/PROJECT_ID/preparing-istio/loadgenCreazione del cluster GKE.
Questi contenitori potrebbero essere eseguiti su una macchina virtuale Cloud Shell o sul computer con il comando docker run. Ma in un ambiente di produzione è necessario un modo per orchestrare centralmente i contenitori. Ad esempio, è necessaria un sistema che monitora affinché i contenitori siano sempre operativi e c'è bisogno di un modo per scalare e avviare istanze aggiuntive di contenitori se il traffico aumenta.
Per eseguire applicazioni containerizzate è possibile utilizzare . GKE è una piattaforma di orchestrazione dei contenitori che raggruppa macchine virtuali in un cluster. Ogni macchina virtuale è chiamata nodo. I cluster GKE si basano sul sistema di gestione dei cluster open source Kubernetes. Kubernetes fornisce meccanismi di interazione con il cluster.
Creazione del cluster GKE:
1) Crea un cluster:
gcloud container clusters create istioready
--cluster-version latest
--machine-type=n1-standard-2
--num-nodes 4Team gcloud crea un cluster istioready nel progetto GCP e nella zona di default che hai specificato. Per eseguire Istio, si consiglia di avere almeno 4 nodi e una macchina virtuale. .
Il comando impiega alcuni minuti per creare il cluster. Quando il cluster sarà pronto, il comando restituirà un messaggio simile .
2) Fornisci le credenziali allo strumento da riga di comando , in modo da poter gestire il cluster:
gcloud container clusters get-credentials istioready3) Ora puoi interagire con Kubernetes tramite kubectl. Ad esempio, con il seguente comando puoi verificare lo stato dei nodi:
kubectl get nodesIl comando restituisce l'elenco dei nodi:
NOME STATO RUOLI ETÀ VERSIONE
gke-istoready-default-pool-dbeb23dc-1vg0 Pronto 99s v1.13.6-gke.13
gke-istoready-default-pool-dbeb23dc-36z5 Pronto 100s v1.13.6-gke.13
gke-istoready-default-pool-dbeb23dc-fj7s Pronto 99s v1.13.6-gke.13
gke-istoready-default-pool-dbeb23dc-wbjw Pronto 99s v1.13.6-gke.13Concetti chiave di Kubernetes
Lo schema mostra un'applicazione su GKE:

Prima di distribuire contenitori in GKE, studia i concetti chiave di Kubernetes. In fondo ci sono collegamenti, se vuoi saperne di più.
- Nodi e cluster. In GKE, un nodo è una macchina virtuale. Su altre piattaforme, un nodo di Kubernetes può essere un computer o una macchina virtuale. Un cluster è un insieme di nodi che possono essere considerati un'unica entità in cui distribuisci l'applicazione containerizzata.
- Pod. In Kubernetes, i contenitori vengono eseguiti all'interno dei pod. Un pod in Kubernetes è un'unità indivisibile. Un pod contiene uno o più contenitori. Distribuisci i contenitori server e loadgen in pod separati. Quando ci sono più contenitori in un pod (ad esempio, il server dell'applicazione e ), i contenitori vengono gestiti come un'unica entità e condividono le risorse del pod.
- Distribuzioni. In Kubernetes, una distribuzione è un oggetto che rappresenta un insieme di pod identici. Una distribuzione avvia più repliche di pod distribuite sui nodi del cluster. La distribuzione sostituisce automaticamente i pod che hanno fallito o non rispondono.
- Servizio Kubernetes. Quando esegui il codice di un'applicazione su GKE, la connessione tra loadgen e server. Quando hai avviato i servizi su una macchina virtuale Cloud Shell o sul computer, inviavi richieste a server all'indirizzo localhost:8080. Dopo la distribuzione in GKE, i pod vengono eseguiti su nodi disponibili. Di default, non puoi gestire su quale nodo è in esecuzione un pod, quindi i non hanno indirizzi IP permanenti.
Per ottenere un indirizzo IP per server, devi definire un'astrazione di rete sopra i pod. Questo è . Il servizio Kubernetes fornisce un endpoint permanente per un insieme di pod. Ci sono diversi . server utilizza LoadBalancer, che forniscono un indirizzo IP esterno per connettersi a server dall'esterno del cluster.
Inoltre, Kubernetes ha un sistema DNS integrato che assegna nomi DNS (ad esempio, helloserver.default.cluster.local) servizi. Grazie a questo, i pod all'interno del cluster si collegano ad altri pod nel cluster tramite un indirizzo permanente. Il nome DNS non può essere utilizzato al di fuori del cluster, ad esempio in Cloud Shell o su un computer.
Manifesti Kubernetes
Quando hai avviato l'applicazione dal codice sorgente, hai utilizzato un comando imperativo python3
server.py
L'imperatività implica un verbo: «fai questo».
Kubernetes utilizza . Questo significa che non diciamo a Kubernetes cosa fare, ma descriviamo lo stato desiderato. Ad esempio, Kubernetes avvia e ferma i pod secondo necessità affinché lo stato attuale del sistema corrisponda a quello desiderato.
Lo stato desiderato lo indichi nei manifesti, o file . Il file YAML contiene specifiche per uno o più oggetti Kubernetes.
Nell'esempio è presente un file YAML per server e loadgen. Ogni file YAML specifica lo stato desiderato dell'oggetto di distribuzione e del servizio Kubernetes.
server.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloserver
spec:
selector:
matchLabels:
app: helloserver
replicas: 1
template:
metadata:
labels:
app: helloserver
spec:
terminationGracePeriodSeconds: 5
restartPolicy: Always
containers:
- name: main
image: gcr.io/google-samples/istio/helloserver:v0.0.1
imagePullPolicy: Always- tipo indica il tipo di oggetto.
- metadata.name indica il nome della distribuzione.
- Il primo campo spec contiene la descrizione dello stato desiderato.
- spec.replicas indica il numero desiderato di pod.
- La sezione spec.template definisce il modello del pod. Nella specifica dei pod c'è un campo image, dove si indica il nome dell'immagine da estrarre dal Container Registry.
Il servizio è definito come segue:
apiVersion: v1
kind: Service
metadata:
name: hellosvc
spec:
type: LoadBalancer
selector:
app: helloserver
ports:
- name: http
port: 80
targetPort: 8080- LoadBalancer: i client inviano richieste all'indirizzo IP del bilanciatore di carico, che ha un indirizzo IP permanente ed è accessibile dall'esterno del cluster.
- targetPort: come ricordate, il comando EXPOSE 8080 in Dockerfile non ha fornito porte. Si fornisce una porta 8080, per poter contattare il contenitore server dall'esterno del cluster. Nel nostro caso hellosvc.default.cluster.local:80 (nome breve: hellosvc) corrisponde alla porta 8080 l'indirizzo IP del pod helloserver.
- port: è il numero di porta a cui gli altri servizi nel cluster invieranno richieste.
loadgen.yaml
L'oggetto di distribuzione in loadgen.yaml è simile a server.yaml. La differenza è che l'oggetto di distribuzione contiene la sezione env. Essa definisce le variabili ambiente necessarie loadgen e che hai impostato all'avvio dell'applicazione dal codice sorgente.
apiVersion: apps/v1
kind: Deployment
metadata:
name: loadgenerator
spec:
selector:
matchLabels:
app: loadgenerator
replicas: 1
template:
metadata:
labels:
app: loadgenerator
spec:
terminationGracePeriodSeconds: 5
restartPolicy: Always
containers:
- name: main
image: gcr.io/google-samples/istio/loadgen:v0.0.1
imagePullPolicy: Always
env:
- name: SERVER_ADDR
value: "http://hellosvc:80/"
- name: REQUESTS_PER_SECOND
value: "10"
resources:
requests:
cpu: 300m
memory: 256Mi
limits:
cpu: 500m
memory: 512MiUna loadgen non accetta richieste in entrata, per il campo type specificato ClusterIP. Questo tipo fornisce un indirizzo IP statico che può essere utilizzato dai servizi nel cluster, ma questo indirizzo IP non è fornito ai client esterni.
apiVersion: v1
kind: Service
metadata:
name: loadgensvc
spec:
type: ClusterIP
selector:
app: loadgenerator
ports:
- name: http
port: 80
targetPort: 8080Distribuzione dei container in GKE
1) Vai alla cartella in cui si trova l'esempio server:
cd YOUR_WORKING_DIRECTORY/istio-samples/sample-apps/helloserver/server/2) Apri server.yaml in un editor di testo.
3) Sostituisci il nome nel campo image con il nome della tua immagine Docker.
image: gcr.io/PROJECT_ID/preparing-istio/helloserver:v0.0.1Sostituisci PROJECT_ID con l'ID del tuo progetto GCP.
4) Salva e chiudi server.yaml.
5) Distribuisci il file YAML in Kubernetes:
kubectl apply -f server.yamlDopo un esito positivo, il comando restituisce il seguente codice:
deployment.apps/helloserver created
service/hellosvc created6) Vai nella cartella dove si trova loadgen:
cd ../loadgen7) Apri loadgen.yaml in un editor di testo.
8) Sostituisci il nome nel campo image con il nome della tua immagine Docker.
image: gcr.io/PROJECT_ID/preparing-istio/loadgenv0.0.1Sostituisci PROJECT_ID con l'ID del tuo progetto GCP.
9) Salva e chiudi loadgen.yaml, chiudi l'editor di testo.
10) Distribuisci il file YAML in Kubernetes:
kubectl apply -f loadgen.yamlDopo un esito positivo, il comando restituisce il seguente codice:
deployment.apps/loadgenerator created
service/loadgensvc created11) Controlla lo stato dei pod:
kubectl get podsIl comando mostra lo stato:
NAME READY STATUS RESTARTS AGE
helloserver-69b9576d96-mwtcj 1/1 Running 0 58s
loadgenerator-774dbc46fb-gpbrz 1/1 Running 0 57s12) Estrai i log dell'app dal pod loadgen. Sostituisci POD_ID con l'ID della risposta precedente.
kubectl logs loadgenerator-POD_ID13) Ottieni gli indirizzi IP esterni hellosvc:
kubectl get serviceLa risposta del comando appare più o meno così:
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 443/TCP 93m
loadgensvc ClusterIP 10.81.15.155 80/TCP 4m52s14) Invia una richiesta a hellosvc: sostituisci EXTERNAL_IP con l'indirizzo IP esterno hellosvc.
curl http://EXTERNAL_IPPassiamo a Istio
Hai già un'applicazione distribuita in GKE. loadgen può utilizzare il DNS di Kubernetes (hellosvc:80), per inviare richieste a server, e puoi inviare richieste all'indirizzo IP esterno. Sebbene Kubernetes abbia molte funzionalità, mancano alcune informazioni sui servizi: server tramite l'indirizzo IP esterno. Sebbene Kubernetes abbia molte caratteristiche, manca di alcune informazioni sui servizi:
- Come interagiscono i servizi? Quali sono le relazioni tra i servizi? Come avviene il traffico tra i servizi? Sei a conoscenza che loadgen invia richieste a server, ma immagina di non sapere nulla dell'applicazione. Per rispondere a queste domande, guardiamo l'elenco dei pod in esecuzione in GKE.
- Metriche. Quanto tempo server impiega a rispondere a una richiesta in ingresso? Quante richieste al secondo arrivano al server? Fornisce messaggi di errore?
- Informazioni sulla sicurezza. Il traffico tra loadgen e server passa semplicemente attraverso HTTP o attraverso ?
Tutte queste domande sono risposte da Istio. Per questo Istio inserisce un proxy sidecar in ogni pod. Il proxy Envoy intercetta tutto il traffico in ingresso e in uscita verso i contenitori dell'applicazione. Questo significa che server e loadgen ricevono tramite il proxy sidecar Envoy, e tutto il traffico da loadgen al server passa attraverso il proxy Envoy.
Le connessioni tra i proxy Envoy formano una rete di servizi. L'architettura della rete di servizi fornisce un livello di controllo sopra Kubernetes.

Poiché i proxy Envoy vengono eseguiti nei loro contenitori, Istio può essere installato sopra un cluster GKE senza dover modificare il codice dell'applicazione. Ma hai fatto un certo lavoro per preparare l'applicazione per la gestione tramite Istio:
- Servizi per tutti i contenitori. Ad ogni distribuzione server e loadgen è legato un servizio Kubernetes. Anche il loadgen, a cui non arrivano richieste in ingresso, ha un servizio.
- Le porte nei servizi devono avere nomi. Anche se in GKE le porte dei servizi possono essere senza nome, Istio richiede di specificare secondo il suo protocollo. Nel file YAML la porta per server si chiama http, perché il server utilizza il protocollo HTTP. Se service utilizzasse gRPC, dovresti chiamare la porta grpc.
- Le distribuzioni sono contrassegnate. Quindi puoi utilizzare le funzionalità di gestione del traffico di Istio, come la suddivisione del traffico tra le versioni di uno stesso servizio.
Installazione di Istio
Istio può essere installato in due modi. Puoi o sul cluster. Con Istio su GKE puoi gestire facilmente l'installazione e l'aggiornamento di Istio nell'ambito del ciclo di vita del cluster GKE. Se hai bisogno dell'ultima versione di Istio o di maggiore controllo sulla configurazione della dashboard di Istio, installa la versione open-source invece dell'estensione Istio su GKE. Per determinare il metodo, leggi l'articolo .
Seleziona un'opzione, studia la guida corrispondente e segui le istruzioni per installare Istio nel cluster. Se desideri utilizzare Istio con un'applicazione appena distribuita, per lo spazio dei nomi default.
Pulizia
Per evitare addebiti per le risorse utilizzate in questa guida dall'account Google Cloud Platform, elimina il cluster dei container una volta che hai installato Istio e hai esplorato l'esempio dell'applicazione. In questo modo verranno rimossi tutte le risorse del cluster, come le istanze di calcolo, i dischi e le risorse di rete.
Cosa succede dopo?
Studia le seguenti tecnologie:
Studia i seguenti strumenti:
Approfondisci i concetti di Kubernetes:
Fonte: habr.com
