Créer un pipeline CI/CD avec Azure Pipelines et Google Kubernetes Engine

Last reviewed 2022-11-29 UTC

Ce tutoriel explique comment utiliser Azure Pipelines, Google Kubernetes Engine (GKE) et Container Registry afin de créer un pipeline d'intégration/de déploiement continu (CI/CD) pour une application Web ASP.NET MVC. Pour les besoins de ce tutoriel, vous avez le choix entre deux exemples d'application :

  • Une application Web ASP.NET Core qui utilise .NET 6.0 et s'exécute sous Linux.
  • Une application Web ASP.NET MVC qui utilise .NET Framework 4 et s'exécute sous Windows.

Le pipeline CI/CD utilise deux clusters GKE distincts, un pour le développement et un pour la production, comme le montre le schéma suivant.

Schéma conceptuel du pipeline CI/CD montrant comment les développeurs et les utilisateurs finaux interagissent avec l'application

Au début du pipeline, les développeurs valident les modifications apportées à l'exemple de code. Cette action déclenche le pipeline pour créer une version et la déployer sur le cluster de développement. Un gestionnaire des versions peut ensuite promouvoir la version afin qu'elle soit déployée dans le cluster de production.

Ce tutoriel est destiné aux développeurs et aux ingénieurs DevOps. Nous partons du principe que vous disposez des connaissances de base sur Microsoft .NET, Azure Pipelines et GKE. Vous avez également besoin d'un accès administrateur à un compte Azure DevOps.

Objectifs

  • Connecter Google Container Registry à Azure Pipelines pour la publication d'images Docker
  • Préparer un exemple d'application .NET Core pour le déploiement dans GKE
  • S'authentifier de manière sécurisée auprès de GKE sans devoir utiliser l'ancienne authentification
  • Utiliser la gestion des versions Azure Pipelines pour orchestrer les déploiements GKE

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.

Consultez la page des tarifs d'Azure DevOps pour connaître les frais éventuels liés à l'utilisation d'Azure DevOps.

Avant de commencer

Il est généralement conseillé d'utiliser des projets distincts pour les charges de travail de développement et de production afin que les rôles et les autorisations Cloud IAM (Cloud Identity and Access Management) puissent être octroyés individuellement. Par souci de simplicité, ce tutoriel utilise un seul projet pour les deux clusters GKE, un pour le développement et un pour la production.

  1. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  2. Make sure that billing is enabled for your Google Cloud project.

  3. Assurez-vous de posséder un compte Azure DevOps et d'en avoir l'accès administrateur. Si vous ne possédez pas encore de compte Azure DevOps, vous pouvez vous inscrire sur la page d'accueil Azure DevOps.

Créer un projet Azure DevOps

Azure DevOps permet de gérer le code source, d'exécuter des builds et des tests, et d'orchestrer le déploiement sur GKE. Pour commencer, vous devez créer un projet dans votre compte Azure DevOps.

  1. Accédez à la page d'accueil Azure DevOps (https://dev.azure.com/YOUR_AZURE_DEVOPS_ACCOUNT_NAME).
  2. Cliquez sur New project (Nouveau projet).
  3. Indiquez un nom de projet, tel que CloudDemo.
  4. Définissez Visibility (Visibilité) sur Private (Mode privé), puis cliquez sur Create (Créer).
  5. Une fois le projet créé, dans le menu de gauche, cliquez sur Repos (Dépôt).
  6. Cliquez sur Importer pour dupliquer le dépôt dotnet-docs-samples à partir de GitHub, puis définissez les valeurs suivantes :
    • Type de dépôt : Git
    • Clone URL (URL du clone) : https://github.com/GoogleCloudPlatform/dotnet-docs-samples.git
  7. Cliquez sur Import (Importer).

    Une fois le processus d'importation terminé, le code source du dépôt dotnet-docs-samples s'affiche.

Connecter Azure Pipelines à Google Container Registry

Avant de pouvoir configurer l'intégration continue pour l'application CloudDemo, vous devez connecter Azure Pipelines à Container Registry. Cette connexion permet à Azure Pipelines de publier des images de conteneurs dans Container Registry.

Configurer un compte de service pour la publication d'images

Créez un compte de service Google Cloud dans votre projet :

  1. Ouvrez la console Google Cloud.

  2. In the Google Cloud console, activate Cloud Shell.

    Activate Cloud Shell

  3. Pour gagner du temps lors de la saisie de votre ID de projet et des options de la zone Compute Engine, définissez des valeurs de configuration par défaut en exécutant les commandes suivantes :

    gcloud config set project PROJECT_ID
    gcloud config set compute/zone us-central1-a
    

    Remplacez PROJECT_ID par l'ID de votre projet.

  4. Activez l'API Container Registry dans le projet :

    gcloud services enable containerregistry.googleapis.com
    
  5. Créez un compte de service utilisé par Azure Pipelines pour publier des images Docker :

    gcloud iam service-accounts create azure-pipelines-publisher \
        --display-name="Azure Pipelines Publisher"
    
  6. Attribuez le rôle IAM d'administrateur Storage (roles/storage.admin) au compte de service pour permettre à Azure Pipelines de transférer les données dans Container Registry :

    AZURE_PIPELINES_PUBLISHER=azure-pipelines-publisher@$GOOGLE_CLOUD_PROJECT.iam.gserviceaccount.com
    
    gcloud projects add-iam-policy-binding $GOOGLE_CLOUD_PROJECT \
        --member serviceAccount:$AZURE_PIPELINES_PUBLISHER \
        --role roles/storage.admin
    
  7. Générez une clé de compte de service :

    gcloud iam service-accounts keys create azure-pipelines-publisher.json \
        --iam-account $AZURE_PIPELINES_PUBLISHER
    
    tr -d '\n' < azure-pipelines-publisher.json > azure-pipelines-publisher-oneline.json
    
  8. Affichez le contenu du fichier de clé du compte de service :

    echo $(<azure-pipelines-publisher-oneline.json)
    

    La clé de compte de service est nécessaire pour l'une des étapes suivantes.

Créer une connexion de service pour Google Container Registry

Dans Azure Pipelines, créez une connexion de service pour Container Registry :

  1. Dans le menu Azure DevOps, sélectionnez Project settings (Paramètres du projet), puis Pipelines > Service connections (Connexions de service).
  2. Cliquez sur Créer une connexion de service.
  3. Dans la liste, sélectionnez Docker Registry (Registre Docker), puis cliquez sur Next (Suivant).
  4. Dans la boîte de dialogue, saisissez les valeurs des champs suivants :
    • Registry type (Type de registre) : Others (Autres)
    • Docker Registry (Registre Docker) : https://gcr.io/PROJECT_ID, en remplaçant PROJECT_ID par le nom de votre projet (par exemple, https://gcr.io/azure-pipelines-test-project-12345)
    • Docker ID (ID Docker) : _json_key
    • Password (Mot de passe) : collez le contenu de azure-pipelines-publisher-oneline.json.
    • Service connexion name (Nom de la connexion au service) : gcr-tutorial
  5. Cliquez sur Save (Enregistrer) pour créer la connexion.

Compiler en continu

Vous pouvez maintenant utiliser Azure Pipelines pour configurer l'intégration continue. Pour chaque commit envoyé dans le dépôt Git, Azure Pipelines compile le code et crée un package des artefacts de la compilation dans un conteneur Docker. Le conteneur est ensuite publié dans Container Registry.

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

.NET/Linux

#
# 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"]

.NET Framework/Windows

#
# 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/windows/servercore/iis:windowsservercore-ltsc2019
EXPOSE 80
SHELL ["powershell", "-command"]

#------------------------------------------------------------------------------
# Add LogMonitor so that IIS and Windows logs are emitted to STDOUT and can be
# picked up by Docker/Kubernetes.
#
# See https://github.com/microsoft/windows-container-tools/wiki/Authoring-a-Config-File
# for details.
#------------------------------------------------------------------------------

ADD https://github.com/microsoft/windows-container-tools/releases/download/v1.1/LogMonitor.exe LogMonitor/
ADD LogMonitorConfig.json LogMonitor/

#------------------------------------------------------------------------------
# Copy publishing artifacts to webroot.
#------------------------------------------------------------------------------

ADD CloudDemo.Mvc/bin/Release/PublishOutput/ c:/inetpub/wwwroot/

#------------------------------------------------------------------------------
# Configure IIS using the helper functions from deployment.ps1.
#------------------------------------------------------------------------------

ADD deployment.ps1 /
RUN . /deployment.ps1; \
	Install-Iis; \
	Register-WebApplication -AppName "CloudDemo"; \
	Remove-Item /deployment.ps1

#------------------------------------------------------------------------------
# Run IIS, wrapped by LogMonitor.
#------------------------------------------------------------------------------

ENTRYPOINT ["C:\\LogMonitor\\LogMonitor.exe", "C:\\ServiceMonitor.exe", "w3svc"]

Vous allez maintenant créer un pipeline qui utilise la syntaxe YAML :

  1. À l'aide de Visual Studio ou d'un client git de ligne de commande, clonez votre nouveau dépôt Git et récupérez la branche main.
  2. À la racine du dépôt, créez un fichier nommé azure-pipelines.yml.
  3. Copiez le code suivant dans le fichier :

    .NET/Linux

    resources:
    - repo: self
      fetchDepth: 1
    pool:
      vmImage: ubuntu-20.04
    trigger:
    - main
    variables:
      TargetFramework: 'net6.0'
      BuildConfiguration: 'Release'
      DockerImageName: 'PROJECT_ID/clouddemo'
    steps:
    - task: DotNetCoreCLI@2
      displayName: Publish
      inputs:
        projects: 'applications/clouddemo/netcore/CloudDemo.MvcCore.sln'
        publishWebProjects: false
        command: publish
        arguments: '--configuration $(BuildConfiguration) --framework=$(TargetFramework)'
        zipAfterPublish: false
        modifyOutputPath: false
    - task: CmdLine@1
      displayName: 'Lock image version in deployment.yaml'
      inputs:
        filename: /bin/bash
        arguments: '-c "awk ''{gsub(\"CLOUDDEMO_IMAGE\", \"gcr.io/$(DockerImageName):$(Build.BuildId)\", $0); print}'' applications/clouddemo/netcore/deployment.yaml > $(build.artifactstagingdirectory)/deployment.yaml"'
    - task: PublishBuildArtifacts@1
      displayName: 'Publish Artifact'
      inputs:
        PathtoPublish: '$(build.artifactstagingdirectory)'
    - task: Docker@2
      displayName: 'Login to Container Registry'
      inputs:
        command: login
        containerRegistry: 'gcr-tutorial'
    - task: Docker@2
      displayName: 'Build and push image'
      inputs:
        Dockerfile: 'applications/clouddemo/netcore/Dockerfile'
        command: buildAndPush
        repository: '$(DockerImageName)'
    

    .NET Framework/Windows

    resources:
    - repo: self
      fetchDepth: 1
    pool:
      vmImage: windows-2019     # Matches WINDOWS_LTSC in GKE
      demands:
      - msbuild
      - visualstudio
    trigger:
    - master
    variables:
      Solution: 'applications/clouddemo/net4/CloudDemo.Mvc.sln'
      BuildPlatform: 'Any CPU'
      BuildConfiguration: 'Release'
      DockerImageName: 'PROJECT_ID/clouddemo'
    steps:
    - task: NuGetCommand@2
      displayName: 'NuGet restore'
      inputs:
        restoreSolution: '$(Solution)'
    - task: VSBuild@1
      displayName: 'Build solution'
      inputs:
        solution: '$(Solution)'
        msbuildArgs: '/p:DeployOnBuild=true /p:PublishProfile=FolderProfile'
        platform: '$(BuildPlatform)'
        configuration: '$(BuildConfiguration)'
    - task: PowerShell@2
      displayName: 'Lock image version in deployment.yaml'
      inputs:
        targetType: 'inline'
        script: '(Get-Content applications\clouddemo\net4\deployment.yaml) -replace "CLOUDDEMO_IMAGE","gcr.io/$(DockerImageName):$(Build.BuildId)" | Out-File -Encoding ASCII $(build.artifactstagingdirectory)\deployment.yaml'
    - task: PublishBuildArtifacts@1
      displayName: 'Publish Artifact'
      inputs:
        PathtoPublish: '$(build.artifactstagingdirectory)'
    - task: Docker@2
      displayName: 'Login to Container Registry'
      inputs:
        command: login
        containerRegistry: 'gcr-tutorial'
    - task: Docker@2
      displayName: 'Build and push image'
      inputs:
        Dockerfile: 'applications/clouddemo/net4/Dockerfile'
        command: buildAndPush
        repository: '$(DockerImageName)'
    
    

    Remplacez PROJECT_ID par le nom de votre projet, puis enregistrez le fichier.

  4. Faites un commit de vos modifications et transférez-les vers Azure Pipelines.

    Visual Studio

    1. Ouvrez Team Explorer, puis cliquez sur l'icône Home (Accueil).
    2. Cliquez sur les Modifications.
    3. Saisissez un message de commit, tel que Add pipeline definition.
    4. Cliquez sur Valider tout et envoyer.

    Ligne de commande

    1. Préproduisez tous les fichiers modifiés :

      git add -A
      
    2. Faites un commit des modifications dans le dépôt local :

      git commit -m "Add pipeline definition"
      
    3. Transférez les modifications vers Azure DevOps :

      git push
      
  5. Dans le menu Azure DevOps, sélectionnez Pipelines, puis cliquez sur Create Pipeline (Créer un pipeline).

  6. Sélectionnez Azure Repos Git.

  7. Sélectionnez votre dépôt.

  8. Sur la page Examiner le pipeline YAML, cliquez sur Exécuter.

    Une nouvelle compilation est déclenchée. Celle-ci va prendre environ six minutes.

  9. Pour vérifier que l'image a été publiée dans Container Registry, sélectionnez votre projet dans la console Google Cloud, sélectionnez Container Registry > Images, puis cliquez sur clouddemo.

    Une seule image et le tag associé s'affichent. Le tag correspond à l'ID numérique du build exécuté dans Azure Pipelines.

Déployer en continu

Puisque Azure Pipelines crée automatiquement votre code et publie des images Docker pour chaque commit, vous pouvez désormais vous concentrer sur le déploiement.

Contrairement à d'autres systèmes d'intégration continue, Azure Pipelines fait la distinction entre la compilation et le déploiement, et fournit un ensemble spécialisé d'outils appelé "Release Management" (gestion des versions) pour toutes les tâches liées au déploiement.

La gestion des versions Azure Pipelines repose sur les concepts suivants :

  • Une version fait référence à un ensemble d'artefacts qui constituent une révision spécifique de votre application et qui résultent généralement d'un processus de compilation.
  • Le déploiement désigne le processus qui consiste à prendre une version et à la déployer dans un environnement spécifique.
  • Un déploiement exécute un ensemble de tâches pouvant être regroupées en jobs.
  • Les étapes vous permettent de segmenter votre pipeline et peuvent être utilisées pour orchestrer des déploiements dans plusieurs environnements, par exemple des environnements de développement et de test.

Le principal artefact produit par le processus de compilation de CloudDemo est l'image Docker. Toutefois, étant donné que l'image Docker est publiée dans Container Registry, elle ne relève pas de la portée d'Azure Pipelines. L'image n'est donc pas un bon indicateur de définition d'une version.

Pour déployer sur Kubernetes, vous avez également besoin d'un fichier manifeste qui ressemble à une nomenclature. Non seulement, le fichier manifeste définit les ressources que Kubernetes est censé créer et gérer, mais il spécifie également la version exacte de l'image Docker à utiliser. Le fichier manifeste Kubernetes est bien adapté pour servir d'artefact de définition de la version dans la gestion des versions Azure Pipelines.

Configurer le déploiement Kubernetes

Pour exécuter CloudDemo dans Kubernetes, vous avez besoin des ressources suivantes :

  • Un déploiement qui définit un pod unique pour exécuter l'image Docker produite par la compilation
  • Un service NodePort qui permet à un équilibreur de charge d'accéder au pod
  • Une entrée qui expose l'application à l'Internet public à l'aide d'un équilibreur de charge Cloud HTTP(S)

Le dépôt contient déjà le fichier manifeste Kubernetes suivant, qui définit ces ressources :

.NET/Linux

#
# 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

.NET Framework/Windows

#
# 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-net4
  annotations:
    cloud.google.com/neg: '{"ingress": false}' # Disable NEG

spec:
  ports:
  - port: 80
    targetPort: 80
    protocol: TCP
    name: http
  selector:
    app: clouddemo-net4
  type: NodePort

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

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: clouddemo-net4
spec:
  replicas: 2
  selector:
    matchLabels:
      app: clouddemo-net4
  template:
    metadata:
      labels:
        app: clouddemo-net4
    spec:
      nodeSelector:
        kubernetes.io/os: windows
      containers:
      - name: clouddemo-net4
        image: CLOUDDEMO_IMAGE
        ports:
          - containerPort: 80
        livenessProbe:      # Used by deployment controller
          httpGet:
            path: /health
            port: 80
          initialDelaySeconds: 120
          periodSeconds: 5
        readinessProbe:     # Used by Ingress/GCLB
          httpGet:
            path: /health
            port: 80
          initialDelaySeconds: 10
          periodSeconds: 5
        resources:
          limits:
            memory: 1024Mi
          requests:
            memory: 256Mi

Configurer les environnements de développement et de production

Avant de revenir à la gestion des versions Azure Pipelines, vous devez créer les clusters GKE.

Créer des clusters GKE

  1. Revenez à votre instance Cloud Shell.

  2. Activez l'API GKE pour votre projet :

    gcloud services enable container.googleapis.com
  3. Créez le cluster de développement à l'aide de la commande suivante. Notez que cela peut prendre quelques minutes :

    .NET/Linux

    gcloud container clusters create azure-pipelines-cicd-dev --enable-ip-alias
    

    .NET Framework/Windows

    gcloud container clusters create azure-pipelines-cicd-dev --enable-ip-alias
    
    gcloud container node-pools create azure-pipelines-cicd-dev-win \
        --cluster=azure-pipelines-cicd-dev \
        --image-type=WINDOWS_LTSC \
        --no-enable-autoupgrade \
        --machine-type=n1-standard-2
    
  4. Créez le cluster de production à l'aide de la commande suivante. Notez que cela peut prendre quelques minutes :

    .NET/Linux

    gcloud container clusters create azure-pipelines-cicd-prod --enable-ip-alias
    

    .NET Framework/Windows

    gcloud container clusters create azure-pipelines-cicd-prod --enable-ip-alias
    
    gcloud container node-pools create azure-pipelines-cicd-prod-win \
        --cluster=azure-pipelines-cicd-prod \
        --image-type=WINDOWS_LTSC \
        --no-enable-autoupgrade \
        --machine-type=n1-standard-2
    

Connecter Azure Pipelines au cluster de développement

Tout comme vous pouvez utiliser Azure Pipelines pour vous connecter à un registre Docker externe tel que Container Registry, Azure Pipelines prend en charge l'intégration de clusters Kubernetes externes.

Il est possible de s'authentifier auprès de Container Registry à l'aide d'un compte de service Google Cloud, mais Azure Pipelines ne permet pas d'employer ce type de compte pour l'authentification avec GKE. Vous devez à la place utiliser un compte de service Kubernetes.

Pour connecter Azure Pipelines à votre cluster de développement, vous devez donc d'abord créer un compte de service Kubernetes.

  1. Dans Cloud Shell, connectez-vous au cluster de développement :

    gcloud container clusters get-credentials azure-pipelines-cicd-dev
  2. Créez un compte de service Kubernetes pour Azure Pipelines :

    kubectl create serviceaccount azure-pipelines-deploy
  3. Créez un secret Kubernetes contenant des identifiants de jeton pour Azure Pipelines :

    kubectl create secret generic azure-pipelines-deploy-token --type=kubernetes.io/service-account-token --dry-run -o yaml \
      | kubectl annotate --local -o yaml -f - kubernetes.io/service-account.name=azure-pipelines-deploy \
      | kubectl apply -f -
    
  4. Attribuez le rôle cluster-admin au compte de service en créant une liaison de rôle de cluster :

    kubectl create clusterrolebinding azure-pipelines-deploy --clusterrole=cluster-admin --serviceaccount=default:azure-pipelines-deploy
  5. Déterminez l'adresse IP du cluster :

    gcloud container clusters describe azure-pipelines-cicd-dev --format=value\(endpoint\)
    

    Vous aurez besoin de cette adresse dans un instant.

  6. Dans le menu Azure DevOps, sélectionnez Project settings (Paramètres du projet), puis Pipelines > Service connections (Connexions de service).

  7. Cliquez sur New service connection (Nouvelle connexion de service).

  8. Sélectionnez Kubernetes, puis cliquez sur Next (Suivant).

  9. Configurez les paramètres suivants.

    • Authentication method (Méthode d'authentification) : Service account (Compte de service).
    • Server URL (URL du serveur) : https://PRIMARY_IP. Remplacez PRIMARY_IP par l'adresse IP que vous avez déterminée précédemment.
    • Secret : code secret Kubernetes que vous avez créé précédemment. Pour obtenir le secret, exécutez la commande suivante, copiez le secret, puis copiez-le sur la page Azure.
      kubectl get secret azure-pipelines-deploy-token -o yaml
    • Service connexion name (Nom de la connexion au service) : azure-pipelines-cicd-dev.
  10. Cliquez sur Enregistrer.

Connecter Azure Pipelines au cluster de production

Pour connecter Azure Pipelines à votre cluster de production, vous pouvez suivre la même approche.

  1. Dans Cloud Shell, connectez-vous au cluster de production :

    gcloud container clusters get-credentials azure-pipelines-cicd-prod
  2. Créez un compte de service Kubernetes pour Azure Pipelines :

    kubectl create serviceaccount azure-pipelines-deploy
  3. Attribuez le rôle cluster-admin au compte de service en créant une liaison de rôle de cluster :

    kubectl create clusterrolebinding azure-pipelines-deploy --clusterrole=cluster-admin --serviceaccount=default:azure-pipelines-deploy
  4. Déterminez l'adresse IP du cluster :

    gcloud container clusters describe azure-pipelines-cicd-prod --format=value\(endpoint\)
    

    Vous aurez besoin de cette adresse dans un instant.

  5. Dans le menu Azure DevOps, sélectionnez Project settings (Paramètres du projet), puis Pipelines > Service connections (Connexions de service).

  6. Cliquez sur New service connection (Nouvelle connexion de service).

  7. Sélectionnez Kubernetes, puis cliquez sur Next (Suivant).

  8. Configurez les paramètres suivants :

    • Authentication method (Méthode d'authentification) : Service account (Compte de service).
    • Server URL (URL du serveur) : https://PRIMARY_IP. Remplacez PRIMARY_IP par l'adresse IP que vous avez déterminée précédemment.
    • Secret: exécutez la commande suivante dans Cloud Shell et copiez le résultat:
      kubectl get secret $(kubectl get serviceaccounts azure-pipelines-deploy -o custom-columns=":secrets[0].name") -o yaml
    • Service connexion name (Nom de la connexion au service) : azure-pipelines-cicd-prod.
  9. Cliquez sur Enregistrer.

Configurer le pipeline de versions

Une fois l'infrastructure GKE configurée, vous revenez à Azure Pipelines pour automatiser le déploiement, ce qui inclut les éléments suivants :

  • Le déploiement dans l'environnement de développement
  • La demande d'approbation manuelle avant de lancer un déploiement dans l'environnement de production
  • Le déploiement dans l'environnement de production

Créer une définition de version

Dans un premier temps, créez une nouvelle définition de version.

  1. Dans le menu Azure DevOps, sélectionnez Pipelines > Releases (Versions).
  2. Cliquez sur New pipeline (Nouveau pipeline).
  3. Dans la liste des modèles, sélectionnez Empty job (Job vide).
  4. Lorsque vous êtes invité à donner un nom à l'étape, saisissez Development.
  5. En haut de l'écran, nommez la version CloudDemo-KubernetesEngine.
  6. Dans le schéma du pipeline, à côté d'Artifacts (Artefacts), cliquez sur Add (Ajouter).
  7. Sélectionnez Compilation et ajoutez les paramètres suivants :

    • Source type (Type de source) : Build
    • Source (build pipeline) (pipeline de compilation) : sélectionnez la définition de compilation (il ne devrait y avoir qu'une seule option)
    • Default version (Version par défaut) : Latest
    • Source alias (Alias source) : manifest
  8. Cliquez sur Ajouter.

  9. Dans la zone Artifact (Artefact), cliquez sur Continuous deployment trigger (Déclencheur de déploiement continu), c'est-à-dire l'icône représentant un éclair, pour ajouter un déclencheur de déploiement.

  10. Sous Continuous deployment trigger (Déclencheur de déploiement continu) définissez le commutateur sur Enabled (Activé).

  11. Cliquez sur Enregistrer.

  12. Saisissez un commentaire si vous le souhaitez, puis confirmez en cliquant sur OK.

    Le pipeline affiché ressemble à ce qui suit :

    Capture d'écran du pipeline mis à jour dans Azure Pipelines

Déployer sur le cluster de développement

Avec la définition de version créée, vous pouvez maintenant configurer le déploiement sur le cluster de développement GKE.

  1. Dans le menu, accédez à l'onglet Tasks (Tâches).
  2. Cliquez sur Job de l'agent, puis configurez les paramètres suivants :

    • Pool d'agents : Azure Pipelines
    • Spécification de l'agent : ubuntu-18.04
  3. À côté de Agent job (Job de l'agent), cliquez sur Add a task to agent job (Ajouter une tâche au job de l'agent)  pour ajouter une étape à la phase.

  4. Sélectionnez la tâche Deploy to Kubernetes (Déployer sur Kubernetes), puis cliquez sur Add (Ajouter).

  5. Cliquez sur la tâche nouvellement ajoutée et configurez les paramètres suivants :

    • Display name (Nom à afficher) : Deploy
    • Action : deploy
    • Kubernetes service connection (Connexion de service Kubernetes) : azure-pipelines-cicd-dev
    • Namespace (Espace de noms) : default
    • Strategy (Stratégie) : None (Aucune)
    • Manifests (Fichiers manifestes) : manifest/drop/deployment.yaml
  6. Cliquez sur Enregistrer.

  7. Saisissez un commentaire si vous le souhaitez, puis confirmez en cliquant sur OK.

Déployer sur le cluster de production

Pour finir, configurez le déploiement sur le cluster de production GKE.

  1. Dans le menu, accédez à l'onglet Pipeline.
  2. Dans la zone "Stages" (Étapes), sélectionnez Add (Ajouter) > New stage (Nouvelle étape).
  3. Dans la liste des modèles, sélectionnez Empty job (Job vide).
  4. Lorsque vous êtes invité à donner un nom à l'étape, saisissez Production.
  5. Cliquez sur l'icône en forme d'éclair de l'environnement récemment créé.
  6. Configurez les paramètres suivants :

    • Select trigger (Sélectionner le déclencheur) : After stage
    • Stages (Étapes) : Dev
    • Approbations de prédéploiement : (activé)
    • Approvers (Approbateurs) : sélectionnez votre propre nom d'utilisateur.

    Le pipeline ressemble désormais à ceci :

    Capture d'écran du pipeline mis à jour dans Azure Pipelines

  7. Accédez à l'onglet Tasks (Tâches).

  8. Maintenez la souris sur l'onglet Tasks (Tâches) et sélectionnez Tasks (Tâches) > Production.

  9. Cliquez sur Job de l'agent, puis configurez les paramètres suivants :

    • Pool d'agents : Azure Pipelines
    • Spécification de l'agent : ubuntu-18.04
  10. Cliquez sur Add a task to agent job (Ajouter une tâche au job de l'agent)  pour ajouter une étape à la phase.

  11. Sélectionnez la tâche Deploy to Kubernetes (Déployer sur Kubernetes), puis cliquez sur Add (Ajouter).

  12. Cliquez sur la tâche nouvellement ajoutée et configurez les paramètres suivants :

    • Display name (Nom à afficher) : Deploy
    • Action : deploy
    • Kubernetes service connection (Connexion de service Kubernetes) : azure-pipelines-cicd-prod
    • Namespace (Espace de noms) : default
    • Strategy (Stratégie) : None (Aucune)
    • Manifests (Fichiers manifestes) : manifest/drop/deployment.yaml
  13. Cliquez sur Enregistrer.

  14. Saisissez un commentaire si vous le souhaitez, puis confirmez en cliquant sur OK.

Exécuter le pipeline

Maintenant que vous avez configuré l'intégralité du pipeline, vous pouvez le tester en modifiant le code source :

  1. Sur votre ordinateur local, ouvrez le fichier Index.cshtml dans le dépôt Git que vous avez cloné précédemment :

    .NET/Linux

    Le fichier se trouve dans applications\clouddemo\netcore\CloudDemo.MvcCore\Views\Home\

    .NET Framework/Windows

    Le fichier se trouve dans applications\clouddemo\net4\CloudDemo.Mvc\Views\Home\

  2. À la ligne 26, remplacez la valeur de ViewBag.Title (Home Page) par This app runs on GKE.

  3. Faites un commit de vos modifications, puis transférez-les vers Azure Pipelines.

    Visual Studio

    1. Ouvrez Team Explorer, puis cliquez sur l'icône Home (Accueil).
    2. Cliquez sur les Modifications.
    3. Saisissez un message de commit, tel que Change site title.
    4. Cliquez sur Valider tout et envoyer.

    Ligne de commande

    1. Préproduisez tous les fichiers modifiés :

      git add -A
      
    2. Faites un commit des modifications dans le dépôt local :

      git commit -m "Change site title"
      
    3. Transférez les modifications à Azure Pipelines :

      git push
      
  4. Dans le menu Azure DevOps, sélectionnez Pipelines. Une compilation est déclenchée.

  5. Une fois la compilation terminée, sélectionnez Pipelines > Releases (Versions). Un processus de déploiement est lancé.

  6. Cliquez sur Release-1 pour ouvrir la page de détails et attendez que l'état de l'étape Development bascule sur Succeeded (Réussite).

  7. Dans la console Google Cloud, sélectionnez Kubernetes Engine > Services et entrées > Entrée.

  8. Recherchez le service d'entrée pour le cluster azure-pipelines-cicd-dev et attendez que son état bascule sur Ok. Cela peut prendre quelques minutes.

  9. Ouvrez le lien dans la colonne Interfaces de la même ligne. Vous risquez peut-être de constater une erreur au début, car un délai de quelques minutes est nécessaire pour que l'équilibreur de charge soit disponible. Lorsqu'il est prêt, vous pouvez constater que l'application CloudDemo a été déployée et qu'elle utilise le titre personnalisé.

  10. Dans Azure Pipelines, cliquez sur le bouton Approve (Approuver) situé sous l'étape Prod pour promouvoir le déploiement dans l'environnement de production.

    Si vous ne voyez pas ce bouton, vous devrez peut-être d'abord approuver ou rejeter une version précédente.

  11. Saisissez un commentaire si vous le souhaitez, puis cliquez sur Approve (Approuver) pour confirmer.

  12. Attendez que l'état de l'environnement Prod bascule sur Succeeded (Réussi). Vous devrez peut-être actualiser manuellement la page dans votre navigateur.

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

  14. Recherchez le service d'entrée pour le cluster azure-pipelines-cicd-prod et attendez que son état bascule sur OK. Cela peut prendre quelques minutes.

  15. Ouvrez le lien dans la colonne Interfaces de la même ligne. Là encore, il est possible que vous voyiez une erreur au début, car l'équilibreur de charge met quelques minutes à être disponible. Lorsqu'il est prêt, vous voyez à nouveau l'application CloudDemo avec le titre personnalisé, qui s'exécute cette fois-ci dans le cluster de production.

Effectuer un nettoyage

Pour éviter la facturation des ressources utilisées dans ce tutoriel, supprimez les entités que vous avez créées.

Supprimer le projet Azure Pipelines

Pour supprimer le projet Azure Pipelines, consultez la documentation sur Azure DevOps Services. La suppression du projet Azure Pipelines entraîne la perte de toutes les modifications du code source.

Supprimer le développement et les projets Google Cloud

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

Étapes suivantes