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.

Im ersten Teil des Labs stellen Sie eine einfache ASP.NET Core-Anwendung für Kubernetes bereit, die in Google Kubernetes Engine (GKE) ausgeführt wird, und konfigurieren sie für die Verwaltung durch Istio.

Im zweiten Teil des Labs lernen Sie die Features von Istio kennen, z. B. Messwerte, Tracing, dynamische Trafficverwaltung, Fehlerinjektion und mehr.

Lerninhalte

  • Einfache ASP.NET Core-App in einem Docker-Container erstellen und verpacken
  • Kubernetes-Cluster mit Google Kubernetes Engine (GKE) erstellen
  • Istio in einem Kubernetes-Cluster in GKE installieren.
  • ASP.NET Core-App bereitstellen und Traffic für die Verwaltung durch Istio konfigurieren

Voraussetzungen

Wie möchten Sie diese Anleitung nutzen?

<ph type="x-smartling-placeholder"></ph> Nur bis zum Ende lesen Lies sie dir durch und absolviere die Übungen

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

<ph type="x-smartling-placeholder"></ph> Neuling Mittel Kompetent

2. Einrichtung und Anforderungen

Umgebung für das selbstbestimmte 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 in diesem Codelab später als PROJECT_ID bezeichnet.

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

Dieses Codelab sollte möglichst wenig kosten. Folgen Sie der Anleitung im Abschnitt „Bereinigen“, . Hier erfahren Sie, wie Sie Ressourcen herunterfahren, damit Ihnen über dieses Tutorial hinaus keine Kosten entstehen. Neue Google Cloud-Nutzer haben Anspruch auf eine kostenlose Testversion mit 300$Guthaben.

Cloud Shell starten

Sie können Google Cloud zwar von Ihrem Laptop aus der Ferne bedienen, in diesem Codelab verwenden Sie jedoch Google Cloud Shell, 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 Cloud Shell noch nie gestartet haben, wird ein Zwischenbildschirm (below the fold) angezeigt, in dem beschrieben wird, worum es sich dabei handelt. Klicken Sie in diesem Fall auf Weiter. Der Chat wird nie wieder angezeigt. So sieht dieser einmalige Bildschirm aus:

70f315d7b402b476.png

Die Bereitstellung und Verbindung mit Cloud Shell dauert nur einen Moment.

fbe3a0674c982259.png

Diese virtuelle Maschine verfügt über alle Entwicklungstools, die Sie benötigen. Es bietet ein Basisverzeichnis mit 5 GB nichtflüchtigem Speicher und wird in Google Cloud ausgeführt. Dadurch werden die Netzwerkleistung und die Authentifizierung erheblich verbessert. Viele, wenn nicht sogar alle Arbeiten in diesem Codelab können Sie ganz einfach mit einem Browser oder Ihrem Chromebook erledigen.

Sobald Sie mit Cloud Shell verbunden sind, sollten Sie sehen, dass Sie bereits authentifiziert sind und dass das Projekt bereits auf Ihre Projekt-ID eingestellt ist.

  1. Führen Sie in 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 in Cloud Shell den folgenden Befehl aus, um zu prüfen, ob 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 überprüfen, ob das dotnet-Befehlszeilentool bereits installiert ist, indem Sie die Version prüfen. Damit sollte die Version des installierten dotnet-Befehlszeilentools angezeigt werden:

dotnet --version

Erstellen Sie als Nächstes das Grundgerüst einer 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

Wir sind fast bereit, unsere App auszuführen. Rufen Sie den App-Ordner auf.

cd HelloWorldAspNetCore

Abschließend führen Sie die App 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.

Wenn Sie prüfen möchten, ob die App ausgeführt wird, klicken Sie oben rechts auf die Schaltfläche „Webvorschau“ und wählen Sie „Vorschau auf Port 8080“ aus.

Capture.PNG

Sie sehen die standardmäßige ASP.NET Core-Webseite:

f579a9baedc108a9.png

Sobald Sie überprüft haben, dass die Anwendung 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 für die Ausführung als Container vor. Dazu legen Sie zuerst den Container und seine Inhalte fest.

Erstellen Sie im Basisverzeichnis der Anwendung einen Dockerfile, um das Docker-Image zu definieren.

touch Dockerfile

Fügen Sie mit Ihrem bevorzugten Editor (vim, nano,emacs oder Cloud Shell-Codeeditor) Folgendes zu Dockerfile 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). Dazu wird die Umgebungsvariable ASPNETCORE_URLS festgelegt, mit der ASP.NET Core-Apps bestimmen, welcher Port überwacht werden soll.

Dockerfile speichern. Jetzt erstellen wir das Image:

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

Sobald der Vorgang abgeschlossen ist (es dauert einige Zeit, bis alles heruntergeladen und extrahiert werden kann) können Sie sehen, 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, der einen Docker-Container lokal auf Port 8080 aus Ihrem neu erstellten Container-Image ausführt:

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

Nutzen Sie auch hier wieder die Webvorschaufunktion von Cloud Shell :

Screenshot vom 03.11.2015 17:20:22.png

Die standardmäßige ASP.NET Core-Webseite sollte in einem neuen Tab angezeigt werden.

f579a9baedc108a9.png

Nachdem Sie sichergestellt haben, dass die Anwendung lokal in einem Docker-Container problemlos ausgeführt wird, können Sie den ausgeführten Container mit Ctrl-> C beenden.

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, und nach kurzer Zeit sollten Sie das Container-Image im Abschnitt Container Registry sehen können. Jetzt steht Ihnen ein projektweites Docker-Image zur Verfügung, auf das Kubernetes zugreifen und es orchestrieren kann, wie Sie gleich sehen werden.

73558f3a54ce1c0c.png

Bei Interesse können Sie sich die in Google Cloud Storage gespeicherten Container-Images ansehen. Klicken Sie dazu auf diesen Link: https://console.cloud.google.com/storage/browser/. Der vollständige Link sollte folgendes 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 auf einen Ort in Ihrer Nähe festlegen, wenn Sie möchten:

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. Sie wird im Abschnitt „Kubernetes Engine“ der Google Cloud Platform Console angezeigt.

e46fd9c6ee82bcc4.png

Für dieses 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 nachfolgenden Anwendungsschritte funktionieren bei jeder Istio-Installation.

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

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

Das Skript teilt Ihnen mit, welche Version von Istio heruntergeladen wurde:

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

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

cd istio-1.8.1

Kopieren Sie den angegebenen Befehl und fügen Sie ihn ein, um das Verzeichnis bin zu PATH 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. Prüfen Sie dazu, ob der Cluster für Istio bereit ist:

istioctl x precheck

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

Installieren Sie Istio mit dem Demoprofil:

istioctl install --set profile=demo

Istio ist jetzt in Ihrem Cluster installiert.

Automatische Sidecar-Einfügung

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

Damit dies funktioniert, müssen Sie die Sidecar-Injektion für den Namespace („Standard“) aktivieren, den Sie für Ihre Mikrodienste verwenden. Dazu wenden Sie ein Label an:

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 bietet drei Dienste: die istiod-Steuerungsebene sowie Eingangs- und Ausgangsgateways (die Sie als „Sidecar-Proxys für den Rest des Internets“ betrachten können) mit den Namen istio-ingressgateway und 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 nur innerhalb des Clusters zugänglich sein müssen.

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. Verwaltet die Konfiguration und Programmierung der Proxy-Sidecars, Diensterkennung, Zertifikatsverteilung und Sidecar-Injektion
  • ingress gateway: verarbeitet eingehende Anfragen von außerhalb des Clusters.
  • egress gateway: Verarbeitet ausgehende Anfragen an Endpunkte außerhalb des Clusters.

8. Anwendung bereitstellen

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

Bereitstellung und Service

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 Anwendung:

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 sind Standardbereitstellungen und ‐dienste zur Bereitstellung der Anwendung und enthält keine Istio-spezifischen Elemente.

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-Netzwerk erreicht, müssen Sie ein Gateway und einen VirtualService erstellen.

Ein Gateway konfiguriert einen Load-Balancer für HTTP/TCP-Traffic, der sich meist am Rand des Mesh-Netzwerks befindet, um eingehenden Traffic für eine Anwendung zu ermöglichen. Ein VirtualService definiert die Regeln, die steuern, wie Anfragen für einen Dienst innerhalb eines 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 Befehl „kubectl“ aus, um das Gateway bereitzustellen mit:

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 funktioniert:

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, wie die Anwendung verwendet wird.

9. Anwendung testen

Endlich können Sie die Anwendung in Aktion sehen. Sie müssen die externe IP-Adresse und den Port des Gateways abrufen. Sie ist 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

Verwende curl, um die App zu testen. Der Dienst sollte mit dem Antwortcode 200 antworten:

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

Alternativ können Sie auch den Browser öffnen und zu http://<gatewayurl> gehen, um sich die App anzusehen:

f579a9baedc108a9.png

10. Glückwunsch!

Sie haben gerade eine einfache ASP.NET Core-App auf Kubernetes bereitgestellt, die in Google Kubernetes Engine (GKE) ausgeführt wird, und für die Verwaltung durch Istio konfiguriert.

Sie fragen sich vielleicht, welche Vorteile Istio bietet. Das ist eine sehr gute Frage. Bislang bietet es keinen Vorteil, diese Anwendung von Istio verwalten zu lassen. Im zweiten Teil des Labs lernen Sie die Features von Istio kennen, 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 Anwendung 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 nicht mehr verfügbar ist:

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 nicht mehr verfügbar ist:

kubectl get pods -n istio-system

Kubernetes-Cluster löschen

gcloud container clusters delete hello-istio