Wdrażanie aplikacji ASP.NET Core w Google Kubernetes Engine za pomocą Istio (część 1)

1. Przegląd

ASP.NET Core to platforma typu open source i na wielu platformach, która umożliwia tworzenie nowoczesnych aplikacji działających w chmurze i połączonych z internetem przy użyciu języka programowania C#.

Kubernetes to system open source do automatyzacji wdrażania i skalowania skonteneryzowanych aplikacji oraz zarządzania nimi. Istio to otwarta platforma do łączenia, zabezpieczania, zarządzania i monitorowania usług.

W pierwszej części tego modułu wdrożysz prostą aplikację ASP.NET Core w Kubernetes działającym w Google Kubernetes Engine (GKE) i skonfigurujesz ją tak, aby była zarządzana przez Istio.

W drugiej części modułu dowiesz się więcej o funkcjach Istio, takich jak pomiary, śledzenie, dynamiczne zarządzanie ruchem, wstrzykiwanie błędów i inne.

Czego się nauczysz

  • Jak utworzyć i spakować prostą aplikację ASP.NET Core w kontenerze Dockera.
  • Jak utworzyć klaster Kubernetes za pomocą Google Kubernetes Engine (GKE).
  • Jak zainstalować Istio w klastrze Kubernetes w GKE.
  • Jak wdrożyć aplikację ASP.NET Core i skonfigurować ruch, którym będzie zarządzać Istio.

Czego potrzebujesz

Jak zamierzasz korzystać z tego samouczka?

Tylko przeczytaj Przeczytaj i wykonaj ćwiczenia

Jak oceniasz korzystanie z Google Cloud Platform?

Początkujący Średnio zaawansowany Zaawansowany

2. Konfiguracja i wymagania

Samodzielne konfigurowanie środowiska

  1. Zaloguj się w konsoli Google Cloud i utwórz nowy projekt lub użyj istniejącego. Jeśli nie masz jeszcze konta Gmail ani Google Workspace, musisz je utworzyć.

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

Zapamiętaj identyfikator projektu, czyli unikalną nazwę we wszystkich projektach Google Cloud (podana powyżej nazwa jest już zajęta i nie będzie działać w Twoim przypadku). W dalszej części tego laboratorium będzie on nazywany PROJECT_ID.

  1. Następnie musisz włączyć rozliczenia w konsoli Cloud, aby korzystać z zasobów Google Cloud.

Ukończenie tego laboratorium nie powinno wiązać się z dużymi kosztami, a nawet z żadnymi. Wykonaj instrukcje z sekcji „Czyszczenie”, w której znajdziesz informacje o tym, jak wyłączyć zasoby, aby uniknąć naliczenia opłat po zakończeniu tego samouczka. Nowi użytkownicy Google Cloud mogą skorzystać z bezpłatnego okresu próbnego, w którym mają do dyspozycji środki w wysokości 300 USD.

Uruchamianie Cloud Shell

Z Google Cloud możesz korzystać zdalnie na laptopie, ale w tym module użyjesz Google Cloud Shell, czyli środowiska wiersza poleceń działającego w Google Cloud.

Aktywowanie Cloud Shell

  1. W konsoli Cloud kliknij Aktywuj Cloud Shell 4292cbf4971c9786.png.

bce75f34b2c53987.png

Jeśli uruchamiasz Cloud Shell po raz pierwszy, zobaczysz ekran pośredni (część strony widoczna po przewinięciu) z opisem tego środowiska. W takim przypadku kliknij Dalej, a ten ekran nie będzie się już wyświetlać. Ten wyświetlany jednorazowo ekran wygląda tak:

70f315d7b402b476.png

Uzyskanie dostępu do środowiska Cloud Shell i połączenie się z nim powinno zająć tylko kilka chwil.

fbe3a0674c982259.png

Ta maszyna wirtualna zawiera wszystkie potrzebne narzędzia dla programistów. Zawiera również stały katalog domowy o pojemności 5 GB i działa w Google Cloud, co znacznie zwiększa wydajność sieci i usprawnia proces uwierzytelniania. Większość zadań w tym module, a być może wszystkie, możesz wykonać w przeglądarce lub na Chromebooku.

Po połączeniu z Cloud Shell zobaczysz, że uwierzytelnianie zostało już przeprowadzone, a projekt jest już ustawiony na Twój identyfikator projektu.

  1. Aby potwierdzić, że uwierzytelnianie zostało przeprowadzone, uruchom w Cloud Shell to polecenie:
gcloud auth list

Wynik polecenia

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

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Aby potwierdzić, że polecenie gcloud zna Twój projekt, uruchom w Cloud Shell to polecenie:
gcloud config list project

Wynik polecenia

[core]
project = <PROJECT_ID>

Jeśli nie, możesz go ustawić za pomocą tego polecenia:

gcloud config set project <PROJECT_ID>

Wynik polecenia

Updated property [core/project].

3. Tworzenie aplikacji ASP.NET Core w Cloud Shell

W wierszu poleceń Cloud Shell możesz sprawdzić, czy narzędzie wiersza poleceń dotnet jest już zainstalowane, sprawdzając jego wersję. Powinna się wyświetlić wersja zainstalowanego narzędzia wiersza poleceń dotnet:

dotnet --version

Następnie utwórz nową szkieletową aplikację internetową ASP.NET Core.

dotnet new mvc -o HelloWorldAspNetCore

Spowoduje to utworzenie projektu i przywrócenie zależności. Wyświetli się komunikat podobny do tego poniżej.

Restore completed in 11.44 sec for HelloWorldAspNetCore.csproj.

Restore succeeded.

4. Uruchamianie aplikacji ASP.NET Core

Nasza aplikacja jest już prawie gotowa do uruchomienia. Otwórz folder aplikacji.

cd HelloWorldAspNetCore

Na koniec uruchom aplikację.

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

Aplikacja zaczyna nasłuchiwać na porcie 8080.

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

Aby sprawdzić, czy aplikacja działa, kliknij przycisk podglądu w przeglądarce w prawym górnym rogu i wybierz „Podejrzyj na porcie 8080”.

Capture.PNG

Zobaczysz domyślną stronę internetową ASP.NET Core:

f579a9baedc108a9.png

Gdy sprawdzisz, czy aplikacja działa, naciśnij Ctrl+C, aby ją wyłączyć.

5. Pakowanie aplikacji ASP.NET Core w kontenerze Dockera

Następnie przygotuj aplikację do uruchomienia jako kontener. Pierwszym krokiem jest zdefiniowanie kontenera i jego zawartości.

W katalogu głównym aplikacji utwórz plik Dockerfile, aby zdefiniować obraz Dockera.

touch Dockerfile

Dodaj poniższy kod do pliku Dockerfile w ulubionym edytorze (vim, nano,emacs lub edytorze kodu 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"]

Ważną konfiguracją zawartą w pliku Dockerfile jest port, na którym aplikacja nasłuchuje ruchu przychodzącego (8080). Możesz to zrobić, ustawiając zmienną środowiskową ASPNETCORE_URLS, której aplikacje ASP.NET Core używają do określania portu, na którym mają nasłuchiwać.

Zapisz to Dockerfile. Teraz utwórzmy obraz:

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

Gdy proces się zakończy (pobieranie i wyodrębnianie wszystkich plików zajmie trochę czasu), zobaczysz, że obraz został utworzony i zapisany lokalnie:

docker images

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

Przetestuj obraz lokalnie za pomocą tego polecenia, które uruchomi kontener Dockera lokalnie na porcie 8080 z nowo utworzonego obrazu kontenera:

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

Ponownie skorzystaj z funkcji podglądu w przeglądarce Cloud Shell :

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

W nowej karcie powinna być widoczna domyślna strona internetowa ASP.NET Core.

f579a9baedc108a9.png

Gdy sprawdzisz, że aplikacja działa prawidłowo lokalnie w kontenerze Dockera, możesz zatrzymać działający kontener, klikając Ctrl-> C.

Teraz, gdy obraz działa zgodnie z oczekiwaniami, możesz przesłać go do Google Container Registry, czyli prywatnego repozytorium obrazów Dockera dostępnego z każdego projektu w chmurze Google (ale też spoza Google Cloud Platform) :

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

Jeśli wszystko przebiegnie pomyślnie, po chwili obraz kontenera powinien pojawić się w sekcji Container Registry. W tym momencie masz już dostępny obraz Dockera w całym projekcie, do którego Kubernetes może uzyskać dostęp i którym może zarządzać, co zobaczysz za kilka minut.

73558f3a54ce1c0c.png

Jeśli chcesz, możesz przejrzeć obrazy kontenerów przechowywane w Google Cloud Storage, klikając ten link: https://console.cloud.google.com/storage/browser/ (pełny link powinien mieć postać https://console.cloud.google.com/project/PROJECT_ID/storage/browser/).

6. Tworzenie klastra GKE z Istio

Najpierw upewnij się, że masz włączony interfejs Kubernetes Engine API:

gcloud services enable container.googleapis.com

Utwórz klaster Kubernetes. Możesz zmienić region na taki, który jest bliżej Ciebie:

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

Poczekaj chwilę, aż klaster zostanie skonfigurowany. Będzie on widoczny w sekcji Kubernetes Engine w konsoli Google Cloud Platform.

e46fd9c6ee82bcc4.png

W tym ćwiczeniu z programowania pobierzemy i zainstalujemy Istio ze strony istio.io. Dostępne są też inne opcje instalacji, w tym dodatek Istio do GKE i Anthos Service Mesh. Kolejne kroki będą działać w przypadku każdej instalacji Istio.

Najpierw pobierz klienta Istio i przykłady. Na stronie wersji Istio znajdziesz artefakty do pobrania dla kilku systemów operacyjnych. W naszym przypadku możemy użyć wygodnego polecenia, aby pobrać i rozpakować najnowszą wersję na naszą obecną platformę:

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

Skrypt wyświetli pobraną wersję Istio:

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

Katalog instalacyjny zawiera przykładowe aplikacje i binarny plik klienta istioctl. Przejdź do tego katalogu:

cd istio-1.8.1

Skopiuj i wklej podane polecenie, aby dodać katalog bin do PATH, dzięki czemu będziesz mieć możliwość korzystania z istioctl:

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

Sprawdź, czy istioctl jest dostępny, sprawdzając, czy klaster jest gotowy na Istio:

istioctl x precheck

Powinien wyświetlić się komunikat Install Pre-Check passed! The cluster is ready for Istio installation.

Zainstaluj Istio z profilem demonstracyjnym:

istioctl install --set profile=demo

Istio jest teraz zainstalowane w klastrze.

Automatyczne wstrzykiwanie kontenera dodatkowego

Aby zacząć korzystać z Istio, nie musisz wprowadzać żadnych zmian w aplikacji. Gdy skonfigurujesz i uruchomisz usługi, do każdego poda usługi automatycznie zostaną wstrzyknięte kontenery pomocnicze Envoy.

Aby to działało, musisz włączyć wstrzykiwanie kontenera pomocniczego w przestrzeni nazw („default”), której używasz w mikroserwisach. Aby to zrobić, zastosuj etykietę:

kubectl label namespace default istio-injection=enabled

Aby sprawdzić, czy etykieta została zastosowana, uruchom to polecenie:

kubectl get namespace -L istio-injection

Dane wyjściowe potwierdzają, że wstrzykiwanie kontenera dodatkowego jest włączone w domyślnej przestrzeni nazw:

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

7. Sprawdzanie instalacji

Istio ma 3 usługi: istiod platformę sterującą oraz bramy ruchu przychodzącego i wychodzącego (które można traktować jako „proxy typu sidecar dla reszty internetu”), odpowiednio istio-ingressgateway i istio-egressgateway.

kubectl get svc -n istio-system

Dane wyjściowe powinny wyglądać tak:

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>

Brama wejściowa ma typ LoadBalancer, więc jest dostępna z internetu. Pozostałe usługi muszą być dostępne tylko w klastrze.

Następnie sprawdź, czy odpowiednie pody Kubernetes są wdrożone, a wszystkie kontenery działają:

kubectl get pods -n istio-system

Gdy wszystkie pody będą uruchomione, możesz przejść dalej.

NAME                                    READY   STATUS
istio-egressgateway-674988f895-m6tk4    1/1     Running
istio-ingressgateway-6996f7dcc8-7lvm2   1/1     Running
istiod-6bf5fc8b64-j79hj                 1/1     Running
  • istiod: platforma sterująca Istio. Zajmuje się konfigurowaniem i programowaniem kontenerów pomocniczych serwera proxy, wykrywaniem usług, dystrybucją certyfikatów i wstrzykiwaniem kontenerów pomocniczych.
  • ingress gateway: obsługuje przychodzące żądania spoza klastra.
  • egress gateway: obsługuje żądania wychodzące do punktów końcowych poza klastrem.

8. Wdrażanie aplikacji

Po sprawdzeniu, czy Istio jest zainstalowane i działa, możesz wdrożyć aplikację ASP.NET Core.

Wdrażanie i obsługa

Najpierw utwórz plik aspnetcore.yaml w ulubionym edytorze (vim, nano,emacs lub edytorze kodu Cloud Shell) i zdefiniuj wdrożenie i usługę Kubernetes dla aplikacji:

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

Zawartość pliku to standardowe wdrożenia i usługi do wdrażania aplikacji, które nie zawierają niczego związanego z Istio.

Wdróż usługi w domyślnej przestrzeni nazw za pomocą polecenia kubectl:

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

Sprawdź, czy pody są uruchomione:

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

Brama i usługa wirtualna

Aby zezwolić na ruch przychodzący do siatki, musisz utworzyć bramęVirtualService.

Brama konfiguruje system równoważenia obciążenia dla ruchu HTTP/TCP, który najczęściej działa na krawędzi siatki, aby umożliwić ruch przychodzący do aplikacji. Usługa wirtualna określa reguły, które kontrolują sposób kierowania żądań do usługi w siatce usług Istio.

Utwórz plik aspnetcore-gateway.yaml, aby zdefiniować bramę:

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

Utwórz plik aspnetcore-virtualservice.yaml, aby zdefiniować VirtualService:

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

Aby wdrożyć bramę, uruchom polecenie kubectl:

kubectl apply -f aspnetcore-gateway.yaml

Polecenie wyświetli te dane wyjściowe:

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

Następnie uruchom to polecenie, aby wdrożyć VirtualService:

kubectl apply -f aspnetcore-virtualservice.yaml

Polecenie wyświetli te dane wyjściowe:

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

Sprawdź, czy wszystko działa:

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

Gratulacje! Aplikacja obsługująca Istio została wdrożona. Następnie zobaczysz aplikację w użyciu.

9. Testowanie aplikacji

Możesz wreszcie zobaczyć aplikację w działaniu. Musisz uzyskać zewnętrzny adres IP i port bramy. Jest on wymieniony w sekcji EXTERNAL-IP:

kubectl get svc istio-ingressgateway -n istio-system

Wyeksportuj zewnętrzny adres IP i port do zmiennej 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

Użyj curl, aby przetestować aplikację. Usługa powinna odpowiedzieć kodem odpowiedzi 200:

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

Możesz też otworzyć przeglądarkę i przejść na stronę http://<gatewayurl>, aby wyświetlić aplikację:

f579a9baedc108a9.png

10. Gratulacje!

Właśnie udało Ci się wdrożyć prostą aplikację ASP.NET Core w Kubernetes działającym w Google Kubernetes Engine (GKE) i skonfigurować ją tak, aby była zarządzana przez Istio.

Możesz się zastanawiać, jakie korzyści przynosi Istio. Świetne pytanie. Jak dotąd zarządzanie tą aplikacją przez Istio nie przynosi żadnych korzyści. W drugiej części ćwiczenia przyjrzymy się bliżej funkcjom Istio, takim jak pomiary, śledzenie, dynamiczne zarządzanie ruchem, wizualizacja usług i wstrzykiwanie błędów.

Następne kroki

Licencja

To zadanie jest licencjonowane na podstawie ogólnej licencji Creative Commons Attribution 2.0.

11. Czyszczenie

Jeśli nie chcesz kontynuować drugiej części ćwiczenia, możesz usunąć aplikację i odinstalować Istio lub po prostu usunąć klaster Kubernetes.

Usuwanie aplikacji

Aby usunąć aplikację:

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

Aby potwierdzić, że aplikacja została usunięta:

kubectl get gateway 
kubectl get virtualservices 
kubectl get pods

Odinstalowywanie Istio

Aby usunąć Istio:

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

Aby potwierdzić, że Istio zostało usunięte:

kubectl get pods -n istio-system

Usuwanie klastra Kubernetes

gcloud container clusters delete hello-istio