Workshop su Anthos Service Mesh: guida del lab

1. ALPHA WORKSHOP

Link al codelab del workshop: bit.ly/asm-workshop

2. Panoramica

Diagramma dell'architettura

9a033157f44308f3.png

Questo workshop è un'esperienza pratica e coinvolgente che illustra come configurare i servizi distribuiti a livello globale su GCP in produzione. Le principali tecnologie utilizzate sono Google Kubernetes Engine (GKE) per il calcolo e Istio Service Mesh per creare connettività sicura, osservabilità e modellazione avanzata del traffico. Tutte le pratiche e gli strumenti utilizzati in questo workshop sono quelli che useresti in produzione.

Programma

  • Modulo 0 - Introduzione e configurazione della piattaforma
  • Introduzione e architettura
  • Introduzione a Service Mesh e Istio/ASM
  • Lab: Infrastructure Setup: User workflow
  • Break (Pausa)
  • QnA
  • Modulo 1 - Installare, proteggere e monitorare le applicazioni con ASM
  • Modello di repository: spiegazione dei repository di infrastruttura e Kubernetes
  • Lab: Deploy sample application
  • Servizi distribuiti e osservabilità
  • Pranzo
  • Lab: Observability with Stackdriver
  • QNA
  • Modulo 2 - DevOps - Implementazioni canary, policy/RBAC
  • Service Discovery e sicurezza/policy multi-cluster
  • Lab: Mutual TLS
  • Deployment canary
  • Lab: Canary Deployments
  • Bilanciamento del carico globale multicluster sicuro
  • Break (Pausa)
  • Lab: Authorization Policy
  • QNA
  • Modulo 3 - Infra Ops - Platform upgrades
  • Componenti di base del servizio distribuito
  • Lab: Infrastructure Scaling
  • Passaggi successivi

Presentazioni

Le slide di questo workshop sono disponibili al seguente link:

Diapositive del workshop ASM

Prerequisiti

Prima di procedere con questo workshop, devi disporre di quanto segue:

  1. Un nodo organizzazione Google Cloud
  2. Un ID account di fatturazione (il tuo utente deve essere amministratore della fatturazione per questo account di fatturazione)
  3. Ruolo IAM Amministratore dell'organizzazione a livello di organizzazione per l'utente

3. Configurazione dell'infrastruttura - Workflow amministrativo

Spiegazione dello script del workshop sul bootstrap

Uno script denominato bootstrap_workshop.sh viene utilizzato per configurare l'ambiente iniziale per il workshop. Puoi utilizzare questo script per configurare un singolo ambiente per te o più ambienti per più utenti nel caso in cui tu stia tenendo questo workshop come formazione per più utenti.

Lo script dell'officina di bootstrap richiede i seguenti input:

  • Nome dell'organizzazione (ad esempio yourcompany.com): l'organizzazione in cui crei gli ambienti per il workshop.
  • ID fatturazione (ad esempio 12345-12345-12345): questo ID fatturazione viene utilizzato per fatturare tutte le risorse utilizzate durante il workshop.
  • Numero di officina (ad esempio 01): un numero di due cifre. Viene utilizzato se tieni più workshop in un giorno e vuoi monitorarli separatamente. I numeri dei workshop vengono utilizzati anche per derivare gli ID progetto. Avere numeri di workshop separati semplifica l'ottenimento di ID progetto univoci ogni volta. Oltre al numero del workshop, per gli ID progetto viene utilizzata anche la data attuale (nel formato YYMMDD). La combinazione di data e numero del workshop fornisce ID progetto univoci.
  • Numero utente iniziale (ad esempio 1): questo numero indica il primo utente del workshop. Ad esempio, se vuoi creare un workshop per 10 utenti, puoi impostare il numero di utenti iniziali su 1 e il numero di utenti finali su 10.
  • Numero utente finale (ad esempio 10): questo numero indica l'ultimo utente del workshop. Ad esempio, se vuoi creare un workshop per 10 utenti, puoi impostare il numero di utenti iniziali su 1 e il numero di utenti finali su 10. Se stai configurando un singolo ambiente (per te, ad esempio), imposta lo stesso numero di utenti iniziali e finali. In questo modo verrà creato un unico ambiente.
  • Bucket GCS amministratore (ad esempio my-gcs-bucket-name): un bucket GCS viene utilizzato per archiviare le informazioni relative al workshop. Queste informazioni vengono utilizzate dallo script cleanup_workshop.sh per eliminare correttamente tutte le risorse create durante lo script del workshop di bootstrap. Gli amministratori che creano workshop devono disporre delle autorizzazioni di lettura/scrittura per questo bucket.

Lo script bootstrap workshop utilizza i valori forniti sopra e funge da script wrapper che chiama lo script setup-terraform-admin-project.sh. Lo script setup-terraform-admin-project.sh crea l'ambiente del workshop per un singolo utente.

Autorizzazioni di amministratore richieste per l'avvio del workshop

In questo workshop esistono due tipi di utenti. Un ADMIN_USER, che crea ed elimina le risorse per questo workshop. Il secondo è MY_USER, che esegue i passaggi del workshop. MY_USER ha accesso solo alle proprie risorse. ADMIN_USER ha accesso a tutte le configurazioni utente. Se stai creando questa configurazione per te, ADMIN_USER e MY_USER sono uguali. Se sei un insegnante che crea questo workshop per più studenti, i valori di ADMIN_USER e MY_USER saranno diversi.

Per ADMIN_USER sono necessarie le seguenti autorizzazioni a livello di organizzazione:

  • Proprietario: autorizzazione di proprietario del progetto per tutti i progetti dell'organizzazione.
  • Amministratore cartelle: possibilità di creare ed eliminare cartelle nell'organizzazione. Ogni utente riceve una singola cartella con tutte le sue risorse all'interno del progetto.
  • Amministratore dell'organizzazione
  • Autore progetto: possibilità di creare progetti nell'organizzazione.
  • Eliminazione progetti: possibilità di eliminare i progetti nell'organizzazione.
  • Project IAM Admin: possibilità di creare regole IAM in tutti i progetti dell'organizzazione.

Oltre a questi, ADMIN_USER deve essere anche l'amministratore della fatturazione per l'ID fatturazione utilizzato per il workshop.

Schema e autorizzazioni utente che esegue il workshop

Se prevedi di creare questo workshop per utenti (diversi da te) della tua organizzazione, devi seguire uno schema di denominazione specifico per gli utenti per MY_USERs. Durante lo script bootstrap_workshop.sh, fornisci un numero di utenti iniziali e finali. Questi numeri vengono utilizzati per creare i seguenti nomi utente:

  • user<3 digit user number>@<organization_name>

Ad esempio, se esegui lo script del workshop di bootstrap con il numero di utenti iniziali pari a 1 e il numero di utenti finali pari a 3, nella tua organizzazione denominata tuaazienda.com vengono creati gli ambienti del workshop per i seguenti utenti:

  • user001@yourcompany.com
  • user002@yourcompany.com
  • user003@yourcompany.com

A questi nomi utente vengono assegnati ruoli di proprietario del progetto per i progetti specifici creati durante lo script setup_terraform_admin_project.sh. Quando utilizzi lo script di bootstrap, devi rispettare questo schema di denominazione degli utenti. Consulta come aggiungere più utenti contemporaneamente in G Suite.

Strumenti necessari per il workshop

Questo workshop è pensato per essere avviato da Cloud Shell. Per questo workshop sono necessari i seguenti strumenti.

  • gcloud (versione >= 270)
  • kubectl
  • sed (funziona con sed su Cloud Shell/Linux e non su Mac OS)
  • git (assicurati di avere l'ultima versione)
  • sudo apt update
  • sudo apt install git
  • jq
  • envsubst
  • kustomize

Configurare il workshop per te (configurazione per un singolo utente)

  1. Apri Cloud Shell ed esegui tutte le azioni riportate di seguito in Cloud Shell. Fai clic sul link di seguito.

CLOUD SHELL

  1. Verifica di aver eseguito l'accesso a gcloud con l'utente amministratore previsto.
gcloud config list
 
  1. Crea un WORKDIR e clona il repository del workshop.
mkdir asm-workshop
cd asm-workshop
export WORKDIR=`pwd`
git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-workshop.git asm
 
  1. Definisci il nome dell'organizzazione, l'ID fatturazione, il numero del workshop e un bucket GCS amministrativo da utilizzare per il workshop. Esamina le autorizzazioni necessarie per configurare il workshop nelle sezioni precedenti.
gcloud organizations list
export ORGANIZATION_NAME=<ORGANIZATION NAME>

gcloud beta billing accounts list
export ADMIN_BILLING_ID=<ADMIN_BILLING ID>

export WORKSHOP_NUMBER=<two digit number for example 01>

export ADMIN_STORAGE_BUCKET=<ADMIN CLOUD STORAGE BUCKET>
 
  1. Esegui lo script bootstrap_workshop.sh. Il completamento di questo script può richiedere alcuni minuti.
cd asm
./scripts/bootstrap_workshop.sh --org-name ${ORGANIZATION_NAME} --billing-id ${ADMIN_BILLING_ID} --workshop-num ${WORKSHOP_NUMBER} --admin-gcs-bucket ${ADMIN_STORAGE_BUCKET} --set-up-for-admin 
 

Al termine dello script bootstrap_workshop.sh, viene creata una cartella GCP per ogni utente all'interno dell'organizzazione. All'interno della cartella viene creato un progetto di amministrazione Terraform. Il progetto di amministrazione Terraform viene utilizzato per creare le restanti risorse GCP necessarie per questo workshop. Abilita le API richieste nel progetto amministratore Terraform. Utilizzi Cloud Build per applicare i piani Terraform. Concedi all'account di servizio Cloud Build i ruoli IAM appropriati per consentirgli di creare risorse su Google Cloud. Infine, configuri un backend remoto in un bucket Google Cloud Storage (GCS) per archiviare gli stati di Terraform per tutte le risorse GCP.

Per visualizzare le attività di Cloud Build nel progetto di amministrazione Terraform, devi disporre dell'ID progetto di amministrazione Terraform. Queste informazioni sono archiviate nel file vars/vars.sh nella directory asm. Questa directory viene mantenuta solo se configuri il workshop per te stesso in qualità di amministratore.

  1. Recupera il file delle variabili per impostare le variabili di ambiente
echo "export WORKDIR=$WORKDIR" >> $WORKDIR/asm/vars/vars.sh
source $WORKDIR/asm/vars/vars.sh 
 

Configurare il workshop per più utenti (configurazione multiutente)

  1. Apri Cloud Shell ed esegui tutte le azioni riportate di seguito in Cloud Shell. Fai clic sul link di seguito.

CLOUD SHELL

  1. Verifica di aver eseguito l'accesso a gcloud con l'utente amministratore previsto.
gcloud config list
 
  1. Crea un WORKDIR e clona il repository del workshop.
mkdir asm-workshop
cd asm-workshop
export WORKDIR=`pwd`
git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-workshop.git asm
 
  1. Definisci il nome dell'organizzazione, l'ID fatturazione, il numero del workshop, il numero di utenti iniziali e finali e un bucket GCS amministrativo da utilizzare per il workshop. Esamina le autorizzazioni necessarie per configurare il workshop nelle sezioni precedenti.
gcloud organizations list
export ORGANIZATION_NAME=<ORGANIZATION NAME>

gcloud beta billing accounts list
export ADMIN_BILLING_ID=<BILLING ID>

export WORKSHOP_NUMBER=<two digit number for example 01>

export START_USER_NUMBER=<number for example 1>

export END_USER_NUMBER=<number greater or equal to START_USER_NUM>

export ADMIN_STORAGE_BUCKET=<ADMIN CLOUD STORAGE BUCKET>
 
  1. Esegui lo script bootstrap_workshop.sh. Il completamento di questo script può richiedere alcuni minuti.
cd asm
./scripts/bootstrap_workshop.sh --org-name ${ORGANIZATION_NAME} --billing-id ${ADMIN_BILLING_ID} --workshop-num ${WORKSHOP_NUMBER} --start-user-num ${START_USER_NUMBER} --end-user-num ${END_USER_NUMBER} --admin-gcs-bucket ${ADMIN_STORAGE_BUCKET}
 
  1. Recupera il file workshop.txt dal bucket GCS dell'amministratore per recuperare gli ID progetto Terraform.
export WORKSHOP_ID="$(date '+%y%m%d')-${WORKSHOP_NUMBER}"
gsutil cp gs://${ADMIN_STORAGE_BUCKET}/${ORGANIZATION_NAME}/${WORKSHOP_ID}/workshop.txt .
 

4. Configurazione e preparazione del lab

Scegliere il percorso del lab

I lab di questo workshop possono essere eseguiti in due modi:

  • Il metodo "easy fast track interactive scripts"
  • Il metodo "copia e incolla manuale di ogni istruzione"

Il metodo degli script di traccia rapida ti consente di eseguire un singolo script interattivo per ogni lab che ti guida attraverso il lab eseguendo automaticamente i comandi per quel lab. I comandi vengono eseguiti in batch con spiegazioni concise di ogni passaggio e di ciò che realizzano. Dopo ogni batch, ti viene chiesto di passare al batch di comandi successivo. In questo modo, puoi eseguire i lab al tuo ritmo. Gli script di fast track sono idempotenti, il che significa che puoi eseguirli più volte ottenendo lo stesso risultato.

Gli script di fast track vengono visualizzati nella parte superiore di ogni lab in una casella verde, come mostrato di seguito.

Il metodo copia e incolla è il modo tradizionale di copiare e incollare singoli blocchi di comandi con spiegazioni. Questo metodo deve essere eseguito una sola volta. Non è garantito che l'esecuzione ripetuta dei comandi con questo metodo produca gli stessi risultati.

Quando esegui i lab, scegli uno dei due metodi.

Configurazione dello script Fast Track

Ottieni informazioni utente

Questo workshop viene eseguito utilizzando un account utente temporaneo (o un account lab) creato dall'amministratore del workshop. L'account lab è proprietario di tutti i progetti del workshop. L'amministratore del workshop fornisce le credenziali dell'account lab (nome utente e password) all'utente che esegue il workshop. Tutti i progetti dell'utente sono preceduti dal nome utente dell'account lab. Ad esempio, per l'account lab user001@yourcompany.com, l'ID progetto amministratore di Terraform sarebbe user001-200131-01-tf-abcde e così via per il resto dei progetti. Ogni utente deve accedere con l'account lab fornito dall'amministratore del workshop ed eseguire il workshop utilizzando l'account lab.

  1. Apri Cloud Shell facendo clic sul link di seguito.

CLOUD SHELL

  1. Accedi con le credenziali dell'account del lab (non accedere con il tuo account aziendale o personale). L'account lab ha il seguente aspetto: userXYZ@<workshop_domain>.com. 3101eca1fd3722bf.png
  2. Poiché si tratta di un nuovo account, ti viene chiesto di accettare i Termini di servizio di Google. Fai clic su Accetta.

fb0219a89ece5168.png 4. Nella schermata successiva, seleziona la casella di controllo per accettare i Termini di servizio di Google e fai clic su Start Cloud Shell.

7b198cf2e32cb457.png

Questo passaggio esegue il provisioning di una piccola VM Linux Debian da utilizzare per accedere alle risorse Google Cloud. Ogni account riceve una VM Cloud Shell. L'accesso con il provisioning dell'account lab ti consente di accedere utilizzando le credenziali dell'account lab. Oltre a Cloud Shell, viene eseguito il provisioning anche di un editor di codice, che semplifica la modifica dei file di configurazione (terraform, YAML e così via). Per impostazione predefinita, lo schermo di Cloud Shell è diviso nell'ambiente shell di Cloud Shell (in basso) e nell'editor Cloud Code (in alto). 5643bb4ebeafd00a.png Le icone della matita 8bca25ef1421c17e.png e del prompt della shell eaeb4ac333783ba8.png nell'angolo in alto a destra ti consentono di passare da una all'altra (shell ed editor di codice). Puoi anche trascinare la barra di separazione centrale (verso l'alto o verso il basso) e modificare manualmente le dimensioni di ogni finestra. 5. Crea una WORKDIR per questo workshop. WORKDIR è una cartella da cui esegui tutti i lab di questo workshop. Esegui questi comandi in Cloud Shell per creare WORKDIR.

mkdir -p ${HOME}/asm-workshop
cd ${HOME}/asm-workshop
export WORKDIR=`pwd` 
 
  1. Esporta l'utente dell'account lab come variabile da utilizzare per questo workshop. Si tratta dello stesso account con cui hai eseguito l'accesso a Cloud Shell.
export MY_USER=<LAB ACCOUNT EMAIL PROVIDED BY THE WORKSHOP ADMIN>
# For example export MY_USER=user001@gcpworkshops.com 
 
  1. Esegui l'echo delle variabili WORKDIR e MY_USER per assicurarti che siano impostate correttamente eseguendo i seguenti comandi.
echo "WORKDIR set to ${WORKDIR}" && echo "MY_USER set to ${MY_USER}"
 
  1. Clona il repository del workshop.
git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-workshop.git ${WORKDIR}/asm
 

5. Configurazione dell'infrastruttura - Workflow utente

Obiettivo: verifica l'infrastruttura e l'installazione di Istio

  • Installare gli strumenti per il workshop
  • Clona il repository del workshop
  • Verifica l'installazione di Infrastructure
  • Verifica l'installazione di k8s-repo
  • Verifica l'installazione di Istio

Istruzioni per il lab sul metodo di copia e incolla

Ottieni informazioni utente

L'amministratore che configura il workshop deve fornire all'utente le informazioni su nome utente e password. Tutti i progetti dell'utente avranno come prefisso il nome utente, ad esempio per l'utente user001@yourcompany.com, l'ID progetto amministratore Terraform sarà user001-200131-01-tf-abcde e così via per il resto dei progetti. Ogni utente ha accesso solo al proprio ambiente di laboratorio.

Strumenti necessari per il workshop

Questo workshop è pensato per essere avviato da Cloud Shell. Per questo workshop sono necessari i seguenti strumenti.

  • gcloud (versione >= 270)
  • kubectl
  • sed (funziona con sed su Cloud Shell/Linux e non su Mac OS)
  • git (assicurati di avere l'ultima versione)
  • sudo apt update
  • sudo apt install git
  • jq
  • envsubst
  • kustomize
  • pv

Accedi al progetto amministrativo Terraform

Al termine dello script bootstrap_workshop.sh, viene creata una cartella GCP per ogni utente all'interno dell'organizzazione. All'interno della cartella viene creato un progetto di amministrazione Terraform. Il progetto di amministrazione Terraform viene utilizzato per creare le restanti risorse GCP necessarie per questo workshop. Lo script setup-terraform-admin-project.sh abilita le API richieste nel progetto amministratore di Terraform. Cloud Build viene utilizzato per applicare i piani Terraform. Tramite lo script, concedi all'account di servizio Cloud Build i ruoli IAM appropriati per consentirgli di creare risorse su Google Cloud. Infine, un backend remoto viene configurato in un bucket Google Cloud Storage (GCS) per archiviare gli stati di Terraform per tutte le risorse GCP.

Per visualizzare le attività di Cloud Build nel progetto di amministrazione Terraform, devi disporre dell'ID progetto di amministrazione Terraform. Queste informazioni vengono archiviate nel bucket GCS di amministrazione specificato nello script di bootstrap. Se esegui lo script di bootstrap per più utenti, tutti gli ID progetto amministratore di Terraform si trovano nel bucket GCS.

  1. Apri Cloud Shell (se non è già aperta dalla sezione Configurazione e preparazione del lab) facendo clic sul link di seguito.

CLOUD SHELL

  1. Installa kustomize (se non è già installato) nella cartella $HOME/bin e aggiungi la cartella $HOME/bin a $PATH.
mkdir -p $HOME/bin
cd $HOME/bin
curl -s "https://raw.githubusercontent.com/\
kubernetes-sigs/kustomize/master/hack/install_kustomize.sh"  | bash
cd $HOME
export PATH=$PATH:${HOME}/bin
echo "export PATH=$PATH:$HOME/bin" >> $HOME/.bashrc
 
  1. Installa pv e spostalo in $HOME/bin/pv.
sudo apt-get update && sudo apt-get -y install pv
sudo mv /usr/bin/pv ${HOME}/bin/pv
 
  1. Aggiorna il prompt di Bash.
cp $WORKDIR/asm/scripts/krompt.bash $HOME/.krompt.bash
echo "export PATH=\$PATH:\$HOME/bin" >> $HOME/.asm-workshop.bash
echo "source $HOME/.krompt.bash" >> $HOME/.asm-workshop.bash

alias asm-init='source $HOME/.asm-workshop.bash' >> $HOME/.bashrc
echo "source $HOME/.asm-workshop.bash" >> $HOME/.bashrc
source $HOME/.bashrc
 
  1. Verifica di aver eseguito l'accesso a gcloud con l'account utente previsto.
echo "Check logged in user output from the next command is $MY_USER"
gcloud config list account --format=json | jq -r .core.account
 
  1. Recupera l'ID progetto amministrativo Terraform eseguendo questo comando:
export TF_ADMIN=$(gcloud projects list | grep tf- | awk '{ print $1 }')
echo $TF_ADMIN
 
  1. Tutte le risorse associate al workshop vengono archiviate come variabili in un file vars.sh memorizzato in un bucket GCS nel progetto amministrativo Terraform. Ottieni il file vars.sh per il progetto di amministrazione Terraform.
mkdir $WORKDIR/asm/vars
gsutil cp gs://$TF_ADMIN/vars/vars.sh $WORKDIR/asm/vars/vars.sh
echo "export WORKDIR=$WORKDIR" >> $WORKDIR/asm/vars/vars.sh
 
  1. Fai clic sul link visualizzato per aprire la pagina Cloud Build per il progetto amministrativo Terraform e verificare che la build sia stata completata correttamente.
source $WORKDIR/asm/vars/vars.sh
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_ADMIN}"
 

Se accedi alla console Cloud per la prima volta, accetta i Termini di servizio di Google.

  1. Ora che visualizzi la pagina Cloud Build, fai clic sul link History nel menu di navigazione a sinistra e poi sull'ultima build per visualizzare i dettagli dell'applicazione Terraform iniziale. Le seguenti risorse vengono create nell'ambito dello script Terraform. Puoi anche fare riferimento al diagramma dell'architettura riportato sopra.
  • 4 progetti Google Cloud nell'organizzazione. L'account di fatturazione fornito è associato a ogni progetto.
  • Un progetto è il network host project per il VPC condiviso. In questo progetto non vengono create altre risorse.
  • Un progetto è ops project utilizzato per i cluster GKE del control plane Istio.
  • Due progetti rappresentano due diversi team di sviluppo che lavorano sui rispettivi servizi.
  • Vengono creati due cluster GKE in ciascuno dei tre progetti ops, dev1 e dev2.
  • Viene creato un repository CSR denominato k8s-repo che contiene sei cartelle per i file manifest di Kubernetes. Una cartella per cluster GKE. Questo repository viene utilizzato per eseguire il deployment dei manifest Kubernetes nei cluster in stile GitOps.
  • Viene creato un trigger Cloud Build in modo che ogni volta che viene eseguito un commit nel ramo master di k8s-repo, i manifest Kubernetes vengano sottoposti a deployment nei cluster GKE dalle rispettive cartelle.
  1. Una volta completata la build in terraform admin project, ne verrà avviata un'altra nel progetto ops. Fai clic sul link visualizzato per aprire la pagina Cloud Build per ops project e verifica che la build di k8s-repo sia stata completata correttamente.
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_VAR_ops_project_name}"
 

Verifica installazione

  1. Crea file kubeconfig per tutti i cluster. Esegui il seguente script.
$WORKDIR/asm/scripts/setup-gke-vars-kubeconfig.sh
 

Questo script crea un nuovo file kubeconfig nella cartella gke denominato kubemesh.

  1. Modifica la variabile KUBECONFIG in modo che rimandi al nuovo file kubeconfig.
source $WORKDIR/asm/vars/vars.sh
export KUBECONFIG=$WORKDIR/asm/gke/kubemesh
 
  1. Aggiungi le variabili vars.sh e KUBECONFIG a .bashrc in Cloud Shell in modo che vengano caricate ogni volta che Cloud Shell viene riavviato.
echo "source ${WORKDIR}/asm/vars/vars.sh" >> $HOME/.bashrc
echo "export KUBECONFIG=${WORKDIR}/asm/gke/kubemesh" >> $HOME/.bashrc
 
  1. Elenca i contesti del cluster. Dovresti vedere sei cluster.
kubectl config view -ojson | jq -r '.clusters[].name'
 
    `Output (do not copy)`
gke_tf05-01-ops_us-central1_gke-asm-2-r2-prod
gke_tf05-01-ops_us-west1_gke-asm-1-r1-prod
gke_tf05-02-dev1_us-west1-a_gke-1-apps-r1a-prod
gke_tf05-02-dev1_us-west1-b_gke-2-apps-r1b-prod
gke_tf05-03-dev2_us-central1-a_gke-3-apps-r2a-prod
gke_tf05-03-dev2_us-central1-b_gke-4-apps-r2b-prod

Verifica l'installazione di Istio

  1. Assicurati che Istio sia installato su entrambi i cluster controllando che tutti i pod siano in esecuzione e che i job siano stati completati.
kubectl --context ${OPS_GKE_1} get pods -n istio-system
kubectl --context ${OPS_GKE_2} get pods -n istio-system
 
    `Output (do not copy)`
NAME                                      READY   STATUS    RESTARTS   AGE
grafana-5f798469fd-z9f98                  1/1     Running   0          6m21s
istio-citadel-568747d88-qdw64             1/1     Running   0          6m26s
istio-egressgateway-8f454cf58-ckw7n       1/1     Running   0          6m25s
istio-galley-6b9495645d-m996v             2/2     Running   0          6m25s
istio-ingressgateway-5df799fdbd-8nqhj     1/1     Running   0          2m57s
istio-pilot-67fd786f65-nwmcb              2/2     Running   0          6m24s
istio-policy-74cf89cb66-4wrpl             2/2     Running   1          6m25s
istio-sidecar-injector-759bf6b4bc-mw4vf   1/1     Running   0          6m25s
istio-telemetry-77b6dfb4ff-zqxzz          2/2     Running   1          6m24s
istio-tracing-cd67ddf8-n4d7k              1/1     Running   0          6m25s
istiocoredns-5f7546c6f4-g7b5c             2/2     Running   0          6m39s
kiali-7964898d8c-5twln                    1/1     Running   0          6m23s
prometheus-586d4445c7-xhn8d               1/1     Running   0          6m25s
    `Output (do not copy)`
NAME                                      READY   STATUS    RESTARTS   AGE
grafana-5f798469fd-2s8k4                  1/1     Running   0          59m
istio-citadel-568747d88-87kdj             1/1     Running   0          59m
istio-egressgateway-8f454cf58-zj9fs       1/1     Running   0          60m
istio-galley-6b9495645d-qfdr6             2/2     Running   0          59m
istio-ingressgateway-5df799fdbd-2c9rc     1/1     Running   0          60m
istio-pilot-67fd786f65-nzhx4              2/2     Running   0          59m
istio-policy-74cf89cb66-4bc7f             2/2     Running   3          59m
istio-sidecar-injector-759bf6b4bc-grk24   1/1     Running   0          59m
istio-telemetry-77b6dfb4ff-6zr94          2/2     Running   4          60m
istio-tracing-cd67ddf8-grs9g              1/1     Running   0          60m
istiocoredns-5f7546c6f4-gxd66             2/2     Running   0          60m
kiali-7964898d8c-nhn52                    1/1     Running   0          59m
prometheus-586d4445c7-xr44v               1/1     Running   0          59m
  1. Assicurati che Istio sia installato su entrambi i cluster dev1. Solo Citadel, sidecar-injector e coredns vengono eseguiti nei cluster dev1. Condividono un controlplane Istio in esecuzione nel cluster ops-1.
kubectl --context ${DEV1_GKE_1} get pods -n istio-system
kubectl --context ${DEV1_GKE_2} get pods -n istio-system
 
  1. Assicurati che Istio sia installato su entrambi i cluster dev2. Solo Citadel, sidecar-injector e coredns vengono eseguiti nei cluster dev2. Condividono un control plane Istio in esecuzione nel cluster ops-2.
kubectl --context ${DEV2_GKE_1} get pods -n istio-system
kubectl --context ${DEV2_GKE_2} get pods -n istio-system
 
    `Output (do not copy)`
NAME                                      READY   STATUS    RESTARTS   AGE
istio-citadel-568747d88-4lj9b             1/1     Running   0          66s
istio-sidecar-injector-759bf6b4bc-ks5br   1/1     Running   0          66s
istiocoredns-5f7546c6f4-qbsqm             2/2     Running   0          78s

Verifica il service discovery per i control plane condivisi

  1. (Facoltativo) Verifica che i secret siano stati implementati.
kubectl --context ${OPS_GKE_1} get secrets -l istio/multiCluster=true -n istio-system
kubectl --context ${OPS_GKE_2} get secrets -l istio/multiCluster=true -n istio-system
 
    `Output (do not copy)`
For OPS_GKE_1:
NAME                  TYPE     DATA   AGE
gke-1-apps-r1a-prod   Opaque   1      8m7s
gke-2-apps-r1b-prod   Opaque   1      8m7s
gke-3-apps-r2a-prod   Opaque   1      44s
gke-4-apps-r2b-prod   Opaque   1      43s

For OPS_GKE_2:
NAME                  TYPE     DATA   AGE
gke-1-apps-r1a-prod   Opaque   1      40s
gke-2-apps-r1b-prod   Opaque   1      40s
gke-3-apps-r2a-prod   Opaque   1      8m4s
gke-4-apps-r2b-prod   Opaque   1      8m4s

In questo workshop utilizzerai un singolo VPC condiviso in cui vengono creati tutti i cluster GKE. Per rilevare i servizi nei cluster, utilizzi i file kubeconfig (per ciascuno dei cluster di applicazioni) creati come secret nei cluster ops. Pilot utilizza questi secret per rilevare i servizi eseguendo query sul server API Kube dei cluster di applicazioni (autenticati tramite i secret sopra indicati). Noti che entrambi i cluster ops possono autenticarsi a tutti i cluster app utilizzando i secret creati con kubeconfig. I cluster operativi possono rilevare automaticamente i servizi utilizzando i file kubeconfig come metodo segreto. Ciò richiede che Pilot nei cluster ops abbia accesso al server API Kube di tutti gli altri cluster. Se Pilot non riesce a raggiungere i server API Kube, devi aggiungere manualmente i servizi remoti come ServiceEntries. Puoi considerare ServiceEntry come voci DNS nel tuo registry di servizi. ServiceEntry definisce un servizio utilizzando un nome DNS completo ( FQDN) e un indirizzo IP in cui è raggiungibile. Per saperne di più, consulta la documentazione di Istio multicluster.

6. Spiegazione del repository dell'infrastruttura

Cloud Build dell'infrastruttura

Le risorse GCP per il workshop sono create utilizzando Cloud Build e un repository CSR infrastructure. Hai appena eseguito uno script di bootstrap (che si trova in scripts/bootstrap_workshop.sh) dal terminale locale. Lo script di bootstrap crea una cartella Google Cloud, un progetto di amministrazione Terraform e le autorizzazioni IAM appropriate per l'account di servizio Cloud Build. Il progetto di amministrazione Terraform viene utilizzato per archiviare stati, log e script vari di Terraform. Contiene i repository CSR infrastructure e k8s_repo. Questi repository sono spiegati in dettaglio nella sezione successiva. Nessun'altra risorsa del workshop è integrata nel progetto di amministrazione Terraform. Il service account Cloud Build nel progetto amministrativo Terraform viene utilizzato per creare risorse per il workshop.

Un file cloudbuild.yaml che si trova nella cartella infrastructure viene utilizzato per creare risorse GCP per il workshop. Crea un'immagine builder personalizzata con tutti gli strumenti necessari per creare risorse GCP. Questi strumenti includono gcloud SDK, Terraform e altre utilità come Python, Git, jq e così via. L'immagine del builder personalizzato esegue terraform plan e apply per ogni risorsa. I file Terraform di ogni risorsa si trovano in cartelle separate (dettagli nella sezione successiva). Le risorse vengono create una alla volta e nell'ordine in cui vengono normalmente create (ad esempio, un progetto Google Cloud viene creato prima che le risorse vengano create nel progetto). Per maggiori dettagli, consulta il file cloudbuild.yaml.

Cloud Build viene attivato ogni volta che viene eseguito un commit nel repository infrastructure. Qualsiasi modifica apportata all'infrastruttura viene archiviata come Infrastructure as Code (IaC) e sottoposta a commit nel repository. Lo stato del tuo workshop viene sempre archiviato in questo repository.

Struttura delle cartelle: team, ambienti e risorse

Il repository dell'infrastruttura configura le risorse dell'infrastruttura GCP per il workshop. È strutturato in cartelle e sottocartelle. Le cartelle di base all'interno del repository rappresentano i team proprietari di risorse Google Cloud specifiche. Il livello successivo di cartelle rappresenta l'ambiente environment specifico per il team (ad esempio dev, stage, prod). Il livello successivo di cartelle all'interno dell'ambiente rappresenta il resource specifico (ad esempio host_project, gke_clusters e così via). Gli script e i file Terraform richiesti si trovano all'interno delle cartelle delle risorse.

434fc1769bb49b8c.png

In questo workshop sono rappresentati i seguenti quattro tipi di team:

  1. infrastructure: rappresenta il team dell'infrastruttura cloud. Sono responsabili della creazione delle risorse GCP per tutti gli altri team. Utilizzano il progetto amministrativo Terraform per le loro risorse. Il repository dell'infrastruttura si trova nel progetto amministrativo Terraform, così come i file di stato di Terraform (spiegati di seguito). Queste risorse vengono create da uno script bash durante il processo di bootstrap (per maggiori dettagli, vedi il Modulo 0 - Flusso di lavoro dell'amministratore).
  2. network: rappresenta il team di networking. Sono responsabili delle risorse VPC e di networking. Possiedono le seguenti risorse Google Cloud.
  3. host project: rappresenta il progetto host VPC condiviso.
  4. shared VPC: rappresenta il VPC condiviso, le subnet, gli intervalli IP secondari, le route e le regole firewall.
  5. ops: rappresenta il team Operations/DevOps. Possiedono le seguenti risorse.
  6. ops project: rappresenta un progetto per tutte le risorse delle operazioni.
  7. gke clusters: un cluster GKE per le operazioni per regione. Il control plane Istio è installato in ciascuno dei cluster GKE ops.
  8. k8s-repo: un repository CSR che contiene i manifest GKE per tutti i cluster GKE.
  9. apps: rappresenta i team di applicazioni. Questo workshop simula due team, ovvero app1 e app2. Possiedono le seguenti risorse.
  10. app projects: ogni team di app ha il proprio insieme di progetti. In questo modo, possono controllare la fatturazione e IAM per il loro progetto specifico.
  11. gke clusters: si tratta di cluster di applicazioni in cui vengono eseguiti i container/pod dell'applicazione.
  12. gce instances: facoltativamente, se hanno applicazioni in esecuzione su istanze GCE. In questo workshop, app1 ha un paio di istanze GCE in cui viene eseguita una parte dell'applicazione.

In questo workshop, la stessa app (l'app Hipster Shop) rappresenta sia app1 che app2.

Provider, stati e output: backend e stati condivisi

I provider google e google-beta si trovano all'indirizzo gcp/[environment]/gcp/provider.tf. Il file provider.tf è symlinked in ogni cartella delle risorse. In questo modo puoi modificare il fornitore in un'unica posizione anziché gestire singolarmente i fornitori per ogni risorsa.

Ogni risorsa contiene un file backend.tf che definisce la posizione del file tfstate della risorsa. Questo file backend.tf viene generato da un modello (che si trova in templates/backend.tf_tmpl) utilizzando uno script (che si trova in scripts/setup_terraform_admin_project) e poi inserito nella rispettiva cartella delle risorse. I bucket Google Cloud Storage (GCS) vengono utilizzati per i backend. Il nome della cartella del bucket GCS corrisponde al nome della risorsa. Tutti i backend delle risorse si trovano nel progetto amministratore Terraform.

Le risorse con valori interdipendenti contengono un file output.tf. I valori di output richiesti vengono archiviati nel file tfstate definito nel backend per quella particolare risorsa. Ad esempio, per creare un cluster GKE in un progetto, devi conoscere l'ID progetto. L'ID progetto viene restituito tramite output.tf al file tfstate che può essere utilizzato tramite un'origine dati terraform_remote_state nella risorsa cluster GKE.

Il file shared_state è un'origine dati terraform_remote_state che punta al file tfstate di una risorsa. Esiste un file (o file) shared_state_[resource_name].tf nelle cartelle delle risorse che richiedono output da altre risorse. Ad esempio, nella cartella delle risorse ops_gke sono presenti file shared_state delle risorse ops_project e shared_vpc, perché hai bisogno dell'ID progetto e dei dettagli del VPC per creare cluster GKE nel progetto ops. I file shared_state vengono generati da un modello (che si trova in templates/shared_state.tf_tmpl) utilizzando uno script (che si trova in scripts/setup_terraform_admin_project). Tutti i file shared_state delle risorse vengono inseriti nella cartella gcp/[environment]/shared_states. I file shared_state richiesti sono collegati simbolicamente nelle rispettive cartelle delle risorse. Se inserisci tutti i file shared_state in una cartella e li colleghi simbolicamente alle cartelle delle risorse appropriate, puoi gestire facilmente tutti i file di stato in un unico posto.

Variabili

Tutti i valori delle risorse vengono archiviati come variabili di ambiente. Queste variabili vengono archiviate (come istruzioni di esportazione) in un file denominato vars.sh che si trova in un bucket GCS nel progetto di amministrazione di Terraform. Contiene l'ID organizzazione, l'account di fatturazione, gli ID progetto, i dettagli del cluster GKE e così via. Puoi scaricare e recuperare vars.sh da qualsiasi terminale per ottenere i valori per la configurazione.

Le variabili Terraform vengono archiviate in vars.sh come TF_VAR_[variable name]. Queste variabili vengono utilizzate per generare un file variables.tfvars nella cartella delle risorse corrispondente. Il file variables.tfvars contiene tutte le variabili con i relativi valori. Il file variables.tfvars viene generato da un file modello nella stessa cartella utilizzando uno script (che si trova in scripts/setup_terraform_admin_project).

Spiegazione del repository K8s

k8s_repo è un repository CSR (separato dal repository dell'infrastruttura) che si trova nel progetto amministratore Terraform. Viene utilizzato per archiviare e applicare i manifest GKE a tutti i cluster GKE. k8s_repo viene creato dall'infrastruttura Cloud Build (per i dettagli, consulta la sezione precedente). Durante il processo iniziale di Cloud Build dell'infrastruttura, vengono creati un totale di sei cluster GKE. In k8s_repo vengono create sei cartelle. Ogni cartella (il cui nome corrisponde al nome del cluster GKE) corrisponde a un cluster GKE contenente i rispettivi file manifest delle risorse. Come per la creazione dell'infrastruttura, Cloud Build viene utilizzato per applicare i manifest Kubernetes a tutti i cluster GKE utilizzando k8s_repo. Cloud Build viene attivato ogni volta che viene eseguito un commit nel repository k8s_repo. Come per l'infrastruttura, tutti i manifest Kubernetes vengono archiviati come codice nel repository k8s_repo e lo stato di ogni cluster GKE viene sempre archiviato nella rispettiva cartella.

Nell'ambito della creazione iniziale dell'infrastruttura, viene creato k8s_repo e Istio viene installato su tutti i cluster.

Progetti, cluster GKE e spazi dei nomi

Le risorse di questo workshop sono suddivise in diversi progetti Google Cloud. I progetti devono corrispondere alla struttura organizzativa (o del team) della tua azienda. I team (all'interno dell'organizzazione) responsabili di diversi progetti/prodotti/risorse utilizzano progetti GCP diversi. Avere progetti separati ti consente di creare set separati di autorizzazioni IAM e gestire la fatturazione a livello di progetto. Inoltre, le quote vengono gestite anche a livello di progetto.

In questo workshop sono rappresentati cinque team, ognuno con il proprio progetto.

  1. Il team dell'infrastruttura che crea le risorse Google Cloud utilizza Terraform admin project. Gestiscono l'infrastruttura come codice in un repository CSR (denominato infrastructure) e archiviano tutte le informazioni sullo stato di Terraform relative alle risorse create in Google Cloud nei bucket GCS. Controllano l'accesso al repository CSR e ai bucket GCS di stato di Terraform.
  2. Il team di rete che crea il VPC condiviso utilizza host project. Questo progetto contiene VPC, subnet, route e regole firewall. Un VPC condiviso consente di gestire centralmente il networking per le risorse GCP. Tutti i progetti utilizzavano questo singolo VPC condiviso per il networking.
  3. Il team ops/platform che crea cluster GKE e control plane ASM/Istio utilizza ops project. Gestiscono il ciclo di vita dei cluster GKE e del service mesh. Sono responsabili dell'hardening dei cluster e della gestione della resilienza e della scalabilità della piattaforma Kubernetes. In questo workshop utilizzerai il metodo GitOps per il deployment delle risorse in Kubernetes. Nel progetto ops esiste un repository CSR (denominato k8s_repo).
  4. Infine, i team dev1 e dev2 (che rappresentano due team di sviluppo) che creano applicazioni utilizzano i propri dev1 e dev2 projects. Queste sono le applicazioni e i servizi che fornisci ai tuoi clienti. Questi sono basati sulla piattaforma gestita dal team Ops. Le risorse (deployment, servizi e così via) vengono inviate a k8s_repo ed eseguite il deployment nei cluster appropriati. È importante notare che questo workshop non si concentra su best practice e strumenti CI/CD. Utilizzi Cloud Build per automatizzare il deployment delle risorse Kubernetes direttamente nei cluster GKE. In scenari di produzione reali, utilizzeresti una soluzione CI/CD appropriata per eseguire il deployment delle applicazioni nei cluster GKE.

In questo workshop esistono due tipi di cluster GKE.

  1. Cluster ops: utilizzati dal team ops per eseguire gli strumenti DevOps. In questo workshop, eseguono il control plane ASM/Istio per gestire il service mesh.
  2. Cluster di applicazioni: utilizzati dai team di sviluppo per eseguire le applicazioni. In questo workshop viene utilizzata l'app Hipster Shop.

La separazione degli strumenti di operazioni/amministrazione dai cluster che eseguono l'applicazione consente di gestire il ciclo di vita di ogni risorsa in modo indipendente. I due tipi di cluster esistono anche in progetti diversi relativi al team/prodotto che li utilizza, il che semplifica anche la gestione delle autorizzazioni IAM.

Ci sono un totale di sei cluster GKE. Nel progetto ops vengono creati due cluster ops regionali. Il control plane ASM/Istio è installato su entrambi i cluster ops. Ogni cluster delle operazioni si trova in un'area geografica diversa. Inoltre, sono presenti quattro cluster di applicazioni zonali. Questi vengono creati nei rispettivi progetti. Questo workshop simula due team di sviluppo, ciascuno con i propri progetti. Ogni progetto contiene due cluster di app. I cluster di app sono cluster di zona in zone diverse. I quattro cluster di app si trovano in due regioni e quattro zone. In questo modo, ottieni la ridondanza regionale e zonale.

L'applicazione utilizzata in questo workshop, l'app Hipster Shop, viene implementata in tutti e quattro i cluster di app. Ogni microservizio si trova nel proprio spazio dei nomi in ogni cluster di app. I deployment (pod) dell'app Hipster Shop non vengono eseguiti sui cluster ops. Tuttavia, negli ops cluster vengono creati anche gli spazi dei nomi e le risorse di servizio per tutti i microservizi. Il control plane ASM/Istio utilizza i registri di servizio Kubernetes per Service Discovery. In assenza di servizi (nei cluster ops), dovresti creare manualmente ServiceEntry per ogni servizio in esecuzione nel cluster app.

In questo workshop esegui il deployment di un'applicazione di microservizi a 10 livelli. L'applicazione è un'app di e-commerce basata sul web chiamata "Hipster Shop", in cui gli utenti possono sfogliare gli articoli, aggiungerli al carrello e acquistarli.

Manifest Kubernetes e k8s_repo

Utilizzi k8s_repo per aggiungere risorse Kubernetes a tutti i cluster GKE. A questo scopo, copia i manifest Kubernetes ed esegui il commit in k8s_repo. Tutti i commit in k8s_repo attivano un job Cloud Build che esegue il deployment dei manifest Kubernetes nel rispettivo cluster. Il manifest di ogni cluster si trova in una cartella separata con lo stesso nome del cluster.

I sei nomi dei cluster sono:

  1. gke-asm-1-r1-prod: il cluster ops regionale nella regione 1
  2. gke-asm-2-r2-prod: il cluster ops regionale nella regione 2
  3. gke-1-apps-r1a-prod: il cluster di app nella zona a della regione 1
  4. gke-2-apps-r1b-prod: il cluster di app nella zona b della regione 1
  5. gke-3-apps-r2a-prod: il cluster di app nella zona a della regione 2
  6. gke-4-apps-r2b-prod: il cluster di app nella zona b della regione 2

k8s_repo ha cartelle corrispondenti a questi cluster. Qualsiasi manifest inserito in queste cartelle viene applicato al cluster GKE corrispondente. Per semplificare la gestione, i manifest per ogni cluster vengono inseriti in sottocartelle (all'interno della cartella principale del cluster). In questo workshop utilizzerai Kustomize per tenere traccia delle risorse di cui viene eseguito il deployment. Per ulteriori dettagli, consulta la documentazione ufficiale di Kustomize.

7. Esegui il deployment dell'app di esempio

Obiettivo: esegui il deployment dell'app Hipster Shop sui cluster di app

  • k8s-repo (clone)
  • Copia i manifest del negozio Hipster in tutti i cluster di app
  • Crea servizi per l'app Hipster Shop nei cluster ops
  • Configura loadgenerators nei cluster ops per testare la connettività globale
  • Verifica la connettività sicura all'app Hipster Shop

Istruzioni per il lab sul metodo di copia e incolla

Clona il repository di origine del progetto ops

Nell'ambito della creazione iniziale dell'infrastruttura Terraform, k8s-repo è già stato creato nel progetto ops.

  1. Crea una directory vuota per il repository Git:
mkdir $WORKDIR/k8s-repo
 
  1. Inizializza il repository Git, aggiungi il repository remoto ed esegui il pull di master dal repository remoto:
cd $WORKDIR/k8s-repo
git init && git remote add origin \
https://source.developers.google.com/p/$TF_VAR_ops_project_name/r/k8s-repo
 
  1. Imposta la configurazione locale di Git.
git config --local user.email $MY_USER
git config --local user.name "K8s repo user"
git config --local \
credential.'https://source.developers.google.com'.helper gcloud.sh
git pull origin master

Copia i manifest, esegui il commit e il push

  1. Copia gli spazi dei nomi e i servizi di Hipster Shop nel repository di origine per tutti i cluster.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/namespaces \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/namespaces \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/namespaces \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/namespaces \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/namespaces \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/namespaces \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app/.

cp -r $WORKDIR/asm/k8s_manifests/prod/app/services \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/services \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/services \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/services \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/services \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/services \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app/.
 
  1. Copia il file kustomization.yaml della cartella dell'app in tutti i cluster.
cp $WORKDIR/asm/k8s_manifests/prod/app/kustomization.yaml \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app/
cp $WORKDIR/asm/k8s_manifests/prod/app/kustomization.yaml \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/
cp $WORKDIR/asm/k8s_manifests/prod/app/kustomization.yaml \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/
cp $WORKDIR/asm/k8s_manifests/prod/app/kustomization.yaml \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/
cp $WORKDIR/asm/k8s_manifests/prod/app/kustomization.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app/
cp $WORKDIR/asm/k8s_manifests/prod/app/kustomization.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app/
 
  1. Copia i deployment, RBAC e PodSecurityPolicy di Hipster Shop nel repository di origine per i cluster di app.
cp -r $WORKDIR/asm/k8s_manifests/prod/app/deployments \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/deployments \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/deployments \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/deployments \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/

cp -r $WORKDIR/asm/k8s_manifests/prod/app/rbac \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/rbac \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/rbac \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/rbac \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/podsecuritypolicies \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/podsecuritypolicies \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/podsecuritypolicies \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/
cp -r $WORKDIR/asm/k8s_manifests/prod/app/podsecuritypolicies \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/
  1. Rimuovi il deployment cartservice, rbac e podsecuritypolicy da tutti i cluster di sviluppo tranne uno. Hipstershop non è stato creato per il deployment multicluster, quindi per evitare risultati incoerenti, utilizziamo un solo cartservice.
rm $WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/deployments/app-cart-service.yaml
rm $WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/podsecuritypolicies/cart-psp.yaml
rm $WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/app/rbac/cart-rbac.yaml

rm $WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/deployments/app-cart-service.yaml
rm $WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/podsecuritypolicies/cart-psp.yaml
rm $WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app/rbac/cart-rbac.yaml

rm $WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/deployments/app-cart-service.yaml
rm $WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/podsecuritypolicies/cart-psp.yaml
rm $WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/app/rbac/cart-rbac.yaml
 
  1. Aggiungi il deployment di cartservice, rbac e podsecuritypolicy a kustomization.yaml solo nel primo cluster di sviluppo.
cd ${WORKDIR}/k8s-repo/${DEV1_GKE_1_CLUSTER}/app
cd deployments && kustomize edit add resource app-cart-service.yaml
cd ../podsecuritypolicies && kustomize edit add resource cart-psp.yaml
cd ../rbac && kustomize edit add resource cart-rbac.yaml
cd ${WORKDIR}/asm
 
  1. Rimuovi le directory podsecuritypolicies, deployments e rbac da ops clusters kustomization.yaml
sed -i -e '/- deployments\//d' -e '/- podsecuritypolicies\//d' \
  -e '/- rbac\//d' \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app/kustomization.yaml
sed -i -e '/- deployments\//d' -e '/- podsecuritypolicies\//d' \
  -e '/- rbac\//d' \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app/kustomization.yaml
  1. Sostituisci PROJECT_ID nei manifest RBAC.
sed -i 's/\${PROJECT_ID}/'${TF_VAR_dev1_project_name}'/g' \
${WORKDIR}/k8s-repo/${DEV1_GKE_1_CLUSTER}/app/rbac/*
sed -i 's/\${PROJECT_ID}/'${TF_VAR_dev1_project_name}'/g' \
${WORKDIR}/k8s-repo/${DEV1_GKE_2_CLUSTER}/app/rbac/*
sed -i 's/\${PROJECT_ID}/'${TF_VAR_dev2_project_name}'/g' \
${WORKDIR}/k8s-repo/${DEV2_GKE_1_CLUSTER}/app/rbac/*
sed -i 's/\${PROJECT_ID}/'${TF_VAR_dev2_project_name}'/g' \
${WORKDIR}/k8s-repo/${DEV2_GKE_2_CLUSTER}/app/rbac/*
  
  1. Copia i manifest IngressGateway e VirtualService nel repository di origine per i cluster ops.
cp -r $WORKDIR/asm/k8s_manifests/prod/app-ingress/* \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-ingress/
cp -r $WORKDIR/asm/k8s_manifests/prod/app-ingress/* \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-ingress/
 
  1. Copia le risorse di Config Connector in uno dei cluster di ogni progetto.
cp -r $WORKDIR/asm/k8s_manifests/prod/app-cnrm/* \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-cnrm/
cp -r $WORKDIR/asm/k8s_manifests/prod/app-cnrm/* \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app-cnrm/
cp -r $WORKDIR/asm/k8s_manifests/prod/app-cnrm/* \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app-cnrm/
 
  1. Sostituisci PROJECT_ID nei manifest di Config Connector.
sed -i 's/${PROJECT_ID}/'$TF_VAR_ops_project_name'/g' \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-cnrm/*
sed -i 's/${PROJECT_ID}/'$TF_VAR_dev1_project_name'/g' \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/app-cnrm/*
sed -i 's/${PROJECT_ID}/'$TF_VAR_dev2_project_name'/g' \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/app-cnrm/*
 
  1. Copia i manifest loadgenerator (Deployment, PodSecurityPolicy e RBAC) nei cluster ops. L'app Hipster Shop è esposta utilizzando un bilanciatore del carico Google Cloud (GCLB) globale. GCLB riceve il traffico client (destinato a frontend) e lo invia all'istanza più vicina del servizio. L'inserimento di loadgenerator in entrambi i cluster ops garantisce che il traffico venga inviato a entrambi i gateway in entrata Istio in esecuzione nei cluster ops. Il bilanciamento del carico è spiegato in dettaglio nella sezione seguente.
cp -r $WORKDIR/asm/k8s_manifests/prod/app-loadgenerator/. \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-loadgenerator/.
cp -r $WORKDIR/asm/k8s_manifests/prod/app-loadgenerator/. \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-loadgenerator/. 
 
  1. Sostituisci l'ID progetto ops nei manifest loadgenerator per entrambi i cluster ops.
sed -i 's/OPS_PROJECT_ID/'$TF_VAR_ops_project_name'/g'  \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-loadgenerator/loadgenerator-deployment.yaml
sed -i 's/OPS_PROJECT_ID/'$TF_VAR_ops_project_name'/g' \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-loadgenerator/loadgenerator-rbac.yaml
sed -i 's/OPS_PROJECT_ID/'$TF_VAR_ops_project_name'/g' \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-loadgenerator/loadgenerator-deployment.yaml
sed -i 's/OPS_PROJECT_ID/'$TF_VAR_ops_project_name'/g' \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-loadgenerator/loadgenerator-rbac.yaml
 

  1. Aggiungi le risorse loadgenerator a kustomization.yaml per entrambi i cluster ops.
cd $WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-loadgenerator/
kustomize edit add resource loadgenerator-psp.yaml
kustomize edit add resource loadgenerator-rbac.yaml
kustomize edit add resource loadgenerator-deployment.yaml

cd $WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-loadgenerator/
kustomize edit add resource loadgenerator-psp.yaml
kustomize edit add resource loadgenerator-rbac.yaml
kustomize edit add resource loadgenerator-deployment.yaml
 

  1. Impegnati a k8s-repo.
cd $WORKDIR/k8s-repo
git add . && git commit -am "create app namespaces and install hipster shop"
git push --set-upstream origin master 
 
  1. Visualizza lo stato di Cloud Build del progetto Ops in una scheda aperta in precedenza o facendo clic sul seguente link:
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_VAR_ops_project_name}"
  

Verifica il deployment dell'applicazione

  1. Verifica che i pod in tutti gli spazi dei nomi dell'applicazione, ad eccezione del carrello, siano in stato Running in tutti i cluster di sviluppo.
for ns in ad checkout currency email frontend payment product-catalog recommendation shipping; do
  kubectl --context $DEV1_GKE_1 get pods -n $ns;
  kubectl --context $DEV1_GKE_2 get pods -n $ns;
  kubectl --context $DEV2_GKE_1 get pods -n $ns;
  kubectl --context $DEV2_GKE_2 get pods -n $ns;
done;
 

Output (do not copy)

NAME                               READY   STATUS    RESTARTS   AGE
currencyservice-5c5b8876db-pvc6s   2/2     Running   0          13m
NAME                               READY   STATUS    RESTARTS   AGE
currencyservice-5c5b8876db-xlkl9   2/2     Running   0          13m
NAME                               READY   STATUS    RESTARTS   AGE
currencyservice-5c5b8876db-zdjkg   2/2     Running   0          115s
NAME                               READY   STATUS    RESTARTS   AGE
currencyservice-5c5b8876db-l748q   2/2     Running   0          82s

NAME                            READY   STATUS    RESTARTS   AGE
emailservice-588467b8c8-gk92n   2/2     Running   0          13m
NAME                            READY   STATUS    RESTARTS   AGE
emailservice-588467b8c8-rvzk9   2/2     Running   0          13m
NAME                            READY   STATUS    RESTARTS   AGE
emailservice-588467b8c8-mt925   2/2     Running   0          117s
NAME                            READY   STATUS    RESTARTS   AGE
emailservice-588467b8c8-klqn7   2/2     Running   0          84s

NAME                        READY   STATUS    RESTARTS   AGE
frontend-64b94cf46f-kkq7d   2/2     Running   0          13m
NAME                        READY   STATUS    RESTARTS   AGE
frontend-64b94cf46f-lwskf   2/2     Running   0          13m
NAME                        READY   STATUS    RESTARTS   AGE
frontend-64b94cf46f-zz7xs   2/2     Running   0          118s
NAME                        READY   STATUS    RESTARTS   AGE
frontend-64b94cf46f-2vtw5   2/2     Running   0          85s

NAME                              READY   STATUS    RESTARTS   AGE
paymentservice-777f6c74f8-df8ml   2/2     Running   0          13m
NAME                              READY   STATUS    RESTARTS   AGE
paymentservice-777f6c74f8-bdcvg   2/2     Running   0          13m
NAME                              READY   STATUS    RESTARTS   AGE
paymentservice-777f6c74f8-jqf28   2/2     Running   0          117s
NAME                              READY   STATUS    RESTARTS   AGE
paymentservice-777f6c74f8-95x2m   2/2     Running   0          86s

NAME                                     READY   STATUS    RESTARTS   AGE
productcatalogservice-786dc84f84-q5g9p   2/2     Running   0          13m
NAME                                     READY   STATUS    RESTARTS   AGE
productcatalogservice-786dc84f84-n6lp8   2/2     Running   0          13m
NAME                                     READY   STATUS    RESTARTS   AGE
productcatalogservice-786dc84f84-gf9xl   2/2     Running   0          119s
NAME                                     READY   STATUS    RESTARTS   AGE
productcatalogservice-786dc84f84-v7cbr   2/2     Running   0          86s

NAME                                     READY   STATUS    RESTARTS   AGE
recommendationservice-5fdf959f6b-2ltrk   2/2     Running   0          13m
NAME                                     READY   STATUS    RESTARTS   AGE
recommendationservice-5fdf959f6b-dqd55   2/2     Running   0          13m
NAME                                     READY   STATUS    RESTARTS   AGE
recommendationservice-5fdf959f6b-jghcl   2/2     Running   0          119s
NAME                                     READY   STATUS    RESTARTS   AGE
recommendationservice-5fdf959f6b-kkspz   2/2     Running   0          87s

NAME                              READY   STATUS    RESTARTS   AGE
shippingservice-7bd5f569d-qqd9n   2/2     Running   0          13m
NAME                              READY   STATUS    RESTARTS   AGE
shippingservice-7bd5f569d-xczg5   2/2     Running   0          13m
NAME                              READY   STATUS    RESTARTS   AGE
shippingservice-7bd5f569d-wfgfr   2/2     Running   0          2m
NAME                              READY   STATUS    RESTARTS   AGE
shippingservice-7bd5f569d-r6t8v   2/2     Running   0          88s
  1. Verifica che i pod nello spazio dei nomi del carrello siano in stato Running solo nel primo cluster di sviluppo.
kubectl --context $DEV1_GKE_1 get pods -n cart;
 

Output (do not copy)

NAME                           READY   STATUS    RESTARTS   AGE
cartservice-659c9749b4-vqnrd   2/2     Running   0          17m

Accedere all'app Hipster Shop

Bilanciamento del carico globale

Ora l'app Hipster Shop è stata implementata in tutti e quattro i cluster di app. Questi cluster si trovano in due regioni e quattro zone. I clienti possono accedere all'app del negozio Hipster accedendo al servizio frontend. Il servizio frontend viene eseguito su tutti e quattro i cluster di app. Un bilanciatore del carico Google Cloud ( GCLB) viene utilizzato per indirizzare il traffico client a tutte e quattro le istanze del servizio frontend.

I gateway Istio Ingress vengono eseguiti solo nei cluster ops e fungono da bilanciatore del carico regionale per i due cluster di applicazioni zonali all'interno della regione. GCLB utilizza i due gateway in entrata Istio (in esecuzione nei due cluster ops) come backend per il servizio frontend globale. I gateway Istio Ingress ricevono il traffico client dal bilanciatore del carico di Google Cloud e lo inviano ai pod frontend in esecuzione nei cluster dell'applicazione.

4c618df35cb928ee.png

In alternativa, puoi inserire i gateway Istio Ingress direttamente nei cluster delle applicazioni e il bilanciatore del carico Google Cloud può utilizzarli come backend.

Controller Autoneg GKE

Il servizio Kubernetes del gateway Istio Ingress si registra come backend nel bilanciatore del carico Google Cloud utilizzando i gruppi di endpoint di rete (NEG). I NEG consentono il bilanciamento del carico nativo del container utilizzando i bilanciatori del carico GCLB. I NEG vengono creati tramite un'annotazione speciale su un servizio Kubernetes, in modo che possa registrarsi nel controller NEG. Il controller Autoneg è un controller GKE speciale che automatizza la creazione di NEG e la loro assegnazione come backend a un bilanciatore del carico Google Cloud utilizzando le annotazioni del servizio. I control plane Istio, inclusi i gateway in entrata Istio, vengono implementati durante la build iniziale dell'infrastruttura Terraform Cloud. La configurazione di GCLB e autoneg viene eseguita nell'ambito della build iniziale dell'infrastruttura Terraform Cloud Build.

Ingress sicuro utilizzando Cloud Endpoints e certificati gestiti

I certificati gestiti da GCP vengono utilizzati per proteggere il traffico client verso il servizio GCLB frontend. GCLB utilizza certificati gestiti per il servizio frontend globale e il certificato viene terminato in GCLB. In questo workshop, utilizzerai Cloud Endpoints come dominio per il certificato gestito. In alternativa, puoi utilizzare il tuo dominio e un nome DNS per frontend per creare certificati gestiti da GCP.

  1. Per accedere al negozio Hipster, fai clic sul link restituito dal seguente comando.
echo "https://frontend.endpoints.$TF_VAR_ops_project_name.cloud.goog" 
 
  1. Puoi verificare che il certificato sia valido facendo clic sul simbolo del lucchetto nella barra degli URL della scheda di Chrome.

6c403a63caa06c84.png

Verifica il bilanciamento del carico globale

Nell'ambito del deployment dell'applicazione, i generatori di carico sono stati implementati in entrambi i cluster ops che generano traffico di test al link Cloud Endpoints di GCLB Hipster Shop. Verifica che il bilanciatore del carico Google riceva traffico e lo invii a entrambi i gateway in entrata Istio.

  1. Ottieni il link GCLB > Monitoring per il progetto ops in cui viene creato il bilanciamento del carico di Google Cloud del negozio Hipster.
echo "https://console.cloud.google.com/net-services/loadbalancing/details/http/istio-ingressgateway?project=$TF_VAR_ops_project_name&cloudshell=false&tab=monitoring&duration=PT1H" 
 
  1. Passa da Tutti i backend a istio-ingressgateway dal menu a discesa Backend, come mostrato di seguito.

6697c9eb67998d27.png

  1. Prendi nota del traffico verso istio-ingressgateways.

ff8126e44cfd7f5e.png

Per ogni istio-ingressgateway vengono creati tre NEG. Poiché i cluster ops sono cluster regionali, viene creato un NEG per ogni zona della regione. I pod istio-ingressgateway, tuttavia, vengono eseguiti in una singola zona per regione. Il traffico viene mostrato in direzione dei pod istio-ingressgateway.

I generatori di carico vengono eseguiti in entrambi i cluster ops simulando il traffico client dalle due regioni in cui si trovano. Il carico generato nella regione 1 del cluster delle operazioni viene inviato a istio-ingressgateway nella regione 2. Allo stesso modo, il carico generato nella regione 2 del cluster ops viene inviato a istio-ingressgateway nella regione 2.

8. Osservabilità con Stackdriver

Obiettivo: connettere la telemetria di Istio a Stackdriver e convalidarla.

  • Installare le risorse istio-telemetry
  • Creare/aggiornare le dashboard dei servizi Istio
  • Visualizzare i log dei container
  • Visualizzare il tracciamento distribuito in Stackdriver

Istruzioni per il lab sul metodo di copia e incolla

Una delle funzionalità principali di Istio è l'osservabilità integrata ("o11y"). Ciò significa che anche con i container black box non strumentati, gli operatori possono comunque osservare il traffico in entrata e in uscita da questi container, fornendo servizi ai clienti. Questa osservazione assume la forma di diversi metodi: metriche, log e tracce.

Utilizzeremo anche il sistema di generazione del carico integrato in Hipster Shop. L'osservabilità non funziona molto bene in un sistema statico senza traffico, quindi la generazione del carico ci aiuta a capire come funziona. Questo caricamento è già in esecuzione, ora potremo solo vederlo.

  1. Installa il file di configurazione di Istio in Stackdriver.
cd $WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/istio-telemetry
kustomize edit add resource istio-telemetry.yaml

cd $WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/istio-telemetry
kustomize edit add resource istio-telemetry.yaml
 
  1. Esegui il commit in k8s-repo.
cd $WORKDIR/k8s-repo
git add . && git commit -am "Install istio to stackdriver configuration"
git push 
 
  1. Visualizza lo stato di Cloud Build del progetto Ops in una scheda aperta in precedenza o facendo clic sul seguente link:
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_VAR_ops_project_name}"
 
  1. Verifica l'integrazione di Istio → Stackdriver. Ottieni la CRD del gestore Stackdriver.
kubectl --context $OPS_GKE_1 get handler -n istio-system
 

L'output dovrebbe mostrare un gestore denominato stackdriver:

NAME            AGE
kubernetesenv   12d
prometheus      12d
stackdriver     69s      # <== NEW!
  1. Verifica che l'esportazione delle metriche di Istio in Stackdriver funzioni. Fai clic sul link restituito da questo comando:
echo "https://console.cloud.google.com/monitoring/metrics-explorer?cloudshell=false&project=$TF_VAR_ops_project_name"
 

Ti verrà chiesto di creare un nuovo spazio di lavoro, denominato come il progetto Ops. Scegli OK. Se ti viene chiesto della nuova UI, chiudi la finestra di dialogo.

In Metrics Explorer, nella sezione "Trova tipo di risorsa e metrica", digita "istio" per visualizzare opzioni come "Conteggio richieste server" nel tipo di risorsa "Container Kubernetes". Ciò dimostra che le metriche vengono trasferite dalla mesh a Stackdriver.

(Dovrai raggruppare per etichetta destination_service_name se vuoi visualizzare le righe riportate di seguito.)

b9b59432ee68e695.png

Visualizzare le metriche con le dashboard:

Ora che le nostre metriche si trovano nel sistema Stackdriver APM, vogliamo un modo per visualizzarle. In questa sezione installeremo una dashboard predefinita che mostra tre delle quattro metriche "Golden Signals": Traffico (richieste al secondo), Latenza (in questo caso, 99° e 50° percentile) ed Errori (in questo esempio escludiamo la Saturazione).

Il proxy Envoy di Istio ci fornisce diverse metriche, ma queste sono un buon punto di partenza. L'elenco esaustivo è disponibile qui. Tieni presente che ogni metrica ha un insieme di etichette che possono essere utilizzate per il filtraggio e l'aggregazione, ad esempio: destination_service, source_workload_namespace, response_code, istio_tcp_received_bytes_total e così via.

  1. Ora aggiungiamo la nostra dashboard delle metriche predefinite. Utilizzeremo direttamente l'API Dashboard. Si tratta di un'operazione che normalmente non faresti generando manualmente chiamate API, ma che fa parte di un sistema di automazione o che ti consente di creare manualmente la dashboard nella UI web. Iniziamo subito:
sed -i 's/OPS_PROJECT/'${TF_VAR_ops_project_name}'/g' \
$WORKDIR/asm/k8s_manifests/prod/app-telemetry/services-dashboard.json
OAUTH_TOKEN=$(gcloud auth application-default print-access-token)
curl -X POST -H "Authorization: Bearer $OAUTH_TOKEN" -H "Content-Type: application/json" \
https://monitoring.googleapis.com/v1/projects/$TF_VAR_ops_project_name/dashboards \
 -d @$WORKDIR/asm/k8s_manifests/prod/app-telemetry/services-dashboard.json
 
  1. Vai al link di output riportato di seguito per visualizzare la nuova "Dashboard dei servizi".
echo "https://console.cloud.google.com/monitoring/dashboards/custom/servicesdash?cloudshell=false&project=$TF_VAR_ops_project_name"
 
 

Potremmo modificare la dashboard in linea utilizzando l'esperienza utente, ma nel nostro caso aggiungeremo rapidamente un nuovo grafico utilizzando l'API. Per farlo, devi scaricare l'ultima versione della dashboard, applicare le modifiche e caricarla di nuovo utilizzando il metodo HTTP PATCH.

  1. Puoi ottenere una dashboard esistente eseguendo una query sull'API Monitoring. Recupera la dashboard esistente appena aggiunta:
curl -X GET -H "Authorization: Bearer $OAUTH_TOKEN" -H "Content-Type: application/json" \
https://monitoring.googleapis.com/v1/projects/$TF_VAR_ops_project_name/dashboards/servicesdash > /tmp/services-dashboard.json
 
  1. Aggiungi un nuovo grafico: (latenza al 50° percentile): [ riferimento API] Ora possiamo aggiungere un nuovo widget grafico alla nostra dashboard nel codice. Questa modifica può essere esaminata dai colleghi e registrata nel controllo delle versioni. Ecco un widget da aggiungere che mostra la latenza al 50° percentile (latenza mediana).

Prova a modificare la dashboard appena ricevuta aggiungendo una nuova strofa:

NEW_CHART=${WORKDIR}/asm/k8s_manifests/prod/app-telemetry/new-chart.json
jq --argjson newChart "$(<$NEW_CHART)" '.gridLayout.widgets += [$newChart]' /tmp/services-dashboard.json > /tmp/patched-services-dashboard.json
 
  1. Aggiorna la dashboard dei servizi esistente:
curl -X PATCH -H "Authorization: Bearer $OAUTH_TOKEN" -H "Content-Type: application/json" \
https://monitoring.googleapis.com/v1/projects/$TF_VAR_ops_project_name/dashboards/servicesdash \
 -d @/tmp/patched-services-dashboard.json
 
  1. Visualizza la dashboard aggiornata accedendo al seguente link di output:
echo "https://console.cloud.google.com/monitoring/dashboards/custom/servicesdash?cloudshell=false&project=$TF_VAR_ops_project_name"
 
  1. Esegui un'analisi semplice dei log.

Istio fornisce un insieme di log strutturati per tutto il traffico di rete in-mesh e li carica in Stackdriver Logging per consentire l'analisi cross-cluster in un unico strumento potente. I log sono annotati con metadati a livello di servizio, come cluster, container, app, connection_id e così via.

Una voce di log di esempio (in questo caso, accesslog del proxy Envoy) potrebbe avere il seguente aspetto (troncato):

*** DO NOT PASTE *** 
 logName: "projects/PROJECTNAME-11932-01-ops/logs/server-tcp-accesslog-stackdriver.instance.istio-system" 
labels: {
  connection_id: "fbb46826-96fd-476c-ac98-68a9bd6e585d-1517191"   
  destination_app: "redis-cart"   
  destination_ip: "10.16.1.7"   
  destination_name: "redis-cart-6448dcbdcc-cj52v"   
  destination_namespace: "cart"   
  destination_owner: "kubernetes://apis/apps/v1/namespaces/cart/deployments/redis-cart"   
  destination_workload: "redis-cart"   
  source_ip: "10.16.2.8"   
  total_received_bytes: "539"   
  total_sent_bytes: "569" 
...  
 }

Visualizza i log qui:

echo "https://console.cloud.google.com/logs/viewer?cloudshell=false&project=$TF_VAR_ops_project_name"
 

Puoi visualizzare i log del control plane di Istio selezionando Risorsa > Container Kubernetes e cercando "pilot".

6f93b2aec6c4f520.png

Qui possiamo vedere il control plane Istio che esegue il push della configurazione del proxy nei proxy sidecar per ogni servizio dell'app di esempio. "CDS", "LDS" e "RDS" rappresentano API Envoy diverse ( maggiori informazioni).

Oltre ai log di Istio, puoi trovare anche i log dei container, dell'infrastruttura o di altri servizi GCP nella stessa interfaccia. Ecco alcune query di esempio per i log per GKE. Il visualizzatore dei log ti consente anche di creare metriche dai log (ad es. "conta ogni errore che corrisponde a una stringa") che possono essere utilizzate in una dashboard o come parte di un avviso. I log possono anche essere trasmessi in streaming ad altri strumenti di analisi come BigQuery.

Alcuni filtri di esempio per un negozio hipster:

resource.type="k8s_container" labels.destination_app="productcatalogservice"

resource.type="k8s_container" resource.labels.namespace_name="cart"

  1. Dai un'occhiata a Distributed Traces.

Ora che lavori con un sistema distribuito, il debug richiede un nuovo strumento: Distributed Tracing. Questo strumento ti consente di scoprire statistiche su come interagiscono i tuoi servizi (ad esempio, trovare eventi lenti anomali nell'immagine seguente), nonché di analizzare tracce di campioni non elaborati per esaminare i dettagli di ciò che sta realmente accadendo.

La visualizzazione cronologia mostra tutte le richieste nel tempo, rappresentate graficamente in base alla latenza o al tempo trascorso tra la richiesta iniziale, tramite lo stack Hipster, fino alla risposta finale all'utente finale. Più in alto si trovano i puntini, più lenta (e meno soddisfacente) è l'esperienza dell'utente.

Puoi fare clic su un punto per visualizzare la visualizzazione a cascata dettagliata di quella particolare richiesta. Questa capacità di trovare i dettagli non elaborati di una determinata richiesta (non solo le statistiche aggregate) è fondamentale per comprendere l'interazione tra i servizi, soprattutto quando si cercano interazioni rare, ma negative, tra i servizi.

La visualizzazione a cascata dovrebbe essere familiare a chiunque abbia utilizzato un debugger, ma in questo caso, anziché mostrare il tempo trascorso in diversi processi di una singola applicazione, mostra il tempo trascorso attraversando la nostra mesh, tra i servizi, in esecuzione in container separati.

Qui puoi trovare le tue Tracce:

echo "https://console.cloud.google.com/traces/overview?cloudshell=false&project=$TF_VAR_ops_project_name"
 

Uno screenshot di esempio dello strumento:

5ee238836dc9047f.png

9. Autenticazione TLS reciproca

Obiettivo: connettività sicura tra i microservizi (autenticazione).

  • Abilita mTLS a livello di mesh
  • Verificare mTLS esaminando i log

Istruzioni per il lab sul metodo di copia e incolla

Ora che le nostre app sono installate e l'osservabilità è configurata, possiamo iniziare a proteggere le connessioni tra i servizi e assicurarci che continuino a funzionare.

Ad esempio, nella dashboard di Kiali possiamo vedere che i nostri servizi non utilizzano MTLS (nessuna icona "lucchetto"). ma il traffico è scorrevole e il sistema funziona bene. La nostra dashboard delle metriche d'oro di Stackdriver ci rassicura sul fatto che le cose funzionano, nel complesso.

  1. Controlla MeshPolicy nei cluster ops. Tieni presente che mTLS è PERMISSIVE, consentendo sia il traffico criptato che quello non mTLS.
kubectl --context $OPS_GKE_1 get MeshPolicy -o json | jq '.items[].spec'
kubectl --context $OPS_GKE_2 get MeshPolicy -o json | jq '.items[].spec'
 
    `Output (do not copy)`
{
  "peers": [
    {
      "mtls": {
        "mode": "PERMISSIVE"
      }
    }
  ]
}

Istio è configurato su tutti i cluster utilizzando l'operatore Istio, che utilizza la risorsa personalizzata (CR) IstioControlPlane. Configureremo mTLS in tutti i cluster aggiornando la CR IstioControlPlane e il repository k8s. L'impostazione di global > mTLS > enabled: true nel CR IstioControlPlane comporta le seguenti due modifiche al control plane Istio:

  • MeshPolicy è impostata per attivare mTLS a livello di mesh per tutti i servizi in esecuzione in tutti i cluster.
  • Viene creata una DestinationRule per consentire il traffico ISTIO_MUTUAL tra i servizi in esecuzione in tutti i cluster.
  1. Applicheremo una patch kustomize al CR istioControlPlane per abilitare mTLS a livello di cluster. Copia la patch nella directory pertinente per tutti i cluster e aggiungi una patch kustomize.
cp -r $WORKDIR/asm/k8s_manifests/prod/app-mtls/mtls-kustomize-patch-replicated.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/istio-controlplane/mtls-kustomize-patch.yaml
cd $WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/istio-controlplane
kustomize edit add patch mtls-kustomize-patch.yaml

cp -r $WORKDIR/asm/k8s_manifests/prod/app-mtls/mtls-kustomize-patch-replicated.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/istio-controlplane/mtls-kustomize-patch.yaml
cd $WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/istio-controlplane
kustomize edit add patch mtls-kustomize-patch.yaml

cp -r $WORKDIR/asm/k8s_manifests/prod/app-mtls/mtls-kustomize-patch-shared.yaml \
$WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/istio-controlplane/mtls-kustomize-patch.yaml
cd $WORKDIR/k8s-repo/$DEV1_GKE_1_CLUSTER/istio-controlplane
kustomize edit add patch mtls-kustomize-patch.yaml

cp -r $WORKDIR/asm/k8s_manifests/prod/app-mtls/mtls-kustomize-patch-shared.yaml \
$WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/istio-controlplane/mtls-kustomize-patch.yaml
cd $WORKDIR/k8s-repo/$DEV1_GKE_2_CLUSTER/istio-controlplane
kustomize edit add patch mtls-kustomize-patch.yaml

cp -r $WORKDIR/asm/k8s_manifests/prod/app-mtls/mtls-kustomize-patch-shared.yaml \
$WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/istio-controlplane/mtls-kustomize-patch.yaml
cd $WORKDIR/k8s-repo/$DEV2_GKE_1_CLUSTER/istio-controlplane
kustomize edit add patch mtls-kustomize-patch.yaml

cp -r $WORKDIR/asm/k8s_manifests/prod/app-mtls/mtls-kustomize-patch-shared.yaml \
$WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/istio-controlplane/mtls-kustomize-patch.yaml
cd $WORKDIR/k8s-repo/$DEV2_GKE_2_CLUSTER/istio-controlplane
kustomize edit add patch mtls-kustomize-patch.yaml
 
  1. Esegui il commit in k8s-repo.
cd $WORKDIR/k8s-repo
git add . && git commit -am "turn mTLS on"
git push
 
  1. Visualizza lo stato di Cloud Build del progetto Ops in una scheda aperta in precedenza o facendo clic sul seguente link:
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_VAR_ops_project_name}"

 

Verifica mTLS

  1. Controlla di nuovo MeshPolicy nei cluster ops. Nota: mTLS non è più PERMISSIVE e consentirà solo il traffico mTLS.
kubectl --context $OPS_GKE_1 get MeshPolicy -o json | jq .items[].spec
kubectl --context $OPS_GKE_2 get MeshPolicy -o json | jq .items[].spec
 

Output (non copiare):

{
  "peers": [
    {
      "mtls": {}
    }
  ]
}
  1. Descrivi la DestinationRule creata dal controller dell'operatore Istio.
kubectl --context $OPS_GKE_1 get DestinationRule default -n istio-system -o json | jq '.spec'
kubectl --context $OPS_GKE_2 get DestinationRule default -n istio-system -o json | jq '.spec'

Output (non copiare):

{
    host: '*.local',
    trafficPolicy: {
      tls: {
        mode: ISTIO_MUTUAL
      }
   }
}

Nei log è visibile anche il passaggio da HTTP a HTTPS.

Possiamo esporre questo campo specifico dai log nell'interfaccia utente facendo clic su una voce di log e poi sul valore del campo che vuoi visualizzare. Nel nostro caso, fai clic su "http" accanto a "protocollo":

d92e0c88cd5b2132.png

In questo modo, puoi visualizzare facilmente il cambio di proprietà:

ea3d0240fa6fed81.png

10. Deployment canary

Obiettivo: implementare una nuova versione del servizio frontend.

  • Implementazione frontend-v2 (versione di produzione successiva) del servizio in una regione
  • Utilizza DestinationRules e VirtualServices per indirizzare lentamente il traffico a frontend-v2
  • Verifica la pipeline di deployment GitOps esaminando una serie di commit in k8s-repo

Istruzioni per il lab sul metodo di copia e incolla

Un deployment canary è un'implementazione progressiva di un nuovo servizio. In un deployment canary, invii una quantità crescente di traffico alla nuova versione, continuando a inviare la percentuale rimanente alla versione attuale. Un pattern comune consiste nell'eseguire un'analisi canary in ogni fase della suddivisione del traffico e confrontare i "golden signal" della nuova versione (latenza, tasso di errore, saturazione) con una baseline. In questo modo, si evitano interruzioni e si garantisce la stabilità del nuovo servizio "v2" in ogni fase della suddivisione del traffico.

In questa sezione imparerai a utilizzare Cloud Build e le policy di gestione del traffico Istio per creare un deployment canary di base per una nuova versione del servizio frontend.

Innanzitutto, eseguiamo la pipeline Canary nella regione DEV1 (us-west1) ed eseguiamo il roll-out del frontend v2 su entrambi i cluster in quella regione. In secondo luogo, eseguiremo la pipeline Canary nella regione DEV2 (us-central) e implementeremo la versione 2 su entrambi i cluster in quella regione. L'esecuzione della pipeline sulle regioni in ordine, anziché in parallelo in tutte le regioni, consente di evitare interruzioni globali causate da una configurazione errata o da bug nella stessa app v2.

Nota: attiveremo manualmente la pipeline Canary in entrambe le regioni, ma in produzione utilizzerai un trigger automatico, ad esempio in base a un nuovo tag dell'immagine Docker eseguito il push in un registro.

  1. Da Cloud Shell, definisci alcune variabili di ambiente per semplificare l'esecuzione del resto dei comandi.
CANARY_DIR="$WORKDIR/asm/k8s_manifests/prod/app-canary/"
K8S_REPO="$WORKDIR/k8s-repo"
 
  1. Esegui lo script repo_setup.sh per copiare i manifest di base in k8s-repo.
$CANARY_DIR/repo-setup.sh 
 

Vengono copiati i seguenti manifest:

  • Deployment frontend-v2
  • Patch frontend-v1 (per includere l'etichetta "v1" e un'immagine con un endpoint "/version")
  • respy, un piccolo pod che stamperà la distribuzione delle risposte HTTP e ci aiuterà a visualizzare il deployment canary in tempo reale.
  • DestinationRule Istio frontend: divide il servizio Kubernetes frontend in due sottoinsiemi, v1 e v2, in base all'etichetta di deployment "version"
  • VirtualService Istio frontend: indirizza il 100% del traffico al frontend v1. In questo modo viene sostituito il comportamento round robin predefinito del servizio Kubernetes, che invierebbe immediatamente il 50% di tutto il traffico regionale Dev1 al frontend v2.
  1. Esegui il commit delle modifiche in k8s_repo:
cd $K8S_REPO 
git add . && git commit -am "frontend canary setup"
git push
 
  1. Visualizza lo stato di Cloud Build del progetto Ops in una scheda aperta in precedenza o facendo clic sul seguente link:
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_VAR_ops_project_name}" 
 
  1. Vai a Cloud Build nella console per il progetto OPS1. Attendi il completamento della pipeline Cloud Build, quindi recupera i pod nello spazio dei nomi frontend in entrambi i cluster DEV1. Dovresti visualizzare quanto segue:
watch -n 1 kubectl --context $DEV1_GKE_1 get pods -n frontend 
 

Output (do not copy)

NAME                           READY   STATUS    RESTARTS   AGE
frontend-578b5c5db6-h9567      2/2     Running   0          59m
frontend-v2-54b74fc75b-fbxhc   2/2     Running   0          2m26s
respy-5f4664b5f6-ff22r         2/2     Running   0          2m26s

Utilizzeremo tmux per dividere la finestra di Cloud Shell in due riquadri:

  • Nel riquadro inferiore verrà eseguito il comando watch per osservare la distribuzione delle risposte HTTP per il servizio di frontend.
  • Il riquadro superiore eseguirà lo script della pipeline canary effettivo.
  1. Esegui il comando per dividere la finestra di Cloud Shell ed esegui il comando watch nel riquadro inferiore.
RESPY_POD=$(kubectl --context $DEV1_GKE_1 get pod \
-n frontend -l app=respy -o jsonpath='{..metadata.name}')
export TMUX_SESSION=$(tmux display-message -p '#S')
tmux split-window -d -t $TMUX_SESSION:0 -p33 \
-v "export KUBECONFIG=$WORKDIR/asm/gke/kubemesh; \
kubectl --context $DEV1_GKE_1 exec -n frontend -it \
$RESPY_POD -c respy /bin/sh -- -c 'watch -n 1 ./respy \
--u http://frontend:80/version --c 10 --n 500'; sleep 2"
 

Output (non copiare)

500 requests to http://frontend:80/version...
+----------+-------------------+
| RESPONSE | % OF 500 REQUESTS |
+----------+-------------------+
| v1       | 100.0%            |
|          |                   |
+----------+-------------------+
  1. Esegui la pipeline canary nella regione Dev1. Forniamo uno script che aggiorna le percentuali di traffico di frontend-v2 in VirtualService (aggiornando i pesi al 20%, 50%, 80% e poi 100%). Tra un aggiornamento e l'altro, lo script attende il completamento della pipeline Cloud Build. Esegui lo script di deployment canary per la regione Dev1. Nota: il completamento di questo script richiede circa 10 minuti.
K8S_REPO=$K8S_REPO CANARY_DIR=$CANARY_DIR \
OPS_DIR=$OPS_GKE_1_CLUSTER OPS_CONTEXT=$OPS_GKE_1 \
${CANARY_DIR}/auto-canary.sh
 

Puoi vedere la suddivisione del traffico in tempo reale nella finestra in basso in cui esegui il comando respy. Ad esempio, al 20%:

Output (non copiare)

500 requests to http://frontend:80/version...
+----------+-------------------+
| RESPONSE | % OF 500 REQUESTS |
+----------+-------------------+
| v1       | 79.4%             |
|          |                   |
| v2       | 20.6%             |
|          |                   |
+----------+-------------------+
  1. Una volta completata l'implementazione di Dev2 per frontend-v2, dovresti visualizzare un messaggio di operazione riuscita alla fine dello script:
     Output (do not copy) 
    
✅ 100% successfully deployed
🌈 frontend-v2 Canary Complete for gke-asm-1-r1-prod
  1. Inoltre, tutto il traffico frontend da un pod Dev2 deve essere indirizzato a frontend-v2:
     Output (do not copy) 
    
500 requests to http://frontend:80/version...
+----------+-------------------+
| RESPONSE | % OF 500 REQUESTS |
+----------+-------------------+
| v2       | 100.0%            |
|          |                   |
+----------+-------------------+
  1. Chiudi il riquadro diviso.
tmux respawn-pane -t ${TMUX_SESSION}:0.1 -k 'exit'
 
  1. Vai a Cloud Source Repos al link generato.
echo https://source.developers.google.com/p/$TF_VAR_ops_project_name/r/k8s-repo

Dovresti visualizzare un commit separato per ogni percentuale di traffico, con il commit più recente in cima all'elenco:

b87b85f52fd2ff0f.png

Ora ripeti la stessa procedura per la regione Dev2. Tieni presente che la regione Dev2 è ancora "bloccata" sulla versione 1. Questo perché nello script baseline repo_setup abbiamo eseguito il push di un VirtualService per inviare esplicitamente tutto il traffico alla versione 1. In questo modo, abbiamo potuto eseguire in sicurezza un canary regionale su Dev1 e assicurarci che funzionasse correttamente prima di implementare la nuova versione a livello globale.

  1. Esegui il comando per dividere la finestra di Cloud Shell ed esegui il comando watch nel riquadro inferiore.
RESPY_POD=$(kubectl --context $DEV2_GKE_1 get pod \
-n frontend -l app=respy -o jsonpath='{..metadata.name}')
export TMUX_SESSION=$(tmux display-message -p '#S')
tmux split-window -d -t $TMUX_SESSION:0 -p33 \
-v "export KUBECONFIG=$WORKDIR/asm/gke/kubemesh; \
kubectl --context $DEV2_GKE_1 exec -n frontend -it \
$RESPY_POD -c respy /bin/sh -- -c 'watch -n 1 ./respy \
--u http://frontend:80/version --c 10 --n 500'; sleep 2"
 

Output (non copiare)

500 requests to http://frontend:80/version...
+----------+-------------------+
| RESPONSE | % OF 500 REQUESTS |
+----------+-------------------+
| v1       | 100.0%            |
|          |                   |
+----------+-------------------+
  1. Esegui la pipeline canary nella regione Dev2. Forniamo uno script che aggiorna le percentuali di traffico di frontend-v2 in VirtualService (aggiornando i pesi al 20%, 50%, 80% e poi 100%). Tra un aggiornamento e l'altro, lo script attende il completamento della pipeline Cloud Build. Esegui lo script di deployment canary per la regione Dev1. Nota: il completamento di questo script richiede circa 10 minuti.
K8S_REPO=$K8S_REPO CANARY_DIR=$CANARY_DIR \
OPS_DIR=$OPS_GKE_2_CLUSTER OPS_CONTEXT=$OPS_GKE_2 \
${CANARY_DIR}/auto-canary.sh
 

Output (non copiare)

500 requests to http://frontend:80/version...
+----------+-------------------+
| RESPONSE | % OF 500 REQUESTS |
+----------+-------------------+
| v1       | 100.0%            |
|          |                   |
+----------+-------------------+
  1. Dal pod Respy in Dev2, osserva il traffico dei pod Dev2 passare progressivamente dal frontend v1 alla v2. Al termine dello script, dovresti visualizzare:

Output (non copiare)

500 requests to http://frontend:80/version...
+----------+-------------------+
| RESPONSE | % OF 500 REQUESTS |
+----------+-------------------+
| v2       | 100.0%            |
|          |                   |
+----------+-------------------+
  1. Chiudi il riquadro diviso.
tmux respawn-pane -t ${TMUX_SESSION}:0.1 -k 'exit'

Questa sezione ha introdotto l'utilizzo di Istio per i deployment canary regionali. In produzione, anziché uno script manuale, puoi attivare automaticamente questo script canary come pipeline Cloud Build, utilizzando un trigger come una nuova immagine taggata di cui è stato eseguito il push in un registro container. Ti consigliamo inoltre di aggiungere l'analisi canary tra un passaggio e l'altro, analizzando la latenza e il tasso di errori della versione 2 rispetto a una soglia di sicurezza predefinita, prima di inviare altro traffico.

11. Policy di autorizzazione

Obiettivo: configurare il controllo dell'accesso basato sui ruoli tra i microservizi (AuthZ).

  • Crea AuthorizationPolicy per NEGARE l'accesso a un microservizio
  • Crea AuthorizationPolicy per CONSENTIRE l'accesso specifico a un microservizio

Istruzioni per il lab sul metodo di copia e incolla

A differenza di un'applicazione monolitica che potrebbe essere eseguita in un'unica posizione, le app di microservizi distribuite a livello globale effettuano chiamate oltre i confini della rete. Ciò significa più punti di accesso alle applicazioni e più opportunità per attacchi dannosi. Poiché i pod Kubernetes hanno IP temporanei, le regole firewall tradizionali basate su IP non sono più adeguate per proteggere l'accesso tra i workload. In un'architettura di microservizi, è necessario un nuovo approccio alla sicurezza. Basandosi sui blocchi di base della sicurezza di Kubernetes, come i service account, Istio fornisce un insieme flessibile di norme di sicurezza per le tue applicazioni.

I criteri Istio coprono sia l'autenticazione che l'autorizzazione. L'autenticazione verifica l'identità (questo server è chi dice di essere?) e l'autorizzazione verifica le autorizzazioni (questo client è autorizzato a farlo?). Abbiamo trattato l'autenticazione Istio nella sezione TLS reciproca del Modulo 1 (MeshPolicy). In questa sezione, impareremo a utilizzare le policy di autorizzazione di Istio per controllare l'accesso a uno dei nostri carichi di lavoro dell'applicazione, currencyservice.

Innanzitutto, implementeremo un AuthorizationPolicy in tutti e quattro i cluster di sviluppo, chiudendo l'accesso a currencyservice e attivando un errore nel frontend. A questo punto, consentiremo solo al servizio frontend di accedere a currencyservice.

  1. Esamina i contenuti di currency-deny-all.yaml. Questa policy utilizza i selettori di etichette di deployment per limitare l'accesso a currencyservice. Nota che non è presente alcun campo spec. Ciò significa che questo criterio negherà l'accesso al servizio selezionato.
cat $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-deny-all.yaml
 

Output (non copiare)

apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
  name: "currency-policy"
  namespace: currency
spec:
  selector:
    matchLabels:
      app: currencyservice
  1. Copia la policy relativa alla valuta in k8s-repo per i cluster ops in entrambe le regioni.
cp $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-deny-all.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-authorization/currency-policy.yaml
cd $WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-authorization
kustomize edit add resource currency-policy.yaml
cp $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-deny-all.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-authorization/currency-policy.yaml
cd $WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-authorization
kustomize edit add resource currency-policy.yaml
  1. Esegui il push delle modifiche.
cd $WORKDIR/k8s-repo 
git add . && git commit -am "AuthorizationPolicy - currency: deny all"
git push 
  1. Controlla lo stato di Cloud Build del progetto Ops in una scheda aperta in precedenza o facendo clic sul seguente link:
echo https://console.cloud.google.com/cloud-build/builds?project=$TF_VAR_ops_project_name 
 
  1. Al termine della build, prova a raggiungere il frontend di hipstershop in un browser al seguente link:
echo "https://frontend.endpoints.$TF_VAR_ops_project_name.cloud.goog" 
 

Dovresti visualizzare un errore di autorizzazione da currencyservice:

f120f3d30d6ee9f.png

  1. Vediamo come il servizio di valuta applica questo AuthorizationPolicy. Innanzitutto, attiva i log a livello di traccia sul proxy Envoy per uno dei pod di valuta, poiché le chiamate di autorizzazione bloccate non vengono registrate per impostazione predefinita.
CURRENCY_POD=$(kubectl --context $DEV1_GKE_2 get pod -n currency | grep currency| awk '{ print $1 }')
kubectl --context $DEV1_GKE_2 exec -it $CURRENCY_POD -n \
currency -c istio-proxy -- curl -X POST \
"http://localhost:15000/logging?level=trace"
 
  1. Recupera i log RBAC (autorizzazione) dal proxy sidecar del servizio di valuta. Dovresti visualizzare il messaggio "enforced denied" (rifiuto forzato), che indica che currencyservice è impostato per bloccare tutte le richieste in entrata.
kubectl --context $DEV1_GKE_2 logs -n currency $CURRENCY_POD \
-c istio-proxy | grep -m 3 rbac
 

Output (non copiare)

[Envoy (Epoch 0)] [2020-01-30 00:45:50.815][22][debug][rbac] [external/envoy/source/extensions/filters/http/rbac/rbac_filter.cc:67] checking request: remoteAddress: 10.16.5.15:37310, localAddress: 10.16.3.8:7000, ssl: uriSanPeerCertificate: spiffe://cluster.local/ns/frontend/sa/frontend, subjectPeerCertificate: , headers: ':method', 'POST'
[Envoy (Epoch 0)] [2020-01-30 00:45:50.815][22][debug][rbac] [external/envoy/source/extensions/filters/http/rbac/rbac_filter.cc:118] enforced denied
[Envoy (Epoch 0)] [2020-01-30 00:45:50.815][22][debug][http] [external/envoy/source/common/http/conn_manager_impl.cc:1354] [C115][S17310331589050212978] Sending local reply with details rbac_access_denied
  1. Ora consenti al frontend, ma non agli altri servizi di backend, di accedere a currencyservice. Apri currency-allow-frontend.yaml e ispeziona i contenuti. Tieni presente che abbiamo aggiunto la seguente regola:
cat ${WORKDIR}/asm/k8s_manifests/prod/app-authorization/currency-allow-frontend.yaml

Output (non copiare)

rules:
 - from:
   - source:
       principals: ["cluster.local/ns/frontend/sa/frontend"]

Qui, inseriamo nella lista consentita un source.principal (client) specifico per accedere al servizio di valuta. Questo source.principal è definito da Kubernetes Service Account. In questo caso, il service account che inseriamo nella lista consentita è il service account frontend nello spazio dei nomi frontend.

Nota:quando utilizzi i service account Kubernetes in AuthorizationPolicies di Istio, devi prima abilitare TLS reciproco a livello di cluster, come abbiamo fatto nel modulo 1. per garantire che le credenziali del service account vengano montate nelle richieste.

  1. Copia le norme aggiornate sulla valuta
cp $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-allow-frontend.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-authorization/currency-policy.yaml
cp $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-allow-frontend.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-authorization/currency-policy.yaml
 
  1. Esegui il push delle modifiche.
cd $WORKDIR/k8s-repo
git add . && git commit -am "AuthorizationPolicy - currency: allow frontend"
git push
 
  1. Visualizza lo stato di Cloud Build del progetto Ops in una scheda aperta in precedenza o facendo clic sul seguente link:
echo https://console.cloud.google.com/cloud-build/builds?project=$TF_VAR_ops_project_name
  1. Al termine della build, apri di nuovo il frontend di Hipstershop. Questa volta non dovresti visualizzare errori nella home page, perché al frontend è consentito esplicitamente l'accesso al servizio corrente.
  2. Ora prova a eseguire un pagamento aggiungendo articoli al carrello e facendo clic su "Effettua ordine". Questa volta dovresti visualizzare un errore di conversione del prezzo dal servizio di valuta. Questo perché abbiamo inserito nella lista bianca solo il frontend, quindi checkoutservice non è ancora in grado di accedere a currencyservice.

7e30813d693675fe.png

  1. Infine, consentiamo al servizio di pagamento di accedere alla valuta aggiungendo un'altra regola al nostro AuthorizationPolicy currencyservice. Tieni presente che stiamo aprendo l'accesso alla valuta solo ai due servizi che devono accedervi: frontend e pagamento. Gli altri backend verranno comunque bloccati.
  2. Apri currency-allow-frontend-checkout.yaml e ispeziona i contenuti. Tieni presente che l'elenco delle regole funziona come un OR logico: la valuta accetterà solo le richieste dei carichi di lavoro con uno di questi due service account.
cat ${WORKDIR}/asm/k8s_manifests/prod/app-authorization/currency-allow-frontend-checkout.yaml
 

Output (non copiare)

apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
  name: "currency-policy"
  namespace: currency
spec:
  selector:
    matchLabels:
      app: currencyservice
  rules:
  - from:
    - source:
        principals: ["cluster.local/ns/frontend/sa/frontend"]
  - from:
    - source:
        principals: ["cluster.local/ns/checkout/sa/checkout"]
  1. Copia la policy di autorizzazione finale in k8s-repo.
cp $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-allow-frontend-checkout.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_1_CLUSTER/app-authorization/currency-policy.yaml
cp $WORKDIR/asm/k8s_manifests/prod/app-authorization/currency-allow-frontend-checkout.yaml \
$WORKDIR/k8s-repo/$OPS_GKE_2_CLUSTER/app-authorization/currency-policy.yaml
 
  1. Esegui il push delle modifiche
cd $WORKDIR/k8s-repo 
git add . && git commit -am "AuthorizationPolicy - currency: allow frontend and checkout"
git push
 
  1. Visualizza lo stato di Cloud Build del progetto Ops in una scheda aperta in precedenza o facendo clic sul seguente link:
echo https://console.cloud.google.com/cloud-build/builds?project=$TF_VAR_ops_project_name
 
  1. Al termine della build, prova a eseguire un pagamento. L'operazione dovrebbe andare a buon fine.

Questa sezione ha illustrato come utilizzare le policy di autorizzazione Istio per applicare il controllo degli accessi granulare a livello di servizio. In produzione, puoi creare una AuthorizationPolicy per servizio e (ad esempio) utilizzare un criterio di autorizzazione totale per consentire a tutti i workload nello stesso spazio dei nomi di accedere l'uno all'altro.

12. Scalabilità dell'infrastruttura

Obiettivo: scalare l'infrastruttura aggiungendo nuove regioni, progetti e cluster.

  • Clona il repository infrastructure
  • Aggiorna i file Terraform per creare nuove risorse
  • 2 subnet nella nuova regione (una per il progetto ops e una per il nuovo progetto)
  • Nuovo cluster delle operazioni nella nuova regione (nella nuova subnet)
  • Nuovo control plane Istio per la nuova regione
  • 2 cluster di app nel nuovo progetto nella nuova regione
  • Esegui il commit nel repository infrastructure
  • Verifica installazione

Istruzioni per il lab sul metodo di copia e incolla

Esistono diversi modi per scalare una piattaforma. Puoi aggiungere ulteriore potenza di calcolo aggiungendo nodi ai cluster esistenti. Puoi aggiungere altri cluster in una regione. In alternativa, puoi aggiungere altre regioni alla piattaforma. La decisione su quale aspetto della piattaforma scalare dipende dai requisiti. Ad esempio, se hai cluster in tutte e tre le zone di una regione, potrebbe essere sufficiente aggiungere altri nodi (o node pool) al cluster esistente. Tuttavia, se hai cluster in due delle tre zone di una singola regione, l'aggiunta di un nuovo cluster nella terza zona ti offre scalabilità e un ulteriore dominio di errore (ovvero una nuova zona). Un altro motivo per aggiungere un nuovo cluster in una regione potrebbe essere la necessità di creare un cluster single-tenant per motivi normativi o di conformità (ad esempio PCI o un cluster di database che contiene informazioni PII). Man mano che la tua attività e i tuoi servizi si espandono, l'aggiunta di nuove regioni diventa inevitabile per fornire servizi più vicini ai clienti.

La piattaforma attuale è costituita da due regioni e cluster in due zone per regione. Puoi pensare di scalare la piattaforma in due modi:

  • Verticalmente: all'interno di ogni regione aggiungendo ulteriore potenza di calcolo. Ciò avviene aggiungendo altri nodi (o pool di nodi) ai cluster esistenti o aggiungendo nuovi cluster all'interno della regione. Ciò avviene tramite il repository infrastructure. Il percorso più semplice è aggiungere nodi ai cluster esistenti. Non occorrono ulteriori configurazioni. L'aggiunta di nuovi cluster potrebbe richiedere subnet (e intervalli secondari) aggiuntive, l'aggiunta di regole firewall appropriate, l'aggiunta dei nuovi cluster al piano di controllo del service mesh ASM/Istio regionale e il deployment delle risorse dell'applicazione nei nuovi cluster.
  • Orizzontalmente: aggiungendo altre regioni. La piattaforma attuale ti offre un modello regionale. È costituito da un cluster ops regionale in cui risiede il control plane ASM/Istio e da due (o più) cluster di applicazioni zonali in cui vengono eseguito il deployment delle risorse dell'applicazione.

In questo workshop, la scalabilità della piattaforma è "orizzontale", in quanto comprende anche i passaggi del caso d'uso verticale. Per scalare orizzontalmente la piattaforma aggiungendo una nuova regione (r3), è necessario aggiungere le seguenti risorse:

  1. Subnet nel VPC condiviso del progetto host nella regione r3 per i nuovi cluster ops e applicazioni.
  2. Un cluster ops regionale nella regione r3 in cui si trova il control plane ASM/Istio.
  3. Due cluster di applicazioni a livello di zona in due zone nella regione r3.
  4. Aggiorna il repository k8s:
  5. Esegui il deployment delle risorse del control plane ASM/Istio nel cluster ops nella regione r3.
  6. Esegui il deployment delle risorse del control plane condiviso ASM/Istio nei cluster delle app nella regione r3.
  7. Anche se non devi creare un nuovo progetto, i passaggi del workshop mostrano l'aggiunta di un nuovo progetto dev3 per coprire il caso d'uso dell'aggiunta di un nuovo team alla piattaforma.

Il repository dell'infrastruttura viene utilizzato per aggiungere le nuove risorse indicate sopra.

  1. In Cloud Shell, vai a WORKDIR e clona il repository infrastructure.
mkdir -p $WORKDIR/infra-repo
cd $WORKDIR/infra-repo
git init && git remote add origin https://source.developers.google.com/p/${TF_ADMIN}/r/infrastructure
git config --local user.email ${MY_USER}
git config --local user.name "infra repo user"
git config --local credential.'https://source.developers.google.com'.helper gcloud.sh
git pull origin master
  1. Clona il ramo add-proj del repository di codice sorgente del workshop nella directory add-proj-repo.
cd $WORKDIR
git clone https://github.com/GoogleCloudPlatform/anthos-service-mesh-workshop.git add-proj-repo -b add-proj

 
  1. Copia i file dal ramo add-proj nel repository del workshop di origine. Il ramo add-proj contiene le modifiche per questa sezione.
cp -r $WORKDIR/add-proj-repo/infrastructure/* $WORKDIR/infra-repo/
 
  1. Sostituisci la directory infrastructure nella directory del repository add-proj con un collegamento simbolico alla directory infra-repo per consentire l'esecuzione degli script sul ramo.
rm -rf $WORKDIR/add-proj-repo/infrastructure
ln -s $WORKDIR/infra-repo $WORKDIR/add-proj-repo/infrastructure
 
  1. Esegui lo script add-project.sh per copiare gli stati e le variabili condivisi nella nuova struttura di directory del progetto.
$WORKDIR/add-proj-repo/scripts/add-project.sh app3 $WORKDIR/asm $WORKDIR/infra-repo
  1. Esegui il commit e il push delle modifiche per creare un nuovo progetto
cd $WORKDIR/infra-repo
git add .
git status
git commit -m "add new project" && git push origin master
 

  1. Il commit attiva il repository infrastructure per il deployment dell'infrastruttura con le nuove risorse. Visualizza l'avanzamento di Cloud Build facendo clic sull'output del seguente link e passando all'ultima build in alto.
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_ADMIN}"
 

L'ultimo passaggio di infrastructure Cloud Build crea nuove risorse Kubernetes in k8s-repo. In questo modo viene attivata la build di Cloud Build in k8s-repo (nel progetto ops). Le nuove risorse Kubernetes sono per i tre nuovi cluster aggiunti nel passaggio precedente. Le risorse del control plane ASM/Istio e del control plane condiviso vengono aggiunte ai nuovi cluster con k8s-repo Cloud Build.

  1. Al termine della build dell'infrastruttura di Cloud Build, vai all'k8s-repoultima esecuzione di Cloud Build facendo clic sul seguente link di output.
echo "https://console.cloud.google.com/cloud-build/builds?project=${TF_VAR_ops_project_name}"
 
  1. Esegui questo script per aggiungere i nuovi cluster al file vars e kubeconfig.
$WORKDIR/add-proj-repo/scripts/setup-gke-vars-kubeconfig-add-proj.sh $WORKDIR/asm
 
  1. Modifica la variabile KUBECONFIG in modo che rimandi al nuovo file kubeconfig.
source $WORKDIR/asm/vars/vars.sh
export KUBECONFIG=$WORKDIR/asm/gke/kubemesh
 
  1. Elenca i contesti del cluster. Dovresti vedere otto cluster.
kubectl config view -ojson | jq -r '.clusters[].name'
 
    `Output (do not copy)`
gke_user001-200204-05-dev1-49tqc4_us-west1-a_gke-1-apps-r1a-prod
gke_user001-200204-05-dev1-49tqc4_us-west1-b_gke-2-apps-r1b-prod
gke_user001-200204-05-dev2-49tqc4_us-central1-a_gke-3-apps-r2a-prod
gke_user001-200204-05-dev2-49tqc4_us-central1-b_gke-4-apps-r2b-prod
gke_user001-200204-05-dev3-49tqc4_us-east1-b_gke-5-apps-r3b-prod
gke_user001-200204-05-dev3-49tqc4_us-east1-c_gke-6-apps-r3c-prod
gke_user001-200204-05-ops-49tqc4_us-central1_gke-asm-2-r2-prod
gke_user001-200204-05-ops-49tqc4_us-east1_gke-asm-3-r3-prod
gke_user001-200204-05-ops-49tqc4_us-west1_gke-asm-1-r1-prod

Verifica l'installazione di Istio

  1. Assicurati che Istio sia installato nel nuovo cluster ops controllando che tutti i pod siano in esecuzione e che i job siano stati completati.
kubectl --context $OPS_GKE_3 get pods -n istio-system
 
    `Output (do not copy)`
NAME                                      READY   STATUS    RESTARTS   AGE
grafana-5f798469fd-72g6w                  1/1     Running   0          5h12m
istio-citadel-7d8595845-hmmvj             1/1     Running   0          5h12m
istio-egressgateway-779b87c464-rw8bg      1/1     Running   0          5h12m
istio-galley-844ddfc788-zzpkl             2/2     Running   0          5h12m
istio-ingressgateway-59ccd6574b-xfj98     1/1     Running   0          5h12m
istio-pilot-7c8989f5cf-5plsg              2/2     Running   0          5h12m
istio-policy-6674bc7678-2shrk             2/2     Running   3          5h12m
istio-sidecar-injector-7795bb5888-kbl5p   1/1     Running   0          5h12m
istio-telemetry-5fd7cbbb47-c4q7b          2/2     Running   2          5h12m
istio-tracing-cd67ddf8-2qwkd              1/1     Running   0          5h12m
istiocoredns-5f7546c6f4-qhj9k             2/2     Running   0          5h12m
kiali-7964898d8c-l74ww                    1/1     Running   0          5h12m
prometheus-586d4445c7-x9ln6               1/1     Running   0          5h12m
  1. Assicurati che Istio sia installato su entrambi i cluster dev3. Solo Citadel, sidecar-injector e coredns vengono eseguiti nei cluster dev3. Condividono un control plane Istio in esecuzione nel cluster ops-3.
kubectl --context $DEV3_GKE_1 get pods -n istio-system
kubectl --context $DEV3_GKE_2 get pods -n istio-system
 
    `Output (do not copy)`
NAME                                      READY   STATUS    RESTARTS   AGE
istio-citadel-568747d88-4lj9b             1/1     Running   0          66s
istio-sidecar-injector-759bf6b4bc-ks5br   1/1     Running   0          66s
istiocoredns-5f7546c6f4-qbsqm             2/2     Running   0          78s

Verifica il service discovery per i control plane condivisi

  1. Verifica che i secret siano implementati in tutti i cluster ops per tutti e sei i cluster di applicazioni.
kubectl --context $OPS_GKE_1 get secrets -l istio/multiCluster=true -n istio-system
kubectl --context $OPS_GKE_2 get secrets -l istio/multiCluster=true -n istio-system
kubectl --context $OPS_GKE_3 get secrets -l istio/multiCluster=true -n istio-system
 
    `Output (do not copy)`
NAME                  TYPE     DATA   AGE
gke-1-apps-r1a-prod   Opaque   1      14h
gke-2-apps-r1b-prod   Opaque   1      14h
gke-3-apps-r2a-prod   Opaque   1      14h
gke-4-apps-r2b-prod   Opaque   1      14h
gke-5-apps-r3b-prod   Opaque   1      5h12m
gke-6-apps-r3c-prod   Opaque   1      5h12m

13. Interruzione del circuito

Obiettivo: implementare un interruttore di sicurezza per il servizio di spedizione.

  • Crea un DestinationRule per il servizio shipping per implementare un interruttore automatico
  • Utilizza fortio (un'utilità di generazione del carico) per convalidare l'interruttore di sicurezza per il servizio shipping forzando lo sgancio dell'interruttore

Istruzioni per il Fast Track Script Lab

Fast Track Script Lab sarà disponibile a breve.

Istruzioni per il lab sul metodo di copia e incolla

Ora che abbiamo appreso alcune strategie di base di monitoraggio e risoluzione dei problemi per i servizi abilitati a Istio, vediamo in che modo Istio ti aiuta a migliorare la resilienza dei tuoi servizi, riducendo la quantità di risoluzione dei problemi che dovrai eseguire in primo luogo.

Un'architettura di microservizi introduce il rischio di errori a cascata, in cui l'errore di un servizio può propagarsi alle sue dipendenze e alle dipendenze di queste dipendenze, causando un'interruzione a "effetto domino" che può potenzialmente interessare gli utenti finali. Istio fornisce una policy di gestione del traffico con interruttore di sicurezza per aiutarti a isolare i servizi, proteggendo i servizi downstream (lato client) dall'attesa di servizi non funzionanti e i servizi upstream (lato server) da un'improvvisa inondazione di traffico downstream quando tornano online. Nel complesso, l'utilizzo di interruttori automatici può aiutarti a evitare che tutti i tuoi servizi non rispettino i contratti di livello di servizio a causa di un servizio di backend bloccato.

Il pattern dell'interruttore di sicurezza prende il nome da un interruttore elettrico che può "scattare" quando il flusso di elettricità è eccessivo, proteggendo i dispositivi dal sovraccarico. In una configurazione Istio, ciò significa che Envoy è l'interruttore automatico, che tiene traccia del numero di richieste in attesa per un servizio. In questo stato chiuso predefinito, le richieste vengono trasmesse tramite Envoy senza interruzioni.

Tuttavia, quando il numero di richieste in attesa supera la soglia definita, l'interruttore automatico si attiva (si apre) ed Envoy restituisce immediatamente un errore. In questo modo, il server può rilevare rapidamente gli errori per il client e impedisce al codice dell'applicazione server di ricevere la richiesta del client in caso di sovraccarico.

Dopodiché, dopo il timeout definito, Envoy passa a uno stato di apertura parziale, in cui il server può ricominciare a ricevere richieste in modo probatorio e, se riesce a rispondere correttamente alle richieste, l'interruttore di sicurezza si chiude di nuovo e le richieste al server ricominciano a fluire.

Questo diagramma riassume il pattern di interruttore di sicurezza di Istio. I rettangoli blu rappresentano Envoy, il cerchio blu pieno rappresenta il client e i cerchi bianchi pieni rappresentano il contenitore del server:

2127a0a172ff4802.png

Puoi definire le norme di interruzione del circuito utilizzando Istio DestinationRules. In questa sezione, applicheremo il seguente criterio per forzare un interruttore automatico per il servizio di spedizione:

Output (do not copy)

apiVersion: "networking.istio.io/v1alpha3"
kind: "DestinationRule"
metadata:
  name: "shippingservice-shipping-destrule"
  namespace: "shipping"
spec:
  host: "shippingservice.shipping.svc.cluster.local"
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL
    connectionPool:
      tcp:
        maxConnections: 1
      http:
        http1MaxPendingRequests: 1
        maxRequestsPerConnection: 1
    outlierDetection:
      consecutiveErrors: 1
      interval: 1s
      baseEjectionTime: 10s
      maxEjectionPercent: 100

Qui sono da notare due campi DestinationRule. connectionPool definisce il numero di connessioni consentite da questo servizio. Il campo outlierDetection è il punto in cui configuriamo il modo in cui Envoy determinerà la soglia a cui aprire l'interruttore automatico. Qui, ogni secondo (intervallo), Envoy conterà il numero di errori ricevuti dal contenitore del server. Se supera la soglia di consecutiveErrors, l'interruttore automatico Envoy si aprirà e il 100% dei pod productcatalog verrà protetto dalle nuove richieste dei client per 10 secondi. Una volta aperto (ovvero attivo) l'interruttore automatico Envoy, i client riceveranno errori 503 (Servizio non disponibile). Vediamo come funziona.

  1. Imposta le variabili di ambiente per le directory k8s-repo e asm per semplificare i comandi.
export K8S_REPO="${WORKDIR}/k8s-repo"
export ASM="${WORKDIR}/asm" 
 
  1. Aggiorna k8s-repo
cd $WORKDIR/k8s-repo
git pull
cd $WORKDIR
  1. Aggiorna la DestinationRule del servizio di spedizione su entrambi i cluster Ops.
cp $ASM/k8s_manifests/prod/istio-networking/app-shipping-circuit-breaker.yaml ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/app-shipping-circuit-breaker.yaml
cp $ASM/k8s_manifests/prod/istio-networking/app-shipping-circuit-breaker.yaml ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/app-shipping-circuit-breaker.yaml

cd ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/; kustomize edit add resource app-shipping-circuit-breaker.yaml
cd ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/; kustomize edit add resource app-shipping-circuit-breaker.yaml
 
  1. Copia un pod del generatore di carico Fortio nel cluster GKE_1 nella regione Dev1. Questo è il pod client che utilizzeremo per "attivare " l'interruttore automatico per shippingservice.
cp $ASM/k8s_manifests/prod/app/deployments/app-fortio.yaml ${K8S_REPO}/${DEV1_GKE_1_CLUSTER}/app/deployments/
cd ${K8S_REPO}/${DEV1_GKE_1_CLUSTER}/app/deployments; kustomize edit add resource app-fortio.yaml
 
  1. Esegui il commit delle modifiche.
cd $K8S_REPO 
git add . && git commit -am "Circuit Breaker: shippingservice"
git push
cd $ASM
 
  1. Attendi il completamento di Cloud Build.
  2. In Cloud Shell, utilizza il pod fortio per inviare traffico gRPC a shippingservice con 1 connessione simultanea e 1000 richieste totali. In questo modo non si attiverà l'interruttore automatico perché non abbiamo ancora superato le impostazioni connectionPool.
FORTIO_POD=$(kubectl --context ${DEV1_GKE_1} get pod -n shipping | grep fortio | awk '{ print $1 }')

kubectl --context ${DEV1_GKE_1} exec -it $FORTIO_POD -n shipping -c fortio /usr/bin/fortio -- load -grpc -c 1 -n 1000 -qps 0 shippingservice.shipping.svc.cluster.local:50051 
 

Output (non copiare)

Health SERVING : 1000
All done 1000 calls (plus 0 warmup) 4.968 ms avg, 201.2 qps
  1. Ora esegui di nuovo fortio, aumentando il numero di connessioni simultanee a 2, ma mantenendo costante il numero totale di richieste. Dovremmo vedere fino a due terzi delle richieste restituire un errore "overflow", perché l'interruttore automatico è scattato:nella policy che abbiamo definito, è consentita una sola connessione simultanea in un intervallo di 1 secondo.
kubectl --context ${DEV1_GKE_1} exec -it $FORTIO_POD -n shipping -c fortio /usr/bin/fortio -- load -grpc -c 2 -n 1000 -qps 0 shippingservice.shipping.svc.cluster.local:50051 
 

Output (non copiare)

18:46:16 W grpcrunner.go:107> Error making grpc call: rpc error: code = Unavailable desc = upstream connect error or disconnect/reset before headers. reset reason: overflow
...

Health ERROR : 625
Health SERVING : 375
All done 1000 calls (plus 0 warmup) 12.118 ms avg, 96.1 qps
  1. Envoy tiene traccia del numero di connessioni interrotte quando l'interruttore automatico è attivo, con la metrica upstream_rq_pending_overflow. Troviamo questo nel pod fortio:
kubectl --context ${DEV1_GKE_1} exec -it $FORTIO_POD -n shipping -c istio-proxy  -- sh -c 'curl localhost:15000/stats' | grep shipping | grep pending
 

Output (non copiare)

cluster.outbound|50051||shippingservice.shipping.svc.cluster.local.circuit_breakers.default.rq_pending_open: 0
cluster.outbound|50051||shippingservice.shipping.svc.cluster.local.circuit_breakers.high.rq_pending_open: 0
cluster.outbound|50051||shippingservice.shipping.svc.cluster.local.upstream_rq_pending_active: 0
cluster.outbound|50051||shippingservice.shipping.svc.cluster.local.upstream_rq_pending_failure_eject: 9
cluster.outbound|50051||shippingservice.shipping.svc.cluster.local.upstream_rq_pending_overflow: 565
cluster.outbound|50051||shippingservice.shipping.svc.cluster.local.upstream_rq_pending_total: 1433
  1. Esegui la pulizia rimuovendo il criterio di interruzione del circuito da entrambe le regioni.
kubectl --context ${OPS_GKE_1} delete destinationrule shippingservice-circuit-breaker -n shipping 
rm ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/app-shipping-circuit-breaker.yaml
cd ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/; kustomize edit remove resource app-shipping-circuit-breaker.yaml
 

kubectl --context ${OPS_GKE_2} delete destinationrule shippingservice-circuit-breaker -n shipping 
rm ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/app-shipping-circuit-breaker.yaml
cd ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/; kustomize edit remove resource app-shipping-circuit-breaker.yaml
cd $K8S_REPO; git add .; git commit -m "Circuit Breaker: cleanup"; git push origin master
 

Questa sezione ha mostrato come configurare un'unica policy di interruzione del circuito per un servizio. Una best practice consiste nell'impostare un interruttore automatico per qualsiasi servizio upstream (backend) che potrebbe bloccarsi. Applicando le policy di interruzione del circuito di Istio, contribuisci a isolare i microservizi, a integrare la tolleranza agli errori nella tua architettura e a ridurre il rischio di errori a cascata in condizioni di carico elevato.

14. Fault Injection

Obiettivo: testare la resilienza del servizio di consigli introducendo ritardi (prima che venga eseguito il push in produzione).

  • Crea un VirtualService per il servizio recommendation per introdurre un ritardo di 5 secondi
  • Testa il ritardo utilizzando il generatore di carico fortio
  • Rimuovi il ritardo in VirtualService e convalida

Istruzioni per il Fast Track Script Lab

Fast Track Script Lab sarà disponibile a breve.

Istruzioni per il lab sul metodo di copia e incolla

L'aggiunta di policy di interruzione automatica ai tuoi servizi è un modo per aumentare la resilienza rispetto ai servizi in produzione. Tuttavia, l'interruzione del circuito provoca guasti, potenzialmente errori rivolti agli utenti, il che non è l'ideale. Per anticipare questi casi di errore e prevedere meglio come potrebbero rispondere i servizi downstream quando i backend restituiscono errori, puoi adottare il chaos testing in un ambiente di staging. Il chaos testing è la pratica di interrompere deliberatamente i servizi per analizzare i punti deboli del sistema e migliorare la tolleranza agli errori. Puoi anche utilizzare il chaos testing per identificare i modi per mitigare gli errori rivolti agli utenti quando i backend non funzionano, ad esempio visualizzando un risultato memorizzato nella cache in un frontend.

L'utilizzo di Istio per l'inserimento di errori è utile perché puoi utilizzare le immagini di rilascio di produzione e aggiungere l'errore a livello di rete, anziché modificare il codice sorgente. In produzione, potresti utilizzare uno strumento di test del caos completo per testare la resilienza a livello di Kubernetes/compute oltre al livello di rete.

Puoi utilizzare Istio per i test del caos applicando un VirtualService con il campo "fault". Istio supporta due tipi di errori: errori di ritardo (inserimento di un timeout) ed errori di interruzione (inserimento di errori HTTP). In questo esempio, inseriremo un errore di ritardo di 5 secondi nel servizio di suggerimenti. Ma questa volta, anziché utilizzare un interruttore automatico per "fallire rapidamente" contro questo servizio in attesa, forzeremo i servizi downstream a sopportare il timeout completo.

  1. Vai alla directory di inserimento dei guasti.
export K8S_REPO="${WORKDIR}/k8s-repo"
export ASM="${WORKDIR}/asm/" 
cd $ASM
 
  1. Apri k8s_manifests/prod/istio-networking/app-recommendation-vs-fault.yaml per esaminarne i contenuti. Tieni presente che Istio offre un'opzione per inserire l'errore in una percentuale delle richieste. In questo caso, introdurremo un timeout in tutte le richieste recommendationservice.

Output (non copiare)

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: recommendation-delay-fault
spec:
  hosts:
  - recommendationservice.recommendation.svc.cluster.local
  http:
  - route:
    - destination:
        host: recommendationservice.recommendation.svc.cluster.local
    fault:
      delay:
        percentage:
          value: 100
        fixedDelay: 5s
  1. Copia VirtualService in k8s_repo. Inseriremo l'errore a livello globale, in entrambe le regioni.
cp $ASM/k8s_manifests/prod/istio-networking/app-recommendation-vs-fault.yaml ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/app-recommendation-vs-fault.yaml
cd ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/; kustomize edit add resource app-recommendation-vs-fault.yaml

cp $ASM/k8s_manifests/prod/istio-networking/app-recommendation-vs-fault.yaml ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/app-recommendation-vs-fault.yaml
cd ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/; kustomize edit add resource app-recommendation-vs-fault.yaml
 
  1. Esegui il push delle modifiche
cd $K8S_REPO 
git add . && git commit -am "Fault Injection: recommendationservice"
git push
cd $ASM
 
  1. Attendi il completamento di Cloud Build.
  2. Esegui il comando exec nel pod fortio di cui è stato eseguito il deployment nella sezione dell'interruttore di circuito e invia un po' di traffico a recommendationservice.
FORTIO_POD=$(kubectl --context ${DEV1_GKE_1} get pod -n shipping | grep fortio | awk '{ print $1 }')

kubectl --context ${DEV1_GKE_1} exec -it $FORTIO_POD -n shipping -c fortio /usr/bin/fortio -- load -grpc -c 100 -n 100 -qps 0 recommendationservice.recommendation.svc.cluster.local:8080
 
    Once the fortio command is complete, you should see responses averaging 5s:

Output (non copiare)

Ended after 5.181367359s : 100 calls. qps=19.3
Aggregated Function Time : count 100 avg 5.0996506 +/- 0.03831 min 5.040237641 max 5.177559818 sum 509.965055
  1. Un altro modo per vedere il guasto che abbiamo inserito in azione è aprire il frontend in un browser web e fare clic su un prodotto qualsiasi. Il caricamento di una pagina di prodotto richiede 5 secondi in più, poiché recupera i consigli visualizzati nella parte inferiore della pagina.
  2. Esegui la pulizia rimuovendo il servizio di inserimento di errori da entrambi i cluster Ops.
kubectl --context ${OPS_GKE_1} delete virtualservice recommendation-delay-fault -n recommendation 
rm ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/app-recommendation-vs-fault.yaml
cd ${K8S_REPO}/${OPS_GKE_1_CLUSTER}/istio-networking/; kustomize edit remove resource app-recommendation-vs-fault.yaml

kubectl --context ${OPS_GKE_2} delete virtualservice recommendation-delay-fault -n recommendation 
rm ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/app-recommendation-vs-fault.yaml
cd ${K8S_REPO}/${OPS_GKE_2_CLUSTER}/istio-networking/; kustomize edit remove resource app-recommendation-vs-fault.yaml
 
  1. Esegui il push delle modifiche:
cd $K8S_REPO 
git add . && git commit -am "Fault Injection cleanup / restore"
git push
cd $ASM
 

15. Monitoraggio del control plane Istio

ASM installa quattro componenti importanti del control plane: Pilot, Mixer, Galley e Citadel. Ciascuno invia le metriche di monitoraggio pertinenti a Prometheus e ASM viene fornito con dashboard Grafana che consentono agli operatori di visualizzare questi dati di monitoraggio e valutare l'integrità e le prestazioni del control plane.

Visualizzare le dashboard

  1. Port forwarding del servizio Grafana installato con Istio
kubectl --context ${OPS_GKE_1} -n istio-system port-forward svc/grafana 3000:3000 >> /dev/null
 
  1. Aprire Grafana nel browser
  2. Fai clic sull'icona "Anteprima web" nell'angolo in alto a destra della finestra di Cloud Shell.
  3. Fai clic su Anteprima sulla porta 3000 (nota: se la porta non è 3000, fai clic su Cambia porta e seleziona la porta 3000).
  4. Si aprirà una scheda nel browser con un URL simile a " BASE_URL/?orgId=1&authuser=0&environment_id=default".
  5. Visualizza le dashboard disponibili
  6. Modifica l'URL in " BASE_URL/dashboard"
  7. Fai clic sulla cartella "istio" per visualizzare le dashboard disponibili
  8. Fai clic su uno di questi dashboard per visualizzare il rendimento del componente. Nelle sezioni seguenti esamineremo le metriche importanti per ogni componente.

Progetto pilota di monitoraggio

Pilot è il componente del control plane che distribuisce la configurazione di rete e dei criteri al data plane (i proxy Envoy). Pilot tende a scalare in base al numero di workload e deployment, anche se non necessariamente in base alla quantità di traffico verso questi workload. Un pilota in stato non integro può:

  • consumano più risorse del necessario (CPU e/o RAM)
  • comportano ritardi nell'invio delle informazioni di configurazione aggiornate agli Envoy

Nota: se Pilot non è disponibile o se si verificano ritardi, i tuoi carichi di lavoro continuano a pubblicare traffico.

  1. Vai a " BASE_URL/dashboard/db/istio-pilot-dashboard" nel browser per visualizzare le metriche di Pilot.

Metriche monitorate importanti

Utilizzo delle risorse

Utilizza la pagina Prestazioni e scalabilità di Istio come guida per i numeri di utilizzo accettabili. Se noti un utilizzo delle risorse molto più elevato e prolungato, contatta l'assistenza GCP.

5f1969f8e2c8b137.png

Pilot Push Information

Questa sezione monitora i push di configurazione di Pilot ai tuoi proxy Envoy.

  • Pilot Pushes mostra il tipo di configurazione inviata in un determinato momento.
  • Monitoraggio ADS mostra il numero di servizi virtuali, servizi ed endpoint connessi nel sistema.
  • Cluster senza endpoint noti mostra gli endpoint che sono stati configurati ma non hanno istanze in esecuzione (il che potrebbe indicare servizi esterni, come *.googleapis.com).
  • Errori pilota mostra il numero di errori riscontrati nel tempo.
  • Conflitti mostra il numero di conflitti che rappresentano una configurazione ambigua sui listener.

Se sono presenti errori o conflitti, la configurazione di uno o più servizi non è corretta o è incoerente. Per informazioni, consulta Risoluzione dei problemi del data plane.

Envoy Information

Questa sezione contiene informazioni sui proxy Envoy che contattano il control plane. Contatta l'assistenza GCP se visualizzi ripetuti errori di connessione XDS.

Monitoring Mixer

Mixer è il componente che convoglia la telemetria dai proxy Envoy ai backend di telemetria (in genere Prometheus, Stackdriver e così via). In questa veste, non si trova nel piano dati. Viene implementato come due job Kubernetes (chiamati Mixer) con due nomi di servizio diversi (istio-telemetry e istio-policy).

Mixer può essere utilizzato anche per l'integrazione con i sistemi di criteri. In questa veste, Mixer influisce sul piano dati, in quanto i controlli delle policy su Mixer che non vanno a buon fine bloccano l'accesso ai tuoi servizi.

Mixer tende a scalare in base al volume di traffico.

  1. Vai a " BASE_URL/dashboard/db/istio-mixer-dashboard" nel browser per visualizzare le metriche di Mixer.

Metriche monitorate importanti

Utilizzo delle risorse

Utilizza la pagina Prestazioni e scalabilità di Istio come guida per i numeri di utilizzo accettabili. Se noti un utilizzo delle risorse molto più elevato e prolungato, contatta l'assistenza GCP.

87ed83238f9addd8.png

Panoramica del mixer

  • Durata della risposta è una metrica importante. Sebbene i report sulla telemetria di Mixer non si trovino nel percorso dei dati, se queste latenze sono elevate, le prestazioni del proxy sidecar rallenteranno sicuramente. Il 90° percentile dovrebbe essere espresso in millisecondi a una sola cifra, mentre il 99° percentile dovrebbe essere inferiore a 100 ms.

e07bdf5fde4bfe87.png

  • Durata invio adattatore indica la latenza riscontrata da Mixer durante la chiamata degli adattatori (tramite i quali invia informazioni ai sistemi di telemetria e logging). Latenze elevate in questo punto influiranno sicuramente sulle prestazioni della mesh. Anche in questo caso, le latenze p90 devono essere inferiori a 10 ms.

1c2ee56202b32bd9.png

Monitoraggio della galleria

Galley è il componente di convalida, inserimento, elaborazione e distribuzione della configurazione di Istio. Trasmette la configurazione dal server API Kubernetes a Pilot. Come Pilot, tende a scalare in base al numero di servizi ed endpoint nel sistema.

  1. Vai a " BASE_URL/dashboard/db/istio-galley-dashboard" nel browser per visualizzare le metriche di Galley.

Metriche monitorate importanti

Convalida delle risorse

La metrica più importante da seguire, che indica il numero di risorse di vari tipi, come regole di destinazione, gateway e voci di servizio, che superano o non superano la convalida.

Client connessi

Indica il numero di client connessi a Galley. In genere sono 3 (pilot, istio-telemetry, istio-policy) e aumentano man mano che questi componenti vengono scalati.

16. Risoluzione dei problemi di Istio

Risoluzione dei problemi relativi al piano dati

Se la dashboard Pilot indica che hai problemi di configurazione, esamina i log di Pilot o utilizza istioctl per trovare i problemi di configurazione.

Per esaminare i log di Pilot, esegui la scoperta di kubectl -n istio-system logs istio-pilot-69db46c598-45m44, sostituendo istio-pilot-... con l'identificatore del pod per l'istanza di Pilot di cui vuoi risolvere i problemi.

Nel log risultante, cerca un messaggio Stato push. Ad esempio:

2019-11-07T01:16:20.451967Z        info        ads        Push Status: {
    "ProxyStatus": {
        "pilot_conflict_outbound_listener_tcp_over_current_tcp": {
            "0.0.0.0:443": {
                "proxy": "cartservice-7555f749f-k44dg.hipster",
                "message": "Listener=0.0.0.0:443 AcceptedTCP=accounts.google.com,*.googleapis.com RejectedTCP=edition.cnn.com TCPServices=2"
            }
        },
        "pilot_duplicate_envoy_clusters": {
            "outbound|15443|httpbin|istio-egressgateway.istio-system.svc.cluster.local": {
                "proxy": "sleep-6c66c7765d-9r85f.default",
                "message": "Duplicate cluster outbound|15443|httpbin|istio-egressgateway.istio-system.svc.cluster.local found while pushing CDS"
            },
            "outbound|443|httpbin|istio-egressgateway.istio-system.svc.cluster.local": {
                "proxy": "sleep-6c66c7765d-9r85f.default",
                "message": "Duplicate cluster outbound|443|httpbin|istio-egressgateway.istio-system.svc.cluster.local found while pushing CDS"
            },
            "outbound|80|httpbin|istio-egressgateway.istio-system.svc.cluster.local": {
                "proxy": "sleep-6c66c7765d-9r85f.default",
                "message": "Duplicate cluster outbound|80|httpbin|istio-egressgateway.istio-system.svc.cluster.local found while pushing CDS"
            }
        },
        "pilot_eds_no_instances": {
            "outbound_.80_._.frontend-external.hipster.svc.cluster.local": {},
            "outbound|443||*.googleapis.com": {},
            "outbound|443||accounts.google.com": {},
            "outbound|443||metadata.google.internal": {},
            "outbound|80||*.googleapis.com": {},
            "outbound|80||accounts.google.com": {},
            "outbound|80||frontend-external.hipster.svc.cluster.local": {},
            "outbound|80||metadata.google.internal": {}
        },
        "pilot_no_ip": {
            "loadgenerator-778c8489d6-bc65d.hipster": {
                "proxy": "loadgenerator-778c8489d6-bc65d.hipster"
            }
        }
    },
    "Version": "o1HFhx32U4s="
}

Lo stato push indica eventuali problemi che si sono verificati durante il tentativo di eseguire il push della configurazione sui proxy Envoy. In questo caso, vengono visualizzati diversi messaggi "Cluster duplicato", che indicano destinazioni upstream duplicate.

Per assistenza nella diagnosi dei problemi, contatta l'assistenza Google Cloud.

Ricerca degli errori di configurazione

Per utilizzare istioctl per analizzare la configurazione, esegui istioctl experimental analyze -k --context $OPS_GKE_1. Verrà eseguita un'analisi della configurazione del sistema, verranno indicati eventuali problemi e suggerite modifiche. Consulta la documentazione per un elenco completo degli errori di configurazione che questo comando può rilevare.

17. Esegui la pulizia

Un amministratore esegue lo script cleanup_workshop.sh per eliminare le risorse create dallo script bootstrap_workshop.sh. Per eseguire lo script di pulizia sono necessarie le seguenti informazioni.

  • Nome dell'organizzazione, ad esempio yourcompany.com
  • ID workshop: nel formato YYMMDD-NN, ad esempio 200131-01
  • Bucket GCS amministratore: definito nello script di bootstrap.
  1. Apri Cloud Shell ed esegui tutte le azioni riportate di seguito in Cloud Shell. Fai clic sul link di seguito.

CLOUD SHELL

  1. Verifica di aver eseguito l'accesso a gcloud con l'utente amministratore previsto.
gcloud config list
 
  1. Vai alla cartella asm.
cd ${WORKDIR}/asm
 
  1. Definisci il nome dell'organizzazione e l'ID workshop da eliminare.
export ORGANIZATION_NAME=<ORGANIZATION NAME>
export ASM_WORKSHOP_ID=<WORKSHOP ID>
export ADMIN_STORAGE_BUCKET=<ADMIN CLOUD STORAGE BUCKET>
 
  1. Esegui lo script di pulizia nel seguente modo.
./scripts/cleanup_workshop.sh --workshop-id ${ASM_WORKSHOP_ID} --admin-gcs-bucket ${ADMIN_STORAGE_BUCKET} --org-name ${ORGANIZATION_NAME}