Esegui il deployment dell'app ASP.NET Core in Google Kubernetes Engine con Istio (parte 1)

1. Panoramica

ASP.NET Core è un framework open source e multipiattaforma per la creazione di applicazioni moderne basate sul cloud e connesse a internet utilizzando il linguaggio di programmazione C#.

Kubernetes è un sistema open source per l'automazione del deployment, della scalabilità e della gestione delle applicazioni containerizzate. Istio è un framework aperto per connettere, proteggere, gestire e monitorare i servizi.

In questa prima parte del lab, esegui il deployment di una semplice app ASP.NET Core in Kubernetes in esecuzione su Google Kubernetes Engine (GKE) e la configuri in modo che venga gestita da Istio.

Nella seconda parte del lab, esplorerai ulteriormente le funzionalità di Istio, come metriche, tracciamento, gestione dinamica del traffico, inserimento di errori e altro ancora.

Obiettivi didattici

  • Come creare e pacchettizzare una semplice app ASP.NET Core in un container Docker.
  • Come creare un cluster Kubernetes con Google Kubernetes Engine (GKE).
  • Come installare Istio su un cluster Kubernetes su GKE.
  • Come eseguire il deployment dell'app ASP.NET Core e configurare il traffico in modo che venga gestito da Istio.

Che cosa ti serve

Come utilizzerai questo tutorial?

Leggilo e basta Leggilo e completa gli esercizi

Come valuteresti la tua esperienza con Google Cloud Platform?

Principiante Intermedio Avanzato

2. Configurazione e requisiti

Configurazione dell'ambiente autonomo

  1. Accedi alla console Cloud e crea un nuovo progetto o riutilizzane uno esistente. Se non hai ancora un account Gmail o Google Workspace, devi crearne uno.

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

Ricorda l'ID progetto, un nome univoco tra tutti i progetti Google Cloud (il nome sopra è già stato utilizzato e non funzionerà per te, mi dispiace). In questo codelab verrà chiamato PROJECT_ID.

  1. Successivamente, dovrai abilitare la fatturazione in Cloud Console per utilizzare le risorse Google Cloud.

L'esecuzione di questo codelab non dovrebbe costare molto, se non nulla. Assicurati di seguire le istruzioni riportate nella sezione "Pulizia", che ti consiglia come arrestare le risorse in modo da non incorrere in addebiti oltre questo tutorial. I nuovi utenti di Google Cloud possono beneficiare del programma prova senza costi di 300$.

Avvia Cloud Shell

Sebbene Google Cloud possa essere gestito da remoto dal tuo laptop, in questo codelab utilizzerai Google Cloud Shell, un ambiente a riga di comando in esecuzione in Google Cloud.

Attiva Cloud Shell

  1. Nella console Cloud, fai clic su Attiva Cloud Shell 4292cbf4971c9786.png.

bce75f34b2c53987.png

Se non hai mai avviato Cloud Shell, viene visualizzata una schermata intermedia (sotto la piega) che ne descrive le funzionalità. In questo caso, fai clic su Continua e non comparirà più. Ecco come si presenta la schermata intermedia:

70f315d7b402b476.png

Bastano pochi istanti per eseguire il provisioning e connettersi a Cloud Shell.

fbe3a0674c982259.png

Questa macchina virtuale è caricata con tutti gli strumenti per sviluppatori di cui hai bisogno. Offre una home directory permanente da 5 GB e viene eseguita in Google Cloud, migliorando notevolmente le prestazioni e l'autenticazione della rete. Gran parte del lavoro per questo codelab, se non tutto, può essere svolto semplicemente con un browser o con Chromebook.

Una volta eseguita la connessione a Cloud Shell, dovresti vedere che il tuo account è già autenticato e il progetto è già impostato sul tuo ID progetto.

  1. Esegui questo comando in Cloud Shell per verificare che l'account sia autenticato:
gcloud auth list

Output comando

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Esegui questo comando in Cloud Shell per verificare che il comando gcloud conosca il tuo progetto:
gcloud config list project

Output comando

[core]
project = <PROJECT_ID>

In caso contrario, puoi impostarlo con questo comando:

gcloud config set project <PROJECT_ID>

Output comando

Updated property [core/project].

3. Crea un'app ASP.NET Core in Cloud Shell

Nel prompt di Cloud Shell, puoi verificare che lo strumento a riga di comando dotnet sia già installato controllandone la versione. Dovrebbe essere stampata la versione dello strumento a riga di comando dotnet installato:

dotnet --version

Poi, crea un nuovo scheletro di app web ASP.NET Core.

dotnet new mvc -o HelloWorldAspNetCore

Viene creato un progetto e ne vengono ripristinate le dipendenze. Dovresti vedere un messaggio simile al seguente.

Restore completed in 11.44 sec for HelloWorldAspNetCore.csproj.

Restore succeeded.

4. Esegui l'app ASP.NET Core

È quasi tutto pronto per eseguire la nostra app. Vai alla cartella dell'app.

cd HelloWorldAspNetCore

Infine, esegui l'app.

dotnet run --urls=http://localhost:8080

L'applicazione inizia ad ascoltare sulla porta 8080.

Hosting environment: Production
Content root path: /home/atameldev/HelloWorldAspNetCore
Now listening on: http://[::]:8080
Application started. Press Ctrl+C to shut down.

Per verificare che l'app sia in esecuzione, fai clic sul pulsante di anteprima web in alto a destra e seleziona "Anteprima sulla porta 8080".

Capture.PNG

Vedrai la pagina web ASP.NET Core predefinita:

f579a9baedc108a9.png

Dopo aver verificato che l'app è in esecuzione, premi Ctrl+C per chiuderla.

5. Pacchettizza l'app ASP.NET Core in un container Docker

Successivamente, prepara l'app per l'esecuzione come container. Il primo passaggio consiste nel definire il contenitore e i relativi contenuti.

Nella directory di base dell'app, crea un Dockerfile per definire l'immagine Docker.

touch Dockerfile

Aggiungi quanto segue a Dockerfile utilizzando il tuo editor preferito (vim, nano,emacs o l'editor di codice di Cloud Shell).

# Use Microsoft's official build .NET image.
# https://hub.docker.com/_/microsoft-dotnet-core-sdk/
FROM mcr.microsoft.com/dotnet/sdk:5.0-alpine AS build
WORKDIR /app

# Install production dependencies.
# Copy csproj and restore as distinct layers.
COPY *.csproj ./
RUN dotnet restore

# Copy local code to the container image.
COPY . ./
WORKDIR /app

# Build a release artifact.
RUN dotnet publish -c Release -o out

# Use Microsoft's official runtime .NET image.
# https://hub.docker.com/_/microsoft-dotnet-core-aspnet/
FROM mcr.microsoft.com/dotnet/aspnet:5.0-alpine AS runtime
WORKDIR /app
COPY --from=build /app/out ./

# Make sure the app binds to port 8080
ENV ASPNETCORE_URLS http://*:8080

# Run the web service on container startup.
ENTRYPOINT ["dotnet", "HelloWorldAspNetCore.dll"]

Una configurazione importante inclusa nel Dockerfile è la porta su cui l'app è in attesa di traffico in entrata (8080). Ciò si ottiene impostando la variabile di ambiente ASPNETCORE_URLS, che le app ASP.NET Core utilizzano per determinare la porta da ascoltare.

Salva questo Dockerfile. Ora creiamo l'immagine:

docker build -t gcr.io/${GOOGLE_CLOUD_PROJECT}/hello-dotnet:v1 .

Al termine dell'operazione (il download e l'estrazione di tutti i file richiedono un po' di tempo), puoi vedere che l'immagine è stata creata e salvata localmente:

docker images

REPOSITORY                             TAG   
gcr.io/yourproject-XXXX/hello-dotnet   v1            

Testa l'immagine in locale con questo comando, che eseguirà un container Docker in locale sulla porta 8080 dalla tua immagine container appena creata:

docker run -p 8080:8080 gcr.io/${GOOGLE_CLOUD_PROJECT}/hello-dotnet:v1

E ancora una volta, sfrutta la funzionalità di anteprima web di Cloud Shell :

Screenshot from 2015-11-03 17:20:22.png

Dovresti vedere la pagina web ASP.NET Core predefinita in una nuova scheda.

f579a9baedc108a9.png

Dopo aver verificato che l'app viene eseguita correttamente in locale in un container Docker, puoi arrestare il container in esecuzione Ctrl-> C.

Ora che l'immagine funziona come previsto, puoi eseguirne il push in Google Container Registry, un repository privato per le tue immagini Docker accessibile da ogni progetto Google Cloud (ma anche dall'esterno di Google Cloud) :

docker push gcr.io/${GOOGLE_CLOUD_PROJECT}/hello-dotnet:v1

Se tutto va bene e dopo un po' di tempo, dovresti essere in grado di vedere l'immagine container elencata nella sezione Container Registry. A questo punto, hai a disposizione un'immagine Docker a livello di progetto a cui Kubernetes può accedere e che può orchestrare, come vedrai tra qualche minuto.

73558f3a54ce1c0c.png

Se vuoi, puoi esplorare le immagini dei container così come sono archiviate in Google Cloud Storage seguendo questo link: https://console.cloud.google.com/storage/browser/ (il link risultante completo dovrebbe avere questo formato: https://console.cloud.google.com/project/PROJECT_ID/storage/browser/).

6. Crea un cluster Kubernetes/GKE con Istio

Innanzitutto, assicurati di aver abilitato l'API Kubernetes Engine:

gcloud services enable container.googleapis.com

Crea un cluster Kubernetes. Se vuoi, puoi cambiare la regione con una più vicina a te:

gcloud container clusters create hello-istio \
  --cluster-version=latest \
  --machine-type=n1-standard-2 \
  --num-nodes=4 \
  --region europe-west1

Attendi qualche istante mentre il cluster viene configurato. Sarà visibile nella sezione Kubernetes Engine della console Google Cloud.

e46fd9c6ee82bcc4.png

Per questo codelab, scaricheremo e installeremo Istio da istio.io. Esistono altre opzioni di installazione, tra cui il componente aggiuntivo Istio per GKE e Anthos Service Mesh. I passaggi dell'applicazione successivi a questo funzioneranno su qualsiasi installazione di Istio.

Per prima cosa, scarichiamo il client e gli esempi di Istio. La pagina delle release di Istio offre artefatti di download per diversi sistemi operativi. Nel nostro caso, possiamo utilizzare un comodo comando per scaricare ed estrarre l'ultima release per la nostra piattaforma attuale:

curl -L https://istio.io/downloadIstio | sh -

Lo script ti indicherà la versione di Istio scaricata:

Istio has been successfully downloaded into the istio-1.8.1 folder on your system.

La directory di installazione contiene applicazioni di esempio e il file binario del client istioctl. Passa a questa directory:

cd istio-1.8.1

Copia e incolla il comando fornito per aggiungere la directory bin a PATH, in modo da poter utilizzare istioctl:

export PATH="$PATH:/home/<YOURHOMEID>/istio-1.8.1/bin"

Verifica che istioctl sia disponibile controllando che il cluster sia pronto per Istio:

istioctl x precheck

Dovresti visualizzare un messaggio che indica Install Pre-Check passed! The cluster is ready for Istio installation.

Installa Istio con il profilo demo:

istioctl install --set profile=demo

Istio è ora installato nel cluster.

Inserimento automatico di sidecar

Per iniziare a utilizzare Istio, non è necessario apportare modifiche all'applicazione. Quando configuri ed esegui i servizi, i sidecar Envoy vengono inseriti automaticamente in ogni pod per il servizio.

Affinché funzioni, devi abilitare l'inserimento di sidecar per lo spazio dei nomi ("default") che utilizzi per i microservizi. Per farlo, applica un'etichetta:

kubectl label namespace default istio-injection=enabled

Per verificare che l'etichetta sia stata applicata correttamente, esegui questo comando:

kubectl get namespace -L istio-injection

L'output conferma che l'inserimento di sidecar è abilitato per lo spazio dei nomi predefinito:

NAME              STATUS   AGE    ISTIO-INJECTION
default           Active   3m     enabled
istio-system      Active   63s    disabled
...

7. Verificare l'installazione

Istio include tre servizi: il piano di controllo istiod e i gateway in entrata e in uscita (che puoi considerare come "proxy sidecar per il resto di internet"), denominati rispettivamente istio-ingressgateway e istio-egressgateway.

kubectl get svc -n istio-system

L'output dovrebbe avere il seguente aspetto:

NAME                   TYPE           CLUSTER-IP      EXTERNAL-IP                                                                     AGE
istio-egressgateway    ClusterIP      10.55.252.182   <none>
istio-ingressgateway   LoadBalancer   10.55.250.185   35.233.118.42
istiod                 ClusterIP      10.55.253.217   <none>

L'Ingress Gateway ha un tipo LoadBalancer, quindi è accessibile da internet; gli altri devono essere accessibili solo dall'interno del cluster.

Successivamente, assicurati che i pod Kubernetes corrispondenti siano implementati e che tutti i container siano in esecuzione:

kubectl get pods -n istio-system

Quando tutti i pod sono in esecuzione, puoi procedere.

NAME                                    READY   STATUS
istio-egressgateway-674988f895-m6tk4    1/1     Running
istio-ingressgateway-6996f7dcc8-7lvm2   1/1     Running
istiod-6bf5fc8b64-j79hj                 1/1     Running
  • istiod: il control plane Istio. Gestisce la configurazione e la programmazione dei proxy sidecar, il Service Discovery, la distribuzione dei certificati e l'inserimento dei sidecar
  • ingress gateway: Gestisce le richieste in entrata provenienti dall'esterno del cluster.
  • egress gateway: gestisce le richieste in uscita agli endpoint esterni al cluster.

8. Esegui il deployment dell'applicazione

Ora che hai verificato che Istio è installato e in esecuzione, puoi eseguire il deployment dell'app ASP.NET Core.

Deployment e servizio

Innanzitutto, crea un file aspnetcore.yaml utilizzando il tuo editor preferito (vim, nano,emacs o l'editor di codice di Cloud Shell) e definisci il deployment e il servizio Kubernetes per l'app:

apiVersion: v1
kind: Service
metadata:
  name: aspnetcore-service
  labels:
    app: aspnetcore
spec:
  ports:
  - port: 8080
    name: http
  selector:
    app: aspnetcore
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: aspnetcore-v1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: aspnetcore
      version: v1
  template:
    metadata:
      labels:
        app: aspnetcore
        version: v1
    spec:
      containers:
      - name: aspnetcore
        image: gcr.io/YOUR-PROJECT-ID/hello-dotnet:v1
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080

I contenuti del file sono Deployment e Servizi standard per il deployment dell'applicazione e non contengono nulla di specifico per Istio.

Esegui il deployment dei servizi nello spazio dei nomi predefinito con kubectl:

kubectl apply -f aspnetcore.yaml
service "aspnetcore-service" created
deployment.extensions "aspnetcore-v1" created

Verifica che i pod siano in esecuzione:

kubectl get pods
NAME                          READY     STATUS    RESTARTS   AGE
aspnetcore-v1-6cf64748-mddb   2/2       Running   0          34s

Gateway e VirtualService

Per consentire al traffico in entrata di raggiungere il mesh, devi creare un gateway e un VirtualService.

Un gateway configura un bilanciatore del carico per il traffico HTTP/TCP, che in genere opera al limite del mesh per abilitare il traffico in entrata per un'applicazione. Un VirtualService definisce le regole che controllano il modo in cui le richieste per un servizio vengono instradate all'interno di un service mesh Istio.

Crea un file aspnetcore-gateway.yaml per definire il gateway:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: aspnetcore-gateway
spec:
  selector:
    istio: ingressgateway # use istio default controller
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"

Crea un file aspnetcore-virtualservice.yaml per definire il VirtualService:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: aspnetcore-virtualservice
spec:
  hosts:
  - "*"
  gateways:
  - aspnetcore-gateway
  http:
  - route:
    - destination:
        host: aspnetcore-service

Esegui il comando kubectl per eseguire il deployment del gateway con:

kubectl apply -f aspnetcore-gateway.yaml

Il comando produce il seguente output:

gateway.networking.istio.io "aspnetcore-gateway" created

Quindi, esegui questo comando per eseguire il deployment di VirtualService:

kubectl apply -f aspnetcore-virtualservice.yaml

Il comando produce il seguente output:

virtualservice.networking.istio.io "aspnetcore-virtualservice" created

Verifica che tutto sia in esecuzione:

kubectl get gateway
NAME                      AGE
aspnetcore-gateway   28s
kubectl get virtualservice
NAME                             AGE
aspnetcore-virtualservice   33s

Complimenti! Hai appena eseguito il deployment di un'applicazione abilitata per Istio. Successivamente, vedrai l'applicazione in uso.

9. testa l'applicazione

Ora puoi vedere l'applicazione in azione. Devi ottenere l'IP esterno e la porta del gateway. È elencato nella sezione EXTERNAL-IP:

kubectl get svc istio-ingressgateway -n istio-system

Esporta l'IP esterno e la porta in una variabile GATEWAY_URL:

export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')

export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].port}')

export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT

Utilizza curl per testare l'app. Il servizio dovrebbe rispondere con un codice di risposta 200:

curl -o /dev/null -s -w "%{http_code}\n" http://${GATEWAY_URL}/

In alternativa, puoi aprire il browser, andare su http://<gatewayurl> per visualizzare l'app:

f579a9baedc108a9.png

10. Complimenti!

Hai appena eseguito il deployment di una semplice app ASP.NET Core su Kubernetes in esecuzione su Google Kubernetes Engine (GKE) e l'hai configurata per essere gestita da Istio.

Ti starai chiedendo: "Qual è il vantaggio di Istio?". È un'ottima domanda. Finora, non c'è alcun vantaggio nell'avere Istio per gestire questa app. Nella seconda parte del lab, esploreremo ulteriormente le funzionalità di Istio, come metriche, tracciamento, gestione dinamica del traffico, visualizzazione dei servizi e inserimento di errori.

Passaggi successivi

Licenza

Questo lavoro è concesso in licenza ai sensi di una licenza Creative Commons Attribution 2.0 Generic.

11. Esegui la pulizia

Se non continui con la seconda parte del lab, puoi eliminare l'app e disinstallare Istio oppure eliminare semplicemente il cluster Kubernetes.

Eliminare l'app

Per eliminare l'app:

kubectl delete -f aspnetcore-gateway.yaml
Kubectl delete -f aspnetcore-virtualservice.yaml
kubectl delete -f aspnetcore.yaml

Per verificare che l'app sia stata eliminata:

kubectl get gateway 
kubectl get virtualservices 
kubectl get pods

Disinstalla Istio

Per eliminare Istio:

kubectl delete -f install/kubernetes/istio-demo-auth.yaml

Per verificare che Istio non sia più presente:

kubectl get pods -n istio-system

Elimina il cluster Kubernetes

gcloud container clusters delete hello-istio