0
votes

Comment déployer plusieurs micro-services à l'aide de pipelines DevOps

J'essaie de déployer deux applications .Net Core sur Azure Kubernetes à l'aide de DevOps. Le pipeline par défaut construit et déploie uniquement le premier projet que j'ai ajouté.

J'ai créé une solution unique avec deux dossiers de solution, chacun contenant un projet .Net Core. J'ai ajouté la prise en charge de l'orchestration aux deux projets et créé un pipeline Azure à l'aide de «l'assistant» dans DevOps. J'ai ajouté le projet secondaire après avoir déployé avec succès le premier projet. Je pensais que le problème existait parce que la connexion du service de registre Docker ne contenait pas le nouveau projet.Je l'ai donc supprimé et recréé la connexion, mais elle ne déploie toujours que le premier projet. J'utilise Azure Git.

Le fichier azure-pipeline.yaml est assez standard. J'ai accepté la valeur par défaut créée lors de la création du pipeline. Voici mon étape buildAndPush.

stages:
- stage: Build
  displayName: Build stage
  jobs:  
  - job: Build
    displayName: Build job
    pool:
      vmImage: $(vmImageName)
    steps:
    - task: Docker@2
      displayName: Build and push an image to container registry
      inputs:
        command: buildAndPush
        repository: $(imageRepository)
        dockerfile: $(dockerfilePath)
        containerRegistry: $(dockerRegistryServiceConnection)
        tags: |
          $(tag)
    - task: PublishPipelineArtifact@0
      inputs:
        artifactName: 'manifests'
        targetPath: 'manifests'

Comment puis-je le faire construire et déployer l'autre projet restant?


0 commentaires

4 Réponses :


0
votes

Vous avez besoin d'un pipeline de build différent pour chaque solution. ma suggestion est de mettre les deux projets sous une seule solution. Vous pouvez avoir n'importe quel type de projet différent sous la même solution.


1 commentaires

Merci Daniel - J'ai les deux projets dans une seule solution. Lorsque j'essaie de créer plusieurs pipelines, DevOps suppose que c'est le même pipeline après avoir sélectionné le même projet à partir d'Azure Git. Cela me permet cependant de créer un nouveau pipeline; il partage le même azure-pipelines.yaml que celui utilisé dans tous les autres. Pendant que je tapais ceci, j'ai pensé à quelque chose - voir ma propre réponse sous peu ...



0
votes

Vous devez supprimer le fichier azure-pipelines.yml de votre référentiel si vous souhaitez créer un nouveau pipeline. Cela vous permettra de parcourir à nouveau le Devops «Deploy to Azure Kubernetes Service» depuis le début. Cela devrait vous donner la possibilité d'ajouter des projets supplémentaires à la version.


1 commentaires

Cela vous permet de recréer le pipeline, en créant de nouvelles connexions de service lorsque cela est nécessaire, cependant; il ne vous permet toujours pas de spécifier les projets à créer et à déployer. Il crée un nouveau azure-pipelines.yml dans votre branche principale (sauf indication contraire), qui sera partagé par tous les pipelines suivants.



0
votes

J'ai réussi à déployer deux projets en utilisant un seul fichier azure-pipelines.yml; cependant, je suis presque certain que c'est incorrect. J'ai dupliqué l'étape de construction pour chaque projet et j'ai également spécifié deux fichiers Docker séparés. De plus, j'ai ajouté un fichier deployment.yml et service.yml pour chaque projet. Voir mon azure-pipelines.yml ci-dessous. Tout conseil sur la manière de procéder correctement sera apprécié.

# Deploy to Azure Kubernetes Service
# Build and push image to Azure Container Registry; Deploy to Azure Kubernetes Service
# https://docs.microsoft.com/azure/devops/pipelines/languages/docker

trigger:
- master

resources:
- repo: self

variables:

  # Container registry service connection established during pipeline creation
  dockerRegistryServiceConnection: '<hidden>'
  imageRepository1: 'k8spocfront'
  imageRepository2: 'k8spocback'
  containerRegistry: '<hidden>.azurecr.io'
  dockerfilePath1: 'k8sPOC/Dockerfile'
  dockerfilePath2: 'k8sPOCApi/Dockerfile'
  tag: '$(Build.BuildId)'

  # Kubernetes Namespace
  k8sNamespace: 'default'
  imagePullSecret: '<hidden>'

  # Agent VM image name
  vmImageName: 'ubuntu-latest'

stages:
- stage: Build_FrontEnd
  displayName: Build stage 1
  jobs:  
  - job: Build
    displayName: Build job
    pool:
      vmImage: $(vmImageName)
    steps:
    - task: Docker@2
      displayName: Build and push an image to container registry
      inputs:
        command: buildAndPush
        repository: $(imageRepository1)
        dockerfile: $(dockerfilePath1)
        containerRegistry: $(dockerRegistryServiceConnection)
        tags: |
          $(tag)

- stage: Build_BackEnd
  displayName: Build stage 2
  jobs:  
  - job: Build
    displayName: Build job
    pool:
      vmImage: $(vmImageName)
    steps:
    - task: Docker@2
      displayName: Build and push an image to container registry
      inputs:
        command: buildAndPush
        repository: $(imageRepository2)
        dockerfile: $(dockerfilePath2)
        containerRegistry: $(dockerRegistryServiceConnection)
        tags: |
          $(tag)          

    - task: PublishPipelineArtifact@0
      inputs:
        artifactName: 'manifests'
        targetPath: 'manifests'

- stage: Deploy_FrontEnd
  displayName: Deploy stage
  dependsOn: Build_BackEnd
  jobs:
  - deployment: Deploy
    displayName: Deploy job
    pool:
      vmImage: $(vmImageName)
    environment: '<hidden>.default'
    strategy:
      runOnce:
        deploy:
          steps:
          - task: DownloadPipelineArtifact@1
            inputs:
              artifactName: 'manifests'
              downloadPath: '$(System.ArtifactsDirectory)/manifests'

          - task: KubernetesManifest@0
            displayName: Create imagePullSecret
            inputs:
              action: createSecret
              secretName: $(imagePullSecret)
              namespace: $(k8sNamespace)
              dockerRegistryEndpoint: $(dockerRegistryServiceConnection)

          - task: KubernetesManifest@0
            displayName: Deploy to Kubernetes cluster
            inputs:
              action: deploy
              namespace: $(k8sNamespace)
              manifests: |
                $(System.ArtifactsDirectory)/manifests/deployment1.yml
                $(System.ArtifactsDirectory)/manifests/service1.yml
                $(System.ArtifactsDirectory)/manifests/deployment2.yml
                $(System.ArtifactsDirectory)/manifests/service2.yml                
              imagePullSecrets: |
                $(imagePullSecret)
              containers: |
                $(containerRegistry)/$(imageRepository1):$(tag)
                $(containerRegistry)/$(imageRepository2):$(tag)


0 commentaires

0
votes

Je ne l'ai pas essayé moi-même, mais vous pouvez profiter de la stratégie matrix .
Les travaux seront dupliqués et exécutés en parallèle, chaque bâtiment et poussant une image différente.
En utilisant votre yaml, cela ressemblerait à ceci:

# Deploy to Azure Kubernetes Service
# Build and push image to Azure Container Registry; Deploy to Azure Kubernetes Service
# https://docs.microsoft.com/azure/devops/pipelines/languages/docker

trigger:
- master

resources:
- repo: self

variables:
  # Container registry service connection established during pipeline creation
  dockerRegistryServiceConnection: '<hidden>'
  imageRepository1: 'k8spocfront'
  imageRepository2: 'k8spocback'
  containerRegistry: '<hidden>.azurecr.io'
  dockerfilePath1: 'k8sPOC/Dockerfile'
  dockerfilePath2: 'k8sPOCApi/Dockerfile'
  tag: '$(Build.BuildId)'

  # Kubernetes Namespace
  k8sNamespace: 'default'
  imagePullSecret: '<hidden>'

  # Agent VM image name
  vmImageName: 'ubuntu-latest'

stages:
- stage: Build
  displayName: Build stage
  jobs:  
  - job: Build
    displayName: Build job
    strategy:
      matrix:
        image1:
          imageRepository: $(imageRepository1)
          dockerfilePath: $(dockerfilePath1)
        image2:
          imageRepository: $(imageRepository2)
          dockerfilePath: $(dockerfilePath2)
      maxParallel: 2
    pool:
      vmImage: $(vmImageName)
    steps:
    - task: Docker@2
      displayName: Build and push an image to container registry
      inputs:
        command: buildAndPush
        repository: $(imageRepository)
        dockerfile: $(dockerfilePath)
        containerRegistry: $(dockerRegistryServiceConnection)
        tags: |
          $(tag)
    - task: PublishPipelineArtifact@0
      inputs:
        artifactName: 'manifests'
        targetPath: 'manifests'
      condition: and(succeeded(), eq(variables['imageRepository'], $(imageRepository1)))

- stage: Deploy_FrontEnd
  displayName: Deploy stage
  dependsOn: Build_BackEnd
  jobs:
  - deployment: Deploy
    displayName: Deploy job
    pool:
      vmImage: $(vmImageName)
    environment: '<hidden>.default'
    strategy:
      runOnce:
        deploy:
          steps:
          - task: DownloadPipelineArtifact@1
            inputs:
              artifactName: 'manifests'
              downloadPath: '$(System.ArtifactsDirectory)/manifests'

          - task: KubernetesManifest@0
            displayName: Create imagePullSecret
            inputs:
              action: createSecret
              secretName: $(imagePullSecret)
              namespace: $(k8sNamespace)
              dockerRegistryEndpoint: $(dockerRegistryServiceConnection)

          - task: KubernetesManifest@0
            displayName: Deploy to Kubernetes cluster
            inputs:
              action: deploy
              namespace: $(k8sNamespace)
              manifests: |
                $(System.ArtifactsDirectory)/manifests/deployment1.yml
                $(System.ArtifactsDirectory)/manifests/service1.yml
                $(System.ArtifactsDirectory)/manifests/deployment2.yml
                $(System.ArtifactsDirectory)/manifests/service2.yml                
              imagePullSecrets: |
                $(imagePullSecret)
              containers: |
                $(containerRegistry)/$(imageRepository1):$(tag)
                $(containerRegistry)/$(imageRepository2):$(tag)

Comme vous pouvez le voir, je n'ai utilisé qu'une seule étape pour créer les images Docker. J'ai remarqué que vous publiez le manifeste back-end en tant qu'artefact de pipeline, je l'ai donc conservé et ajouté une condition pour que la tâche de publication ne s'exécute que lorsqu'elle le devrait.


0 commentaires