ASP.NET Core-App mit Istio auf der Google Kubernetes Engine bereitstellen (Teil 1)

1. Übersicht

ASP.NET Core ist ein plattformübergreifendes Open-Source-Framework zum Entwickeln moderner cloudbasierter und mit dem Internet verbundener Anwendungen mithilfe der Programmiersprache C#.

Kubernetes ist ein Open-Source-System zur Automatisierung der Bereitstellung, Skalierung und Verwaltung von Containeranwendungen. Istio ist ein offenes Framework zum Verbinden, Sichern, Verwalten und Überwachen von Diensten.

In diesem ersten Teil des Labs stellen Sie eine einfache ASP.NET Core-App in Kubernetes bereit, die in Google Kubernetes Engine (GKE) ausgeführt wird, und konfigurieren sie so, dass sie von Istio verwaltet wird.

Im zweiten Teil des Labs werden weitere Funktionen von Istio wie Messwerte, Tracing, dynamische Trafficverwaltung und Fehlerinjektion behandelt.

Lerninhalte

  • Eine einfache ASP.NET Core-App in einem Docker-Container erstellen und verpacken
  • So erstellen Sie einen Kubernetes-Cluster mit Google Kubernetes Engine (GKE).
  • So installieren Sie Istio in einem Kubernetes-Cluster in GKE.
  • ASP.NET Core-App bereitstellen und den Traffic so konfigurieren, dass er von Istio verwaltet wird

Voraussetzungen

Wie werden Sie diese Anleitung verwenden?

Nur lesen Lesen und Übungen durchführen

Wie würden Sie Ihre Erfahrung mit der Google Cloud Platform bewerten?

Anfänger Mittelstufe Fortgeschritten

2. Einrichtung und Anforderungen

Umgebung zum selbstbestimmten Lernen einrichten

  1. Melden Sie sich in der Cloud Console an und erstellen Sie ein neues Projekt oder verwenden Sie ein vorhandenes Projekt. Wenn Sie noch kein Gmail- oder Google Workspace-Konto haben, müssen Sie eines erstellen.

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

Notieren Sie sich die Projekt-ID, also den projektübergreifend nur einmal vorkommenden Namen eines Google Cloud-Projekts. Der oben angegebene Name ist bereits vergeben und kann leider nicht mehr verwendet werden. Sie wird später in diesem Codelab als PROJECT_ID bezeichnet.

  1. Als Nächstes müssen Sie die Abrechnung in der Cloud Console aktivieren, um Google Cloud-Ressourcen verwenden zu können.

Die Durchführung dieses Codelabs sollte keine oder nur geringe Kosten verursachen. Folgen Sie bitte der Anleitung im Abschnitt „Bereinigen“, in der Sie erfahren, wie Sie Ressourcen herunterfahren können, damit nach Abschluss dieser Anleitung keine Gebühren anfallen. Neue Nutzer von Google Cloud kommen für das Programm für kostenlose Testversionen mit einem Guthaben von 300$ infrage.

Cloud Shell starten

Während Sie Google Cloud von Ihrem Laptop aus per Fernzugriff nutzen können, wird in diesem Codelab Google Cloud Shell verwendet, eine Befehlszeilenumgebung, die in Google Cloud ausgeführt wird.

Cloud Shell aktivieren

  1. Klicken Sie in der Cloud Console auf Cloud Shell aktivieren 4292cbf4971c9786.png.

bce75f34b2c53987.png

Wenn Sie die Cloud Shell zuvor noch nicht gestartet haben, wird ein Fenster mit einer Beschreibung eingeblendet. Klicken Sie in diesem Fall einfach auf Weiter. So sieht dieses Fenster aus:

70f315d7b402b476.png

Das Herstellen der Verbindung mit der Cloud Shell sollte nur wenige Augenblicke dauern.

fbe3a0674c982259.png

Auf dieser virtuellen Maschine sind alle Entwicklungstools installiert, die Sie benötigen. Sie bietet ein Basisverzeichnis mit 5 GB nichtflüchtigem Speicher und läuft in Google Cloud, was die Netzwerkleistung und Authentifizierung erheblich verbessert. Die meisten, wenn nicht sogar alle Aufgaben in diesem Codelab können mit einem Browser oder Ihrem Chromebook erledigt werden.

Sobald die Verbindung mit der Cloud Shell hergestellt ist, sehen Sie, dass Sie bereits authentifiziert sind und für das Projekt schon Ihre Projekt-ID eingestellt ist.

  1. Führen Sie in der Cloud Shell den folgenden Befehl aus, um zu prüfen, ob Sie authentifiziert sind:
gcloud auth list

Befehlsausgabe

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

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Führen Sie den folgenden Befehl in Cloud Shell aus, um zu bestätigen, dass der gcloud-Befehl Ihr Projekt kennt:
gcloud config list project

Befehlsausgabe

[core]
project = <PROJECT_ID>

Ist dies nicht der Fall, können Sie die Einstellung mit diesem Befehl vornehmen:

gcloud config set project <PROJECT_ID>

Befehlsausgabe

Updated property [core/project].

3. ASP.NET Core-App in Cloud Shell erstellen

In der Cloud Shell-Eingabeaufforderung können Sie prüfen, ob das dotnet-Befehlszeilentool bereits installiert ist, indem Sie die Version abrufen. Dadurch sollte die Version des installierten dotnet-Befehlszeilentools ausgegeben werden:

dotnet --version

Erstellen Sie als Nächstes das Grundgerüst für eine neue ASP.NET Core-Web-App.

dotnet new mvc -o HelloWorldAspNetCore

Dadurch sollte ein Projekt mit wiederhergestellten Abhängigkeiten erstellt werden, was durch eine Meldung wie die folgende bestätigt wird.

Restore completed in 11.44 sec for HelloWorldAspNetCore.csproj.

Restore succeeded.

4. ASP.NET Core-App ausführen

Die Anwendung ist fast einsatzbereit. Rufen Sie den App-Ordner auf.

cd HelloWorldAspNetCore

Führen Sie die App zum Schluss aus.

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

Die Anwendung überwacht nun Port 8080.

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

Klicken Sie oben rechts auf die Schaltfläche „Webvorschau“ und wählen Sie „Vorschau auf Port 8080“ aus, um zu prüfen, ob die App ausgeführt wird.

Capture.PNG

Sie sehen die ASP.NET Core-Standardwebseite:

f579a9baedc108a9.png

Wenn Sie bestätigt haben, dass die App ausgeführt wird, drücken Sie Strg + C, um sie zu beenden.

5. ASP.NET Core-App in einem Docker-Container verpacken

Als Nächstes bereiten Sie Ihre App darauf vor, als Container ausgeführt zu werden. Dazu legen Sie zuerst den Container und seine Inhalte fest.

Erstellen Sie im Basisverzeichnis der App eine Dockerfile, um das Docker-Image zu definieren.

touch Dockerfile

Fügen Sie mithilfe eines Editors Ihrer Wahl (vim,, nano,emacs oder der Code-Editor von Cloud Shell) dem Dockerfile den folgenden Code hinzu.

# 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"]

Eine wichtige Konfiguration im Dockerfile ist der Port, von dem eingehender Traffic abgerufen wird (8080). Dafür wird die Umgebungsvariable ASPNETCORE_URLS festgelegt, die von ASP.NET Core-Apps verwendet wird, um den relevanten Port zu erkennen.

Speichere diese Dockerfile. Erstellen Sie nun das Image:

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

Sobald dies abgeschlossen ist (es dauert einige Zeit, bis alles heruntergeladen und extrahiert wurde), sehen Sie, dass das Image erstellt und lokal gespeichert wurde:

docker images

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

Testen Sie das Image lokal mit dem folgenden Befehl, durch den ein Docker-Container lokal von Ihrem neu erstellten Container-Image auf Port 8080 ausgeführt wird:

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

Sie können dazu wieder die Webvorschau von Cloud Shell nutzen :

Screenshot vom 03.11.2015, 17:20:22.png

Sie sollten die ASP.NET Core-Webseite in einem neuen Tab sehen.

f579a9baedc108a9.png

Nachdem Sie überprüft haben, dass die App lokal in einem Docker-Container ausgeführt wird, können Sie den Container mit Ctrl-> C stoppen.

Wenn nun das Image wie gewünscht funktioniert, laden Sie es in die Google Container Registry hoch. Das ist ein privates Repository für Ihre Docker-Images, auf die von jedem Google Cloud-Projekt aus (aber auch von außerhalb der Google Cloud Platform) zugegriffen werden kann:

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

Wenn alles gut geht, sollte das Container-Image nach einiger Zeit im Abschnitt Container Registry aufgeführt sein. Ihnen steht nun ein Docker-Image für das gesamte Projekt zur Verfügung, das sich mit Kubernetes aufrufen und orchestrieren lässt, wie Sie gleich sehen werden.

73558f3a54ce1c0c.png

Wenn Sie wissen möchten, welche Container-Images in Google Cloud Storage gespeichert sind, wählen Sie den folgenden Link aus: https://console.cloud.google.com/storage/browser/. Der vollständige Link sollte dieses Format haben: https://console.cloud.google.com/project/PROJECT_ID/storage/browser/.

6. Kubernetes-/GKE-Cluster mit Istio erstellen

Prüfen Sie zuerst, ob die Kubernetes Engine API aktiviert ist:

gcloud services enable container.googleapis.com

Kubernetes-Cluster erstellen Sie können die Region bei Bedarf in eine Region in Ihrer Nähe ändern:

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

Warten Sie einige Sekunden, bis der Cluster eingerichtet ist. Er ist im Bereich „Kubernetes Engine“ der Google Cloud Console sichtbar.

e46fd9c6ee82bcc4.png

In diesem Codelab laden wir Istio von istio.io herunter und installieren es. Es gibt weitere Installationsoptionen, darunter das Istio-Add-on für GKE und Anthos Service Mesh. Die Anwendungs-Schritte danach funktionieren bei jeder Istio-Installation.

Laden wir zuerst den Istio-Client und die Beispiele herunter. Auf der Releaseseite für Istio werden für verschiedene Betriebssysteme Artefakte zum Herunterladen angeboten. In unserem Fall können wir einen praktischen Befehl verwenden, um die aktuelle Version für unsere aktuelle Plattform herunterzuladen und zu extrahieren:

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

Das Skript gibt die heruntergeladene Version von Istio an:

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

Das Installationsverzeichnis enthält Beispielanwendungen und die istioctl-Client-Binärdatei. Wechseln Sie in dieses Verzeichnis:

cd istio-1.8.1

Kopieren Sie den bereitgestellten Befehl und fügen Sie ihn in Ihre PATH ein, um das Verzeichnis bin hinzuzufügen, damit Sie istioctl verwenden können:

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

Prüfen Sie, ob istioctl verfügbar ist, indem Sie prüfen, ob Ihr Cluster für Istio bereit ist:

istioctl x precheck

Es sollte die Meldung Install Pre-Check passed! The cluster is ready for Istio installation. angezeigt werden.

Installieren Sie Istio mit dem Demoprofil:

istioctl install --set profile=demo

Istio ist jetzt in Ihrem Cluster installiert.

Automatische Sidecar-Injektion

Um Istio zu verwenden, müssen Sie keine Änderungen an der Anwendung vornehmen. Wenn Sie die Dienste konfigurieren und ausführen, werden Envoy-Sidecars automatisch in jeden Pod für den Dienst eingefügt.

Dazu müssen Sie die Sidecar-Injektion für den Namespace („default“) aktivieren, den Sie für Ihre Microservices verwenden. Dazu weisen Sie ein Label zu:

kubectl label namespace default istio-injection=enabled

Führen Sie den folgenden Befehl aus, um zu prüfen, ob das Label erfolgreich angewendet wurde:

kubectl get namespace -L istio-injection

Die Ausgabe bestätigt, dass die Sidecar-Injektion für den Standard-Namespace aktiviert ist:

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

7. Installation überprüfen

Istio umfasst drei Dienste: die istiod-Steuerungsebene sowie Ein- und Ausgangsgateways (die Sie sich als „Sidecar-Proxys für das restliche Internet“ vorstellen können) mit den Namen istio-ingressgateway bzw. istio-egressgateway.

kubectl get svc -n istio-system

Die Ausgabe sollte so aussehen:

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>

Das Ingress-Gateway hat den Typ LoadBalancer und ist daher über das Internet zugänglich. Die anderen müssen nur innerhalb des Clusters zugänglich sein.

Prüfen Sie als Nächstes, ob die entsprechenden Kubernetes-Pods bereitgestellt wurden und alle Container ausgeführt werden:

kubectl get pods -n istio-system

Wenn alle Pods ausgeführt werden, können Sie fortfahren.

NAME                                    READY   STATUS
istio-egressgateway-674988f895-m6tk4    1/1     Running
istio-ingressgateway-6996f7dcc8-7lvm2   1/1     Running
istiod-6bf5fc8b64-j79hj                 1/1     Running
  • istiod: Die Istio-Steuerungsebene. Verarbeitet die Konfiguration und Programmierung der Proxy-Sidecars, die Diensterkennung, die Zertifikatverteilung und die Sidecar-Einfügung.
  • ingress gateway: verarbeitet von außerhalb des Clusters eingehende Anfragen
  • egress gateway:Verarbeitet ausgehende Anfragen an Endpunkte außerhalb Ihres Clusters.

8. Anwendung bereitstellen

Nachdem Sie überprüft haben, dass Istio installiert ist und ausgeführt wird, können Sie die ASP.NET Core-App bereitstellen.

Bereitstellung und Dienst

Erstellen Sie zuerst mit Ihrem bevorzugten Editor (vim, nano,emacs oder dem Code-Editor von Cloud Shell) eine aspnetcore.yaml-Datei und definieren Sie das Kubernetes-Deployment und den Kubernetes-Dienst für die 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

Der Inhalt der Datei besteht aus Standard-Deployments und -Diensten zum Bereitstellen der Anwendung und enthält nichts Istio-Spezifisches.

Stellen Sie die Dienste mit kubectl im Standard-Namespace bereit:

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

Prüfen Sie, ob die Pods ausgeführt werden:

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

Gateway und VirtualService

Damit eingehender Traffic das Mesh erreichen kann, müssen Sie ein Gateway und einen VirtualService erstellen.

Ein Gateway konfiguriert einen Load Balancer für HTTP-/TCP-Traffic. Es wird in der Regel am Rand des Mesh-Netzwerks ausgeführt, um Ingress-Traffic für eine Anwendung zu ermöglichen. Ein VirtualService definiert die Regeln, die steuern, wie Anfragen für einen Dienst in einem Istio-Service Mesh weitergeleitet werden.

Erstellen Sie eine aspnetcore-gateway.yaml-Datei, um das Gateway zu definieren:

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:
    - "*"

Erstellen Sie eine aspnetcore-virtualservice.yaml-Datei, um den VirtualService zu definieren:

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

Führen Sie den kubectl-Befehl aus, um das Gateway bereitzustellen:

kubectl apply -f aspnetcore-gateway.yaml

Dieser Befehl erzeugt folgende Ausgabe:

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

Führen Sie als Nächstes den folgenden Befehl aus, um den VirtualService bereitzustellen:

kubectl apply -f aspnetcore-virtualservice.yaml

Dieser Befehl erzeugt folgende Ausgabe:

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

Prüfen Sie, ob alles ausgeführt wird:

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

Glückwunsch! Sie haben gerade eine Istio-fähige Anwendung bereitgestellt. Als Nächstes sehen Sie die Anwendung in Aktion.

9. Anwendung testen

Sie können die Anwendung endlich in Aktion sehen. Sie müssen die externe IP-Adresse und den Port des Gateways abrufen. Sie wird unter EXTERNAL-IP aufgeführt:

kubectl get svc istio-ingressgateway -n istio-system

Exportieren Sie die externe IP-Adresse und den Port in eine GATEWAY_URL-Variable:

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

Testen Sie die App mit curl. Der Dienst sollte mit dem Antwortcode 200 antworten:

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

Alternativ können Sie den Browser öffnen und zu http://<gatewayurl> wechseln, um die App aufzurufen:

f579a9baedc108a9.png

10. Glückwunsch!

Sie haben gerade eine einfache ASP.NET Core-App in Kubernetes bereitgestellt, die in der Google Kubernetes Engine (GKE) ausgeführt wird, und sie so konfiguriert, dass sie von Istio verwaltet wird.

Sie fragen sich vielleicht, welche Vorteile Istio bietet. Das ist eine sehr gute Frage. Bisher bietet es keinen Vorteil, wenn Istio diese App verwaltet. Im zweiten Teil des Labs werden wir weitere Funktionen von Istio kennenlernen, z. B. Messwerte, Tracing, dynamische Trafficverwaltung, Dienstvisualisierung und Fehlerinjektion.

Nächste Schritte

Lizenz

Dieser Text ist mit einer Creative Commons Attribution 2.0 Generic License lizenziert.

11. Bereinigen

Wenn Sie nicht mit dem zweiten Teil des Labs fortfahren, können Sie die App löschen und Istio deinstallieren oder einfach den Kubernetes-Cluster löschen.

App löschen

So löschen Sie die Anwendung:

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

So prüfen Sie, ob die App entfernt wurde:

kubectl get gateway 
kubectl get virtualservices 
kubectl get pods

Istio deinstallieren

So löschen Sie Istio:

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

So prüfen Sie, ob Istio entfernt wurde:

kubectl get pods -n istio-system

Kubernetes-Cluster löschen

gcloud container clusters delete hello-istio