Déployer une application .NET sur Google Kubernetes Engine à l'aide d'un workflow d'actions GitHub


Ce tutoriel explique comment utiliser un workflow GitHub Actions pour déployer une application Web ASP.NET Model-View-Controller (MVC) utilisant .NET sur Google Kubernetes Engine (GKE).

Ce tutoriel est destiné aux développeurs et aux ingénieurs DevOps qui connaissent les bases de Microsoft .NET, GitHub Actions et GKE. Vous avez également besoin d'un compte GitHub pour exécuter ce tutoriel.

Objectifs

Déployez une application Web ASP.NET Core utilisant .NET 6.0 sous Linux sur Google Kubernetes Engine.

Le schéma suivant illustre le workflow GitHub permettant de déployer une application Web ASP.NET MVC sur Google Kubernetes Engine (GKE).

Schéma conceptuel du workflow d'actions GitHub

Ce tutoriel vous explique comment effectuer les tâches suivantes, en vue d'atteindre votre objectif :

  • Créer un dépôt GitHub
  • Configurer l'authentification
  • Déployer un cluster GKE et un dépôt Artifact Registry
  • Créer un workflow d'actions GitHub

Coûts

Dans ce document, vous utilisez les composants facturables suivants de Google Cloud :

Obtenez une estimation des coûts en fonction de votre utilisation prévue à l'aide du simulateur de coût. Les nouveaux utilisateurs de Google Cloud peuvent bénéficier d'un essai gratuit.

Une fois que vous avez terminé les tâches décrites dans ce document, vous pouvez éviter de continuer à payer des frais en supprimant les ressources que vous avez créées. Pour en savoir plus, consultez la section Effectuer un nettoyage.

Avant de commencer

  1. Connectez-vous à votre compte Google Cloud. Si vous débutez sur Google Cloud, créez un compte pour évaluer les performances de nos produits en conditions réelles. Les nouveaux clients bénéficient également de 300 $ de crédits gratuits pour exécuter, tester et déployer des charges de travail.
  2. Dans Google Cloud Console, sur la page de sélection du projet, sélectionnez ou créez un projet Google Cloud.

    Accéder au sélecteur de projet

  3. Vérifiez que la facturation est activée pour votre projet Google Cloud.

  4. Activer les API Artifact Registry and Google Kubernetes Engine.

    Activer les API

  5. Dans Google Cloud Console, sur la page de sélection du projet, sélectionnez ou créez un projet Google Cloud.

    Accéder au sélecteur de projet

  6. Vérifiez que la facturation est activée pour votre projet Google Cloud.

  7. Activer les API Artifact Registry and Google Kubernetes Engine.

    Activer les API

Créer un dépôt GitHub

Créez une copie du dépôt dotnet-docs-samples dans votre compte GitHub. Cette étape est nécessaire, car le processus de compilation s'effectue avec GitHub Actions.

  1. Accédez au dépôt GitHub dotnet-docs-samples.
  2. Cliquez sur Fork (Dupliquer).
  3. Sur la page Créer une copie, définissez les éléments suivants:

    • Propriétaire : votre compte GitHub
    • Nom du dépôt : dotnet-docs-samples
  4. Cliquez sur Créer une copie.

Configurer l'authentification

Préparez votre projet Google Cloud afin que les actions GitHub puissent s'authentifier et accéder aux ressources du projet Google Cloud.

Créer un pool et un fournisseur de fédération d'identité de charge de travail

Pour autoriser GitHub Actions à authentifier Google Cloud et à le déployer sur GKE, utilisez la fédération d'identité de charge de travail. La fédération d'identité de charge de travail vous évite d'avoir à stocker et gérer des clés de compte de service pour votre charge de travail GitHub Actions.

La fédération d'identité de charge de travail nécessite un pool d'identités de charge de travail et un fournisseur. Nous vous recommandons d'utiliser un projet dédié pour gérer les pools d'identités de charge de travail et les fournisseurs. Dans ce tutoriel, par souci de simplicité, créez le pool et le fournisseur dans le même projet que votre cluster GKE:

  1. Ouvrez la console Google Cloud.

  2. Dans la console Google Cloud, activez Cloud Shell.

    Activer Cloud Shell

    En bas de la fenêtre de la console Google Cloud, une session Cloud Shell démarre et affiche une invite de ligne de commande. Cloud Shell est un environnement shell dans lequel Google Cloud CLI est déjà installé, et dans lequel des valeurs sont déjà définies pour votre projet actuel. L'initialisation de la session peut prendre quelques secondes.

  3. Créez un pool d'identités de charge de travail :

    gcloud iam workload-identity-pools create github-actions \
        --location="global" \
        --description="GitHub Actions tutorial" \
        --display-name="GitHub Actions"
    
  4. Ajoutez les actions GitHub en tant que fournisseur de pool d'identités de charge de travail:

    gcloud iam workload-identity-pools providers create-oidc github-actions-oidc \
        --location="global" \
        --workload-identity-pool=github-actions \
        --issuer-uri="https://token.actions.githubusercontent.com/" \
        --attribute-mapping="google.subject=assertion.sub"
    

Créer un compte de service

  1. Dans Cloud Shell, créez un compte de service que les actions GitHub peuvent utiliser pour publier des images Docker et les déployer sur GKE:

    SERVICE_ACCOUNT=$(gcloud iam service-accounts create github-actions-workflow \
      --display-name "GitHub Actions workflow" \
      --format "value(email)")
    
  2. Attribuez le rôle de rédacteur Artifact Registry (roles/artifactregistry.writer) au compte de service pour autoriser le transfert des actions GitHub vers Artifact Registry:

    gcloud projects add-iam-policy-binding $(gcloud config get-value core/project) \
      --member serviceAccount:$SERVICE_ACCOUNT \
      --role roles/artifactregistry.writer
    
  3. Attribuez le rôle de développeur Google Kubernetes Engine (roles/container.developer) au compte de service pour autoriser le transfert des actions GitHub vers Artifact Registry:

    gcloud projects add-iam-policy-binding $(gcloud config get-value core/project) \
      --member serviceAccount:$SERVICE_ACCOUNT \
      --role roles/container.developer
    

Autoriser le workflow GitHub Actions à utiliser le compte de service

Autorisez le workflow GitHub Actions à usurper l'identité et à utiliser le compte de service:

  1. Initialisez une variable d'environnement contenant l'objet utilisé par le workflow d'actions GitHub. Un objet est semblable à un nom d'utilisateur qui identifie de manière unique le dépôt et la branche GitHub:

    SUBJECT=repo:OWNER/dotnet-docs-samples:ref:refs/heads/main
    

    Remplacez OWNER par votre nom d'utilisateur GitHub.

  2. Autorisez l'objet à emprunter l'identité du compte de service:

    PROJECT_NUMBER=$(gcloud projects describe $(gcloud config get-value core/project) --format='value(projectNumber)')
    
    gcloud iam service-accounts add-iam-policy-binding $SERVICE_ACCOUNT \
      --role=roles/iam.workloadIdentityUser \
      --member="principal://iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/github-actions/subject/$SUBJECT"
    

Déployer un cluster GKE et un dépôt Artifact Registry

  1. Créez un dépôt pour les images Docker:

    gcloud artifacts repositories create clouddemo \
      --repository-format=docker \
      --location=us-central1
    
  2. Autorisez le compte de service Compute Engine par défaut à accéder au dépôt:

    gcloud projects add-iam-policy-binding $(gcloud config get-value core/project) \
      --member=serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com \
      --role=roles/artifactregistry.reader
    
  3. Créez le cluster :

    gcloud container clusters create clouddemo-linux \
      --enable-ip-alias \
      --zone us-central1-a
    

    Cette commande peut prendre plusieurs minutes.

  4. Obtenez le nom et le numéro de projet du cluster:

    echo "Project ID: $(gcloud config get-value core/project)"
    echo "Project Number: $(gcloud projects describe $(gcloud config get-value core/project) --format=value\(projectNumber\))"
    

    Vous aurez besoin de ces valeurs ultérieurement.

Créer un workflow d'actions GitHub

Les actions GitHub peuvent désormais être configurées pour l'intégration continue. Pour chaque commit envoyé dans le dépôt Git, un workflow d'actions GitHub compile le code et empaquette les artefacts de compilation dans un conteneur Docker. Le conteneur est ensuite publié dans Artifact Registry.

Le dépôt contient déjà le fichier Dockerfile suivant :

#
# Copyright 2020 Google LLC
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#

FROM mcr.microsoft.com/dotnet/aspnet:6.0
EXPOSE 8080

#------------------------------------------------------------------------------
# Copy publishing artifacts.
#------------------------------------------------------------------------------

WORKDIR /app
COPY CloudDemo.MvcCore/bin/Release/net6.0/publish/ /app/

ENV ASPNETCORE_URLS=http://0.0.0.0:8080

#------------------------------------------------------------------------------
# Run application in Kestrel.
#------------------------------------------------------------------------------

ENTRYPOINT ["dotnet", "CloudDemo.MvcCore.dll"]

Le dépôt contient également un fichier manifeste Kubernetes:

#
# Copyright 2020 Google LLC
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
#

apiVersion: v1
kind: Service
metadata:
  name: clouddemo-netcore
spec:
  ports:
  - port: 80
    targetPort: 8080
    protocol: TCP
    name: http
  selector:
    app: clouddemo-netcore
  type: NodePort

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: clouddemo-netcore
spec:
  defaultBackend:
    service:
      name: clouddemo-netcore
      port:
        number: 80

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: clouddemo-netcore
spec:
  replicas: 2
  selector:
    matchLabels:
      app: clouddemo-netcore
  template:
    metadata:
      labels:
        app: clouddemo-netcore
    spec:
      containers:
      - name: clouddemo-netcore
        image: CLOUDDEMO_IMAGE
        ports:
          - containerPort: 8080
        livenessProbe:      # Used by deployment controller
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 5
        readinessProbe:     # Used by Ingress/GCLB
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 3
          periodSeconds: 5
        resources:
          limits:
            memory: 1024Mi
          requests:
            memory: 256Mi

Créez un workflow d'actions GitHub qui effectue les opérations suivantes:

  • Authentifiez-vous auprès de Google Cloud à l'aide de la fédération d'identité de charge de travail et du compte de service que vous avez créé précédemment.
  • Créer une image Docker et la déployer dans Artifact Registry
  • déployer l'image Docker sur GKE ;

Pour créer le workflow d'actions GitHub, procédez comme suit:

  1. Sur GitHub, accédez à votre fork du dépôt dotnet-docs-samples.
  2. Cliquez sur Ajouter un fichier > Créer un fichier.
  3. Dans le champ de texte Nom du fichier, saisissez le nom suivant:

    .github/workflows/deploy-gke.yaml
    
  4. Copiez le code suivant dans le fichier :

    name: Build and Deploy to GKE
    
    on:
      push:
        branches:
          - main
    
    env:
      PROJECT_ID: PROJECT_ID
      PROJECT_NUMBER: PROJECT_NUMBER
    
      CLUSTER: clouddemo-linux
      CLUSTER_ZONE: us-central1-a
    
      REPOSITORY: clouddemo
      REPOSITORY_REGION: us-central1
    
      IMAGE: clouddemo
    
    jobs:
      build:
        runs-on: ubuntu-latest
        permissions:
          id-token: write
          contents: read
    
        steps:
        - name: Checkout
          uses: actions/checkout@v3
    
        #
        # Authenticate to Google Cloud using workload identity federation
        #
        - id: 'auth'
          name: 'Obtain access token by using workload identity federation'
          uses: 'google-github-actions/auth@v0'
          with:
            create_credentials_file: true
            token_format: access_token
            workload_identity_provider: projects/${{ env.PROJECT_NUMBER }}/locations/global/workloadIdentityPools/github-actions/providers/github-actions-oidc
            service_account: github-actions-workflow@${{ env.PROJECT_ID }}.iam.gserviceaccount.com
    
        - name: Connect to Artifact Registry
          run: |-
            echo ${{ steps.auth.outputs.access_token }} | docker login -u oauth2accesstoken --password-stdin https://${{ env.REPOSITORY_REGION }}-docker.pkg.dev
    
        - name: Connect to GKE
          uses: google-github-actions/get-gke-credentials@v0
          with:
            cluster_name: ${{ env.CLUSTER }}
            location: ${{ env.CLUSTER_ZONE }}
    
        #
        # Build the .NET code
        #
        - name: Build solution
          run: |-
            dotnet publish applications/clouddemo/netcore/CloudDemo.MvcCore.sln \
                --configuration Release \
                --framework net6.0
    
        #
        # Build the Docker image and push it to Artifact Registry
        #
        - name: Create image tag
          run: echo "IMAGE_TAG=${{ env.REPOSITORY_REGION }}-docker.pkg.dev/${{ env.PROJECT_ID }}/${{ env.REPOSITORY }}/${{ env.IMAGE }}:$GITHUB_SHA" >> $GITHUB_ENV
    
        - name: Lock image version in deployment.yaml
          run: sed -i 's|CLOUDDEMO_IMAGE|${{ env.IMAGE_TAG }}|g' applications/clouddemo/netcore/deployment.yaml
    
        - name: Build Docker image
          run: docker build --tag "${{ env.IMAGE_TAG }}" applications/clouddemo/netcore
    
        - name: Publish Docker image to Google Artifact Registry
          run: docker push "${{ env.IMAGE_TAG }}"
    
        #
        # Deploy to GKE
        #
        - name: Deploy to GKE
          run: kubectl apply -f applications/clouddemo/netcore/deployment.yaml
        

    Remplacez les valeurs suivantes :

    • PROJECT_ID: l'ID du projet qui contient le cluster GKE.
    • PROJECT_NUMBER: numéro du projet contenant le cluster GKE.
  5. Dans la section Valider le nouveau fichier, saisissez un message de commit, par exemple Add workflow, puis cliquez sur Valider le nouveau fichier.

  6. Dans le menu, cliquez sur Actions et attendez la fin du workflow.

    Le workflow peut prendre plusieurs minutes.

  7. Dans la console Google Cloud, actualisez la page Services et entrées.

    Accéder à la page Services et entrées

  8. Accédez à l'onglet Entrée.

  9. Recherchez le service d'Ingress pour le cluster clouddemo et attendez que son état bascule sur OK. Cela peut prendre quelques minutes.

  10. Ouvrez le lien dans la colonne Interfaces de la même ligne. L'équilibreur de charge met quelques minutes à devenir disponible. Il est donc possible que l'application Cloud Demo ne se charge pas immédiatement. Lorsque l'équilibreur de charge est prêt, l'application CloudDemo s'affiche avec le titre personnalisé, cette fois-ci dans le cluster de production.

Effectuer un nettoyage

Une fois le tutoriel terminé, vous pouvez procéder au nettoyage des ressources que vous avez créées afin qu'elles ne soient plus comptabilisées dans votre quota et qu'elles ne vous soient plus facturées. Dans les sections suivantes, nous allons voir comment supprimer ou désactiver ces ressources.

Supprimer le dépôt GitHub

Pour supprimer le dépôt GitHub, consultez la section Supprimer un dépôt. La suppression du dépôt entraîne la perte de toutes les modifications du code source.

Supprimer le projet

Le moyen le plus simple d’éliminer la facturation consiste à supprimer le projet que vous avez créé pour ce tutoriel.

    Supprimez un projet Google Cloud :

    gcloud projects delete PROJECT_ID

Étapes suivantes