Wdrażanie i aktualizowanie aplikacji .NET Core w Google Kubernetes Engine

1. Omówienie

Microsoft .NET Core to wieloplatformowa, open source wersja .NET, która może działać natywnie w kontenerach. Oprogramowanie .NET Core jest dostępne w GitHubie i utrzymywane przez Microsoft oraz społeczność .NET. W tym module wdrażamy skonteneryzowaną aplikację .NET Core w Google Kubernetes Engine (GKE).

W tym module powtarza się typowy schemat programowania – aplikacje są tworzone w lokalnym środowisku programistycznym, a następnie wdrażane w środowisku produkcyjnym. W pierwszej części modułu weryfikowana jest przykładowa aplikacja podstawowa .NET, korzystając z kontenera działającego w Cloud Shell. Po zweryfikowaniu aplikacja jest wdrażana w Kubernetes przy użyciu GKE. Moduł obejmuje kroki potrzebne do utworzenia klastra GKE.

W drugiej części modułu wprowadzamy niewielką zmianę w aplikacji, w której wyświetla się nazwa hosta kontenera, w którym działa dana instancja aplikacji. Zaktualizowana aplikacja jest następnie weryfikowana w Cloud Shell, a wdrożenie jest aktualizowane pod kątem nowej wersji. Poniższa ilustracja przedstawia sekwencję zadań w tym module:

Diagram sekwencji demonstracyjnej

Koszty

Jeśli przeprowadzisz ten moduł dokładnie w takiej formie, zaczną obowiązywać normalne opłaty za poniższe usługi

2. Konfiguracja i wymagania

Wymagania wstępne

Do ukończenia tego modułu wymagane są konto i projekt Google Cloud. Szczegółowe instrukcje tworzenia nowego projektu znajdziesz w tych ćwiczeniach z programowania.

W tym module wykorzystano narzędzie Dockera uruchomione w Cloud Shell, które jest dostępne w konsoli Google Cloud i jest wstępnie skonfigurowane oraz zawiera wiele przydatnych narzędzi, takich jak gcloud i Docker. Poniżej dowiesz się, jak uzyskać dostęp do Cloud Shell. Kliknij ikonę Cloud Shell w prawym górnym rogu, aby wyświetlić ją w dolnym panelu okna konsoli.

Cloud Shell

Alternatywne opcje konfiguracji klastra GKE (opcjonalnie)

Ten moduł wymaga klastra Kubernetes. W następnej sekcji zostanie utworzony klaster GKE z prostą konfiguracją. W tej sekcji znajdziesz niektóre polecenia gcloud z alternatywnymi opcjami konfiguracji do użycia podczas tworzenia klastra Kubernetes przy użyciu GKE. Za pomocą poniższych poleceń można na przykład zidentyfikować różne typy maszyn, strefy, a nawet GPU (akceleratory).

  • Wyświetl typy maszyn za pomocą tego polecenia gcloud compute machine-types list
  • Wyświetl listę GPU za pomocą tego polecenia gcloud compute accelerator-types list
  • Wyświetl strefy obliczeniowe za pomocą tego polecenia gcloud compute zones list
  • Pomoc dotycząca dowolnego polecenia gcloud gcloud container clusters --help
    • Na przykład tutaj znajdziesz szczegółowe informacje o tworzeniu klastra Kubernetes gcloud container clusters create --help

Pełną listę opcji konfiguracyjnych GKE znajdziesz w tym dokumencie.

Przygotowanie do utworzenia klastra Kubernetes

W Cloud Shell konieczne jest ustawienie pewnych zmiennych środowiskowych i skonfigurowanie klienta gcloud. Można to zrobić za pomocą następujących poleceń.

export PROJECT_ID=YOUR_PROJECT_ID
export DEFAULT_ZONE=us-central1-c

gcloud config set project ${PROJECT_ID}
gcloud config set compute/zone ${DEFAULT_ZONE}

Tworzenie klastra GKE

W tym module wdrażana jest aplikacja .NET Core w Kubernetes, dlatego musisz utworzyć klaster. Użyj poniższego polecenia, aby utworzyć nowy klaster Kubernetes w Google Cloud przy użyciu GKE.

gcloud container clusters create dotnet-cluster \
  --zone ${DEFAULT_ZONE} \
  --num-nodes=1 \
  --node-locations=${DEFAULT_ZONE},us-central1-b \
  --enable-stackdriver-kubernetes \
  --machine-type=n1-standard-1 \
  --workload-pool=${PROJECT_ID}.svc.id.goog \
  --enable-ip-alias
  • --num-nodes to liczba węzłów, które należy dodać na strefę. Można ją później skalować.
  • --node-locations to rozdzielona przecinkami lista stref. W tym przypadku strefa określona w powyższej zmiennej środowiskowej i strefa us-central1-b jest używana
    • UWAGA: ta lista nie może zawierać duplikatów
  • --workload-pool określa tożsamość zadań, aby zadania GKE miały dostęp do usług Google Cloud

Podczas tworzenia klastra wyświetlane są następujące elementy

Creating cluster dotnet-cluster in us-central1-b... Cluster is being deployed...⠼

Konfigurowanie kubectl

Interfejs wiersza poleceń kubectl to główny sposób interakcji z klastrem Kubernetes. Aby można było używać go z nowo utworzonym klastrem, należy go skonfigurować pod kątem uwierzytelniania w klastrze. Odbywa się to za pomocą tego polecenia.

$ gcloud container clusters get-credentials dotnet-cluster --zone ${DEFAULT_ZONE}
Fetching cluster endpoint and auth data.
kubeconfig entry generated for dotnet-cluster.

Korzystanie z usługi kubectl do interakcji z klastrem powinno być teraz możliwe.

$ kubectl get nodes
NAME                                            STATUS   ROLES    AGE     VERSION
gke-dotnet-cluster-default-pool-02c9dcb9-fgxj   Ready    <none>   2m15s   v1.16.13-gke.401
gke-dotnet-cluster-default-pool-ed09d7b7-xdx9   Ready    <none>   2m24s   v1.16.13-gke.401

3. Przetestuj lokalnie funkcje i potwierdź odpowiednie działanie

W tym module używane są poniższe obrazy kontenerów z oficjalnego repozytorium .NET w centrum Dockera.

Uruchom kontener lokalnie, aby sprawdzić jego działanie

Sprawdź w Cloud Shell, czy Docker działa prawidłowo i czy kontener .NET działa zgodnie z oczekiwaniami, uruchamiając to polecenie Dockera:

$ docker run --rm mcr.microsoft.com/dotnet/samples

      Hello from .NET!
      __________________
                        \
                        \
                            ....
                            ....'
                            ....
                          ..........
                      .............'..'..
                  ................'..'.....
                .......'..........'..'..'....
                ........'..........'..'..'.....
              .'....'..'..........'..'.......'.
              .'..................'...   ......
              .  ......'.........         .....
              .                           ......
              ..    .            ..        ......
            ....       .                 .......
            ......  .......          ............
              ................  ......................
              ........................'................
            ......................'..'......    .......
          .........................'..'.....       .......
      ........    ..'.............'..'....      ..........
    ..'..'...      ...............'.......      ..........
    ...'......     ...... ..........  ......         .......
  ...........   .......              ........        ......
  .......        '...'.'.              '.'.'.'         ....
  .......       .....'..               ..'.....
    ..       ..........               ..'........
            ............               ..............
          .............               '..............
          ...........'..              .'.'............
        ...............              .'.'.............
        .............'..               ..'..'...........
        ...............                 .'..............
        .........                        ..............
          .....
  
Environment:
.NET 5.0.1-servicing.20575.16
Linux 5.4.58-07649-ge120df5deade #1 SMP PREEMPT Wed Aug 26 04:56:33 PDT 2020

Potwierdź funkcje aplikacji internetowej

Przykładowa aplikacja internetowa w usłudze można również zweryfikować w Cloud Shell. Poniższe polecenie uruchomienia Dockera tworzy nowy kontener, który udostępnia port 80 i mapuje go na port localhost 8080. Pamiętaj, że w tym przypadku obiekt localhost znajduje się w Cloud Shell.

$ docker run -it --rm -p 8080:80 --name aspnetcore_sample mcr.microsoft.com/dotnet/samples:aspnetapp
warn: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[60]
      Storing keys in a directory '/root/.aspnet/DataProtection-Keys' that may not be persisted outside of the container. Protected data will be unavailable when container is destroyed.
warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]
      No XML encryptor configured. Key {64a3ed06-35f7-4d95-9554-8efd38f8b5d3} may be persisted to storage in unencrypted form.
info: Microsoft.Hosting.Lifetime[0]
      Now listening on: http://[::]:80
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]
      Content root path: /app

Ponieważ jest to aplikacja internetowa, należy ją wyświetlić i zweryfikować w przeglądarce internetowej. W następnej sekcji dowiesz się, jak to zrobić w Cloud Shell przy użyciu podglądu w przeglądarce.

4. Dostęp do usług w Cloud Shell za pomocą funkcji „Podgląd w przeglądarce”

Cloud Shell udostępnia podgląd w przeglądarce, który umożliwia interakcję z procesami uruchomionymi w instancji Cloud Shell za pomocą przeglądarki.

Użyj „Podglądu w przeglądarce” aby wyświetlać aplikacje w Cloud Shell

W Cloud Shell kliknij przycisk podglądu w przeglądarce i wybierz „Podejrzyj na porcie 8080”. (lub innego portu w podglądzie w przeglądarce).

Cloud Shell

Spowoduje to otwarcie okna przeglądarki z adresem podobnym do tego:

https://8080-cs-754738286554-default.us-central1.cloudshell.dev/?authuser=0

Wyświetl przykładową aplikację .NET za pomocą podglądu w przeglądarce

Przykładowa aplikacja uruchomiona w ostatnim kroku można teraz wyświetlić, uruchamiając podgląd w przeglądarce i wczytując podany adres URL. Powinna wyglądać mniej więcej tak:

Zrzut ekranu aplikacji .NET w wersji 1

5. Wdróż w Kubernetes

Tworzenie i stosowanie pliku YAML

Następny krok wymaga pliku YAML z opisem 2 zasobów Kubernetes: wdrożenia i usługi. Utwórz w Cloud Shell plik o nazwie dotnet-app.yaml i dodaj do niego tę zawartość.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: dotnet-deployment
  labels:
    app: dotnetapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: dotnetapp
  template:
    metadata:
      labels:
        app: dotnetapp
    spec:
      containers:
      - name: dotnet
        image: mcr.microsoft.com/dotnet/samples:aspnetapp
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: dotnet-service
spec:
    selector:
      app: dotnetapp
    ports:
      - protocol: TCP
        port: 8080
        targetPort: 80

Teraz użyj narzędzia kubectl, aby zastosować ten plik w Kubernetes.

$ kubectl apply -f dotnet-app.yaml
deployment.apps/dotnet-deployment created
service/dotnet-service created

Zwróć uwagę na komunikaty wskazujące, że odpowiednie zasoby zostały utworzone.

Zapoznaj się z dostępnymi materiałami

Za pomocą interfejsu wiersza poleceń kubectl możemy zbadać zasoby utworzone powyżej. Najpierw przyjrzyjmy się zasobom dotyczącym wdrażania i sprawdźmy, czy nowe wdrożenie już istnieje.

$ kubectl get deployment
NAME                READY   UP-TO-DATE   AVAILABLE   AGE
dotnet-deployment   3/3     3            3           80s

Teraz przyjrzyjmy się obiektom ReplicaSets. Powyższe wdrożenie powinno tworzyć obiekt ReplicaSet.

$ kubectl get replicaset
NAME                           DESIRED   CURRENT   READY   AGE
dotnet-deployment-5c9d4cc4b9   3         3         3       111s

Na koniec przyjrzyj się Podom. Zasób Deployment wskazuje, że powinny istnieć 3 instancje. Poniższe polecenie powinno pokazywać 3 instancje. Opcja -o wide została dodana, dzięki czemu będą wyświetlane węzły, w których działają te instancje.

$ kubectl get pod -o wide
NAME                                 READY   STATUS    RESTARTS   AGE     IP          NODE                                            NOMINATED NODE   READINESS GATES
dotnet-deployment-5c9d4cc4b9-cspqd   1/1     Running   0          2m25s   10.16.0.8   gke-dotnet-cluster-default-pool-ed09d7b7-xdx9   <none>           <none>
dotnet-deployment-5c9d4cc4b9-httw6   1/1     Running   0          2m25s   10.16.1.7   gke-dotnet-cluster-default-pool-02c9dcb9-fgxj   <none>           <none>
dotnet-deployment-5c9d4cc4b9-vvdln   1/1     Running   0          2m25s   10.16.0.7   gke-dotnet-cluster-default-pool-ed09d7b7-xdx9   <none>           <none>

Sprawdzanie zasobu usługi

Zasób usługi w Kubernetes to system równoważenia obciążenia. Punkty końcowe są określane przez etykiety w podach. Dzięki temu po dodaniu do wdrożenia nowych podów za pomocą powyższej operacji kubectl scale deployment utworzone pody są od razu dostępne dla żądań obsługiwanych przez tę usługę.

Poniższe polecenie powinno wyświetlić zasób Service.

$ kubectl get svc
NAME             TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)    AGE
dotnet-service   ClusterIP   10.20.9.124   <none>        8080/TCP   2m50s
...

Za pomocą poniższego polecenia możesz wyświetlić więcej informacji o usłudze.

$ kubectl describe svc dotnet-service
Name:              dotnet-service
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          app=dotnetapp
Type:              ClusterIP
IP:                10.20.9.124
Port:              <unset>  8080/TCP
TargetPort:        80/TCP
Endpoints:         10.16.0.7:80,10.16.0.8:80,10.16.1.7:80
Session Affinity:  None
Events:            <none>

Zwróć uwagę, że typ usługi to ClusterIP. Oznacza to, że dowolny pod w klastrze może rozpoznać nazwę usługi (dotnet-service) na swój adres IP. Żądania wysyłane do usługi będą równoważone obciążenie we wszystkich instancjach (podach). Powyższa wartość Endpoints to adresy IP podów obecnie dostępnych dla tej usługi. Porównaj je z adresami IP podów, które zostały wyświetlone powyżej.

Sprawdź uruchomioną aplikację

W tym momencie aplikacja jest aktywna i gotowa do obsługi żądań użytkowników. Aby uzyskać do niego dostęp, użyj serwera proxy. Poniższe polecenie tworzy lokalny serwer proxy, który akceptuje żądania na porcie 8080 i przekazuje je do klastra Kubernetes.

$ kubectl proxy --port 8080
Starting to serve on 127.0.0.1:8080

Aby uzyskać dostęp do aplikacji internetowej, użyj teraz podglądu w przeglądarce w Cloud Shell.

Do adresu URL wygenerowanego przez Podgląd w przeglądarce dodaj ten fragment: /api/v1/namespaces/default/services/dotnet-service:8080/proxy/. Efekt będzie wyglądał mniej więcej tak:

https://8080-cs-473655782854-default.us-central1.cloudshell.dev/api/v1/namespaces/default/services/dotnet-service:8080/proxy/

Gratulujemy wdrożenia aplikacji .NET Core w Google Kubernetes Engine. Następnie wprowadzimy zmianę w aplikacji i wprowadzimy ją ponownie.

6. Modyfikowanie aplikacji

W tej sekcji aplikacja zostanie zmodyfikowana, aby wyświetlić hosta, na którym działa instancja. Dzięki temu będzie można sprawdzić, czy równoważenie obciążenia działa i czy dostępne pody odpowiadają zgodnie z oczekiwaniami.

Pobieranie kodu źródłowego

git clone https://github.com/dotnet/dotnet-docker.git
cd dotnet-docker/samples/aspnetapp/

Zaktualizuj aplikację, dodając do niej nazwę hosta.

vi aspnetapp/Pages/Index.cshtml
    <tr>
        <td>Host</td>
        <td>@Environment.MachineName</td>
    </tr>

Tworzenie nowego obrazu kontenera i testowanie go lokalnie

Utwórz nowy obraz kontenera ze zaktualizowanym kodem.

docker build --pull -t aspnetapp:alpine -f Dockerfile.alpine-x64 .

Tak jak poprzednio przetestuj nową aplikację lokalnie

$ docker run --rm -it -p 8080:80 aspnetapp:alpine
warn: Microsoft.AspNetCore.DataProtection.Repositories.FileSystemXmlRepository[60]
      Storing keys in a directory '/root/.aspnet/DataProtection-Keys' that may not be persisted outside of the container. Protected data will be unavailable when container is destroyed.
warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]
      No XML encryptor configured. Key {f71feb13-8eae-4552-b4f2-654435fff7f8} may be persisted to storage in unencrypted form.
info: Microsoft.Hosting.Lifetime[0]
      Now listening on: http://[::]:80
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]
      Content root path: /app

Tak jak wcześniej, dostęp do aplikacji można uzyskać za pomocą podglądu w przeglądarce. Tym razem parametr Host powinien być widoczny, jak tutaj:

Cloud Shell

Otwórz nową kartę w Cloud Shell i uruchom polecenie docker ps, aby sprawdzić, czy identyfikator kontenera odpowiada powyższej wartości Host.

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                  NAMES
ab85ce11aecd        aspnetapp:alpine    "./aspnetapp"       2 minutes ago       Up 2 minutes        0.0.0.0:8080->80/tcp   relaxed_northcutt

Dodaj tag do obrazu i przekaż go, aby był dostępny w Kubernetes

Obraz musi zostać otagowany i wypchnięty, aby można go było pobrać przez Kubernetes. Zacznij od wyświetlenia listy obrazów kontenerów i określenia odpowiedniego obrazu.

$ docker image list
REPOSITORY                                         TAG                 IMAGE ID            CREATED             SIZE
aspnetapp                                          alpine              95b4267bb6d0        6 days ago          110MB

Następnie otaguj obraz i przekaż go do Google Container Registry. Przy użyciu powyższego identyfikatora IMAGE będzie on wyglądać tak

docker tag 95b4267bb6d0 gcr.io/${PROJECT_ID}/aspnetapp:alpine
docker push gcr.io/${PROJECT_ID}/aspnetapp:alpine

7. Wdróż ponownie zaktualizowaną aplikację

Edytuj plik YAML

Wróć do katalogu, w którym zapisany jest plik dotnet-app.yaml. Znajdź następujący wiersz w pliku YAML

        image: mcr.microsoft.com/dotnet/core/samples:aspnetapp

Trzeba to zmienić, aby odwołać się do obrazu kontenera, który został utworzony i przeniesiony do gcr.io powyżej.

        image: gcr.io/PROJECT_ID/aspnetapp:alpine

Nie zapomnij go zmodyfikować, aby korzystać z PROJECT_ID. Po zakończeniu pracy powinien on wyglądać mniej więcej tak

        image: gcr.io/myproject/aspnetapp:alpine

Zastosuj zaktualizowany plik YAML

$ kubectl apply -f dotnet-app.yaml
deployment.apps/dotnet-deployment configured
service/dotnet-service unchanged

Zwróć uwagę, że zasób Deployment wyświetla się jako zaktualizowany, a zasób Service – bez zmian. Zaktualizowane pody można zobaczyć tak jak poprzednio przy użyciu polecenia kubectl get pod, ale tym razem dodamy -w, który będzie na bieżąco obserwować wszystkie zmiany.

$ kubectl get pod -w
NAME                                 READY   STATUS              RESTARTS   AGE
dotnet-deployment-5c9d4cc4b9-cspqd   1/1     Running             0          34m
dotnet-deployment-5c9d4cc4b9-httw6   1/1     Running             0          34m
dotnet-deployment-5c9d4cc4b9-vvdln   1/1     Running             0          34m
dotnet-deployment-85f6446977-tmbdq   0/1     ContainerCreating   0          4s
dotnet-deployment-85f6446977-tmbdq   1/1     Running             0          5s
dotnet-deployment-5c9d4cc4b9-vvdln   1/1     Terminating         0          34m
dotnet-deployment-85f6446977-lcc58   0/1     Pending             0          0s
dotnet-deployment-85f6446977-lcc58   0/1     Pending             0          0s
dotnet-deployment-85f6446977-lcc58   0/1     ContainerCreating   0          0s
dotnet-deployment-5c9d4cc4b9-vvdln   0/1     Terminating         0          34m
dotnet-deployment-85f6446977-lcc58   1/1     Running             0          6s
dotnet-deployment-5c9d4cc4b9-cspqd   1/1     Terminating         0          34m
dotnet-deployment-85f6446977-hw24v   0/1     Pending             0          0s
dotnet-deployment-85f6446977-hw24v   0/1     Pending             0          0s
dotnet-deployment-5c9d4cc4b9-cspqd   0/1     Terminating         0          34m
dotnet-deployment-5c9d4cc4b9-vvdln   0/1     Terminating         0          34m
dotnet-deployment-5c9d4cc4b9-vvdln   0/1     Terminating         0          34m
dotnet-deployment-85f6446977-hw24v   0/1     Pending             0          2s
dotnet-deployment-85f6446977-hw24v   0/1     ContainerCreating   0          2s
dotnet-deployment-5c9d4cc4b9-cspqd   0/1     Terminating         0          34m
dotnet-deployment-5c9d4cc4b9-cspqd   0/1     Terminating         0          34m
dotnet-deployment-85f6446977-hw24v   1/1     Running             0          3s
dotnet-deployment-5c9d4cc4b9-httw6   1/1     Terminating         0          34m
dotnet-deployment-5c9d4cc4b9-httw6   0/1     Terminating         0          34m

Te dane wyjściowe pokazują bieżącą aktualizację kroczącą. Po pierwsze uruchamiane są nowe kontenery, a po uruchomieniu wyłączane są stare kontenery.

Sprawdź uruchomioną aplikację

W tym momencie aplikacja jest aktualizowana i gotowa do obsługi żądań użytkowników. Tak jak poprzednio można uzyskać do niego dostęp za pomocą serwera proxy.

$ kubectl proxy --port 8080
Starting to serve on 127.0.0.1:8080

Aby uzyskać dostęp do aplikacji internetowej, użyj teraz podglądu w przeglądarce w Cloud Shell.

Do adresu URL wygenerowanego przez Podgląd w przeglądarce dodaj ten fragment: /api/v1/namespaces/default/services/dotnet-service:8080/proxy/. Efekt będzie wyglądał mniej więcej tak:

https://8080-cs-473655782854-default.us-central1.cloudshell.dev/api/v1/namespaces/default/services/dotnet-service:8080/proxy/

Sprawdzanie, czy usługa Kubernetes rozkłada obciążenie

Odśwież ten adres URL kilka razy i zauważ, że host się zmienia, ponieważ obciążenie żądaniami jest równoważone w różnych podach przez usługę. Porównaj wartości hosta z powyższą listą podów, aby sprawdzić, czy wszystkie pody odbierają ruch.

Skalowanie instancji w górę

Skalowanie aplikacji w Kubernetes jest proste. Widoczne poniżej polecenie przeskaluje wdrożenie do 6 instancji aplikacji.

$ kubectl scale deployment dotnet-deployment --replicas 6
deployment.apps/dotnet-deployment scaled

Nowe pody i ich bieżący stan można wyświetlić za pomocą tego polecenia

kubectl get pod -w

Zwróć uwagę, że odświeżenie tego samego okna przeglądarki pokazuje, że ruch jest teraz równoważony we wszystkich nowych podach.

8. Gratulacje!

W tym module zweryfikowano przykładową aplikację internetową .NET Core w środowisku programistycznym, a następnie wdrożono ją w Kubernetes przy użyciu GKE. Następnie aplikacja została zmodyfikowana, tak aby wyświetlała nazwę hosta kontenera, w którym działała. Następnie wdrożenie Kubernetes zostało zaktualizowane do nowej wersji, a aplikację przeskalowano w górę, aby zademonstrować rozkład obciążenia między dodatkowymi instancjami.

Aby dowiedzieć się więcej o .NET i Kubernetes, zapoznaj się z tymi samouczkami. Bazują one na wiedzy zdobytej w tym module przez wprowadzenie Istio Service Mesh na potrzeby bardziej zaawansowanych wzorców routingu i odporności.

9. Czyszczenie danych

Aby uniknąć niezamierzonych kosztów, usuń klaster i obraz kontenera utworzone w tym module za pomocą podanych niżej poleceń.

gcloud container clusters delete dotnet-cluster --zone ${DEFAULT_ZONE}
gcloud container images delete gcr.io/${PROJECT_ID}/aspnetapp:alpine