Déployer une application ASP.NET Core sur Google Kubernetes Engine avec Istio (Partie 1)

1. Présentation

ASP.NET Core est un nouveau framework Open Source et multiplate-forme qui permet de créer des applications innovantes basées sur le cloud et connectées à Internet, à l'aide du langage de programmation C#.

Kubernetes est un système Open Source qui automatise le déploiement, le scaling et la gestion des applications conteneurisées. Istio est un framework ouvert qui permet de connecter, de sécuriser, de gérer et de surveiller des services.

Dans cette première partie de l'atelier, vous allez déployer une application ASP.NET Core simple dans Kubernetes s'exécutant sur Google Kubernetes Engine (GKE) et la configurer pour qu'elle soit gérée par Istio.

Dans la deuxième partie de l'atelier, vous allez découvrir plus en détail les fonctionnalités d'Istio telles que les métriques, le traçage, la gestion dynamique du trafic, l'injection de pannes, etc.

Points abordés

  • Créer et empaqueter une application ASP.NET Core simple dans un conteneur Docker
  • Créer un cluster Kubernetes avec Google Kubernetes Engine (GKE)
  • Installer Istio sur un cluster Kubernetes sur GKE
  • Déployer votre application ASP.NET Core et configurer son trafic pour qu'il soit géré par Istio

Prérequis

Comment allez-vous utiliser ce tutoriel ?

Je vais le lire uniquement Je vais le lire et effectuer les exercices

Quel est votre niveau d'expérience avec Google Cloud Platform ?

<ph type="x-smartling-placeholder"></ph> Débutant Intermédiaire Expert
.

2. Préparation

Configuration de l'environnement au rythme de chacun

  1. Connectez-vous à la console Cloud, puis créez un projet ou réutilisez un projet existant. (Si vous ne possédez pas encore de compte Gmail ou Google Workspace, vous devez en créer un.)

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

Mémorisez l'ID du projet. Il s'agit d'un nom unique permettant de différencier chaque projet Google Cloud (le nom ci-dessus est déjà pris ; vous devez en trouver un autre). Il sera désigné par le nom PROJECT_ID tout au long de cet atelier de programmation.

  1. Vous devez ensuite activer la facturation dans Cloud Console pour pouvoir utiliser les ressources Google Cloud.

L'exécution de cet atelier de programmation est très peu coûteuse, voire gratuite. Veillez à suivre les instructions de la section "Nettoyer" qui indique comment désactiver les ressources afin d'éviter les frais une fois ce tutoriel terminé. Les nouveaux utilisateurs de Google Cloud peuvent participer au programme d'essai sans frais pour bénéficier d'un crédit de 300$.

Démarrer Cloud Shell

Bien que Google Cloud puisse être utilisé à distance depuis votre ordinateur portable, vous allez utiliser Google Cloud Shell dans cet atelier de programmation, un environnement de ligne de commande exécuté dans Google Cloud.

Activer Cloud Shell

  1. Dans Cloud Console, cliquez sur Activer Cloud Shell 4292cbf4971c9786.png.

bce75f34b2c53987.png

Si vous n'avez jamais démarré Cloud Shell auparavant, un écran intermédiaire (en dessous de la ligne de flottaison) vous explique de quoi il s'agit. Dans ce cas, cliquez sur Continuer (elle ne s'affichera plus). Voici à quoi il ressemble :

70f315d7b402b476.png

Le provisionnement et la connexion à Cloud Shell ne devraient pas prendre plus de quelques minutes.

fbe3a0674c982259.png

Cette machine virtuelle contient tous les outils de développement dont vous avez besoin. Elle comprend un répertoire d'accueil persistant de 5 Go et s'exécute sur Google Cloud, ce qui améliore nettement les performances du réseau et l'authentification. Vous pouvez réaliser une grande partie, voire la totalité, des activités de cet atelier dans un simple navigateur ou sur votre Chromebook.

Une fois connecté à Cloud Shell, vous êtes en principe authentifié et le projet est défini avec votre ID de projet.

  1. Exécutez la commande suivante dans Cloud Shell pour vérifier que vous êtes authentifié :
gcloud auth list

Résultat de la commande

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

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Exécutez la commande suivante dans Cloud Shell pour vérifier que la commande gcloud connaît votre projet:
gcloud config list project

Résultat de la commande

[core]
project = <PROJECT_ID>

Si vous obtenez un résultat différent, exécutez cette commande :

gcloud config set project <PROJECT_ID>

Résultat de la commande

Updated property [core/project].

3. Créer une application ASP.NET Core dans Cloud Shell

Dans l'invite Cloud Shell, vous pouvez vérifier que l'outil de ligne de commande dotnet est déjà installé en vérifiant sa version. La version de l'outil de ligne de commande dotnet installé devrait s'afficher:

dotnet --version

Ensuite, créez une application Web squelette ASP.NET Core.

dotnet new mvc -o HelloWorldAspNetCore

Cette action créera un projet et restaurera ses dépendances. Un message de ce type doit s'afficher :

Restore completed in 11.44 sec for HelloWorldAspNetCore.csproj.

Restore succeeded.

4. Exécuter l'application ASP.NET Core

Nous sommes presque prêts à exécuter notre application. Accédez au dossier de l'application.

cd HelloWorldAspNetCore

Enfin, exécutez l'application.

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

L'application commence à écouter sur le port 8080.

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

Pour vérifier que l'application est bien en cours d'exécution, cliquez sur le bouton "Aperçu sur le Web" en haut à droite, puis sélectionnez "Prévisualiser sur le port 8080".

Capture.PNG

La page Web ASP.NET Core par défaut s'affiche:

f579a9baedc108a9.png

Après avoir vérifié que l'application est en cours d'exécution, appuyez sur Ctrl+C pour la fermer.

5. Empaqueter l'application ASP.NET Core dans un conteneur Docker

Préparez ensuite votre application pour qu'elle s'exécute en tant que conteneur. La première étape consiste à définir le conteneur et son contenu.

Dans le répertoire de base de l'application, créez un Dockerfile pour définir l'image Docker.

touch Dockerfile

Ajoutez le code suivant à Dockerfile à l'aide de l'éditeur de votre choix (vim, nano,emacs ou l'éditeur de code de 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"]

Une des configurations importantes du fichier Dockerfile est le port 8080 sur lequel l'application écoute le trafic entrant. Pour ce faire, définissez la variable d'environnement ASPNETCORE_URLS, que les applications ASP.NET Core utilisent pour déterminer le port à écouter.

Enregistrez ce Dockerfile. Créons maintenant l'image:

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

Une fois l'opération terminée (le téléchargement et l'extraction de tous les éléments peuvent prendre un certain temps), vous pouvez voir que l'image est créée et enregistrée en local:

docker images

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

Testez l'image localement à l'aide de la commande suivante, qui exécutera un conteneur Docker localement sur le port 8080 à partir de l'image de conteneur que vous venez de créer:

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

Profitez également de la fonctionnalité d'aperçu sur le Web de Cloud Shell :

Capture d&#39;écran du 03/11/2015 17:20:22.png

La page Web ASP.NET Core par défaut doit s'afficher dans un nouvel onglet.

f579a9baedc108a9.png

Une fois que vous avez vérifié que l'application fonctionne correctement localement dans un conteneur Docker, vous pouvez arrêter le conteneur en cours d'exécution à l'aide de la commande Ctrl-> C.

Maintenant que l'image fonctionne comme prévu, transférez-la vers Google Container Registry, un dépôt privé pour vos images Docker accessible depuis tous les projets Google Cloud (mais également en dehors de Google Cloud Platform).

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

Si tout se déroule comme prévu, l'image de conteneur doit s'afficher dans la section Container Registry au bout de quelques instants. À ce stade, vous disposez désormais d'une image Docker disponible à l'échelle du projet, que Kubernetes peut consulter et orchestrer, comme vous le verrez dans quelques minutes.

73558f3a54ce1c0c.png

Si vous êtes curieux, vous pouvez parcourir les images de conteneurs stockées dans Google Cloud Storage en cliquant sur ce lien: https://console.cloud.google.com/storage/browser/ (le lien complet obtenu doit se présenter sous la forme suivante: https://console.cloud.google.com/project/PROJECT_ID/storage/browser/).

6. Créer un cluster Kubernetes/GKE avec Istio

Tout d'abord, assurez-vous que l'API Kubernetes Engine est activée:

gcloud services enable container.googleapis.com

Créez un cluster Kubernetes. Si vous le souhaitez, vous pouvez choisir une région proche de vous:

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

Attendez quelques instants pendant que le système configure votre cluster. Il sera visible dans la section "Kubernetes Engine" de la console Google Cloud Platform.

e46fd9c6ee82bcc4.png

Pour cet atelier de programmation, nous allons télécharger et installer Istio à partir d'istio.io. Il existe d'autres options d'installation, y compris le module complémentaire Istio pour GKE et Anthos Service Mesh. Les étapes suivantes de l'application fonctionneront sur n'importe quelle installation d'Istio.

Commençons par télécharger le client et les exemples Istio. La page des versions d'Istio propose de télécharger des artefacts pour plusieurs systèmes d'exploitation. Dans notre cas, nous pouvons utiliser une commande pratique pour télécharger et extraire la dernière version de notre plateforme actuelle:

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

Le script vous indique la version d'Istio qui a été téléchargée:

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

Le répertoire d'installation contient des exemples d'applications et le binaire du client istioctl. Accédez à ce répertoire:

cd istio-1.8.1

Copiez et collez la commande fournie pour ajouter le répertoire bin à votre PATH, afin de pouvoir utiliser istioctl:

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

Vérifiez que istioctl est disponible en vérifiant que votre cluster est prêt pour Istio:

istioctl x precheck

Le message Install Pre-Check passed! The cluster is ready for Istio installation. doit s'afficher

Installez Istio avec le profil de démonstration:

istioctl install --set profile=demo

Istio est maintenant installé dans votre cluster.

Injection side-car automatique

Pour commencer à utiliser Istio, vous n'avez aucune modification à apporter à l'application. Lorsque vous configurez et exécutez les services, les side-cars Envoy sont automatiquement injectés dans chaque pod du service.

Pour que cela fonctionne, vous devez activer l'injection side-car pour l'espace de noms ("default") que vous utilisez pour vos microservices. Pour ce faire, appliquez une étiquette:

kubectl label namespace default istio-injection=enabled

Pour vérifier que le libellé a bien été appliqué, exécutez la commande suivante:

kubectl get namespace -L istio-injection

Le résultat confirme que l'injection side-car est activée pour l'espace de noms par défaut:

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

7. Vérifiez l'installation

Istio est fourni avec trois services: le plan de contrôle istiod, et les passerelles d'entrée et de sortie (que vous pouvez considérer comme des "proxys side-car pour le reste d'Internet") , nommés respectivement istio-ingressgateway et istio-egressgateway.

kubectl get svc -n istio-system

Vous devez normalement obtenir le résultat suivant :

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>

La passerelle d'entrée est de type LoadBalancer. Elle est donc accessible depuis Internet. les autres doivent être accessibles uniquement depuis le cluster.

Vérifiez ensuite que les pods Kubernetes correspondants sont déployés et que tous les conteneurs sont opérationnels:

kubectl get pods -n istio-system

Lorsque tous les pods sont en cours d'exécution, vous pouvez continuer.

NAME                                    READY   STATUS
istio-egressgateway-674988f895-m6tk4    1/1     Running
istio-ingressgateway-6996f7dcc8-7lvm2   1/1     Running
istiod-6bf5fc8b64-j79hj                 1/1     Running
  • istiod: plan de contrôle Istio Gère la configuration et la programmation des proxys side-car, la détection de services, la distribution des certificats et l'injection side-car
  • ingress gateway: gère les requêtes entrantes provenant de l'extérieur de votre cluster.
  • egress gateway: gère les requêtes sortantes vers les points de terminaison en dehors de votre cluster.

8. Déployer l'application

Maintenant que vous avez vérifié qu'Istio est installé et en cours d'exécution, vous pouvez déployer l'application ASP.NET Core.

Déploiement et service

Commencez par créer un fichier aspnetcore.yaml à l'aide de l'éditeur de votre choix (vim, nano,emacs ou l'éditeur de code de Cloud Shell), puis définissez le déploiement et le service Kubernetes pour l'application:

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

Ce fichier contient des déploiements et des services standards permettant de déployer l'application. Il ne contient aucun élément spécifique à Istio.

Déployez les services sur l'espace de noms par défaut à l'aide de kubectl:

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

Vérifiez que les pods sont en cours d'exécution:

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

Gateway et VirtualService

Pour autoriser le trafic entrant à atteindre le réseau maillé, vous devez créer une passerelle et un VirtualService.

Une passerelle configure un équilibreur de charge pour le trafic HTTP/TCP, généralement opérant à la périphérie du réseau maillé afin d'activer le trafic entrant pour une application. Un VirtualService définit les règles qui contrôlent la manière dont les requêtes d'un service sont acheminées au sein d'un maillage de services Istio.

Créez un fichier aspnetcore-gateway.yaml pour définir la passerelle:

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

Créez un fichier aspnetcore-virtualservice.yaml pour définir le VirtualService:

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

Exécutez la commande kubectl pour déployer la passerelle avec:

kubectl apply -f aspnetcore-gateway.yaml

La commande produit le résultat suivant :

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

Exécutez ensuite la commande suivante pour déployer le service virtuel:

kubectl apply -f aspnetcore-virtualservice.yaml

La commande produit le résultat suivant :

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

Vérifiez que tout est en cours d'exécution:

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

Félicitations ! Vous venez de déployer une application compatible avec Istio. L'application est ensuite utilisée.

9. Tester l'application

Vous pouvez enfin voir l'application en action. Vous devez obtenir l'adresse IP externe et le port de la passerelle. Il est répertorié sous EXTERNAL-IP:

kubectl get svc istio-ingressgateway -n istio-system

Exportez l'adresse IP externe et le port vers une variable 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

Utilisez curl pour tester l'application. Le service doit répondre avec le code de réponse 200:

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

Vous pouvez également ouvrir le navigateur et accéder à http://<gatewayurl> pour afficher l'application:

f579a9baedc108a9.png

10. Félicitations !

Vous venez de déployer une application ASP.NET Core simple dans Kubernetes s'exécutant sur Google Kubernetes Engine (GKE) et de la configurer pour qu'elle soit gérée par Istio.

Vous vous demandez peut-être quel est l'avantage d'Istio. C'est une excellente question. Jusqu'à présent, la gestion de cette application par Istio ne présente aucun avantage. Dans la deuxième partie de l'atelier, nous explorerons plus en détail les fonctionnalités d'Istio, telles que les métriques, le traçage, la gestion dynamique du trafic, la visualisation des services et l'injection de pannes.

Étapes suivantes

Licence

Ce document est publié sous une licence Creative Commons Attribution 2.0 Generic.

11. Nettoyage

Si vous ne passez pas à la deuxième partie de l'atelier, vous pouvez supprimer l'application et désinstaller Istio, ou simplement supprimer le cluster Kubernetes.

Supprimer l'application

Pour supprimer l'application, procédez comme suit :

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

Pour vérifier que l'application a disparu:

kubectl get gateway 
kubectl get virtualservices 
kubectl get pods

Désinstaller Istio

Pour supprimer Istio:

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

Pour vérifier qu'Istio a bien été supprimé:

kubectl get pods -n istio-system

Supprimer un cluster Kubernetes

gcloud container clusters delete hello-istio