如何使用DevOps管道部署多个微服务

时间:2019-06-24 08:08:07

标签: docker kubernetes .net-core azure-devops azure-pipelines

我正在尝试使用DevOps将两个.Net Core应用程序部署到Azure Kubernetes。默认管道仅构建和部署我添加的第一个项目。

我用两个解决方案文件夹创建了一个解决方案,每个文件夹包含一个.Net Core项目。我已经为两个项目添加了业务流程支持,并使用DevOps中的“向导”创建了Azure管道。成功部署第一个项目后,我已经添加了第二个项目。我认为这个问题存在是因为Docker Registry Service Connection不包含新项目,所以我删除了该项目并重新创建了连接,但它仍然仅部署第一个项目。我正在使用Azure Git。

azure-pipeline.yaml非常标准。我接受了创建管道时创建的默认设置。这是我的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'

如何获取它来构建和部署其他剩余项目?

4 个答案:

答案 0 :(得分:0)

每种解决方案都需要一个不同的构建管道。我的建议是将两个项目都放在一个解决方案下。 在同一解决方案下,您可以具有任何不同类型的项目。

答案 1 :(得分:0)

如果您要创建新管道,则需要从存储库中删除azure-pipelines.yml文件。这将使您从头开始逐步浏览Devops“部署到Azure Kubernetes服务”。这应该使您有机会向发行版中添加任何其他项目。

答案 2 :(得分:0)

我已经使用一个azure-pipelines.yml文件成功部署了两个项目;但是,我几乎可以肯定这是不正确的。 我已经为每个项目重复了Build Stage,并且还指定了两个单独的Dockerfile。另外,我为每个项目添加了一个deployment.yml和service.yml文件。请参阅下面的我的azure-pipelines.yml。有关如何正确执行此操作的任何建议将不胜感激。

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

答案 3 :(得分:0)

我还没有尝试过,但是您可以利用matrix策略。
作业将被复制并并行运行,每个建筑物并推送不同的图像。
使用您的Yaml,它看起来像这样:

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

如您所见,我仅使用了一个阶段来构建Docker映像。我注意到您将后端清单作为管道工件发布,因此我保留了它,并添加了条件,以便发布任务仅在应有的时候运行。