拆分构建和部署管道,无法弄清楚 k8s 清单上传需要去哪里

Splitting out build and deployment pipelines and can't figure out where the k8s manifest uploads need to go

所以我采用了系统生成的 azure-pipelines.yml,现在我将其拆分为 build.yamldeployment.yaml,每个在 Azure DevOps 中都有自己的管道。

我已将分支和构建验证添加到 production 分支,以便 PR 需要合并到它。创建 PR 时,它会自动运行 Build,因此会运行 build.yaml 管道。

如果通过,可以通过,并入production。然后合并触发 Deployment,因此 deployment.yaml 管道。

Build 正在工作。 Deployment 不是,原因是它找不到 k8s 清单...基本上系统中的这一部分生成 azure-pipelines.yml:

- upload: k8s
  artifact: k8s

以下是自动生成内容的完整上下文:

trigger:
- production

resources:
- repo: self

variables:

  # Container registry service connection established during pipeline creation
  dockerRegistryServiceConnection: '<GUID>'
  imageRepository: 'app'
  containerRegistry: 'appacr.azurecr.io'
  dockerfilePath: '$(Build.SourcesDirectory)'
  tag: '$(Build.BuildId)'
  imagePullSecret: 'appacr1c5a-auth'

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

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

    - upload: k8s
      artifact: k8s

- stage: Deploy
  displayName: Deploy stage
  dependsOn: Build
  jobs:
    - deployment: Deploy
      displayName: Deploy
      pool:
        vmImage: $(vmImageName)
      environment: 'App Production AKS'
      strategy:
        runOnce:
          deploy:
            steps:
            - task: KubernetesManifest@0
              displayName: Create imagePullSecret
              inputs:
                action: createSecret
                secretName: $(imagePullSecret)
                kubernetesServiceConnection: 'App Production AKS'
                dockerRegistryEndpoint: $(dockerRegistryServiceConnection)
            - task: KubernetesManifest@0
              displayName: Deploy to api Kubernetes cluster
              inputs:
                action: deploy
                kubernetesServiceConnection: 'App Production AKS'
                manifests: |
                  $(Pipeline.Workspace)/k8s/aks/api.yaml
                imagePullSecrets: |
                  $(imagePullSecret)
                containers: |
                  $(containerRegistry)/$(imageRepository)-api:$(tag)

这就是我拆分的方式:

# build.yaml (works)
trigger: none

resources:
- repo: self

variables:
- template: templates/variables.yaml

stages:
- stage: Build
  displayName: Build stage
  jobs:
  - job: Build
    displayName: Build
    pool:
      vmImage: $(vmImageName)
    steps:
    - task: Docker@2
      displayName: Build and push an api image to container registry
      inputs:
        command: buildAndPush
        repository: $(imageRepository)-api
        dockerfile: $(dockerfilePath)/api/Dockerfile
        containerRegistry: $(dockerRegistryServiceConnection)
        tags: |
          $(tag)
    - upload: k8s
      artifact: k8s

还有...

# deployment.yaml (does not work)
trigger: 
  branches: 
    include:
    - production

resources:
- repo: self

variables:
- template: templates/variables.yaml

stages:
# - template: templates/changed.yaml
- stage: Deploy
  displayName: Deploy stage
  # dependsOn: Build
  jobs:
  - deployment: Deploy
    displayName: Deploy
    pool:
      vmImage: $(vmImageName)
    environment: 'App Production AKS'
    strategy:
      runOnce:
        deploy:
          steps:
          - task: PublishPipelineArtifact@1
            displayName: Publish k8s manifests
            inputs:
              targetPath: $(Build.SourcesDirectory)/k8s
              artifactName: k8s
              artifactType: pipeline
          - task: KubernetesManifest@0
            displayName: Create imagePullSecret
            inputs:
              action: createSecret
              secretName: $(imagePullSecret)
              kubernetesServiceConnection: 'App Production AKS'
              dockerRegistryEndpoint: $(dockerRegistryServiceConnection)        
          - task: KubernetesManifest@0
            displayName: Deploy to api Kubernetes cluster
            inputs:
              action: deploy
              kubernetesServiceConnection: 'App Production AKS'
              manifests: |
                $(Pipeline.Workspace)/k8s/aks/api.yaml
              imagePullSecrets: |
                $(imagePullSecret)
              containers: |
                $(containerRegistry)/$(imageRepository)-api:$(tag)

我已经尝试了十几种不同的方法来发布 k8s 清单,错误消息通常类似于:

##[error]Path does not exist: /home/vsts/work/1/s/k8s

# or 

##[error]No manifest file(s) matching /home/vsts/work/1/k8s/aks/api.yaml was found.

关于如何解决这个问题的建议?

显然有些概念我没有完全掌握。

好吧,这是否被认为是 good/practice 是另一回事,但我确实使用了以下内容:

# deployment.yaml (does not work)
trigger: 
  branches: 
    include:
    - production

resources:
- repo: self

variables:
- template: templates/variables.yaml

stages:
- stage: Publish
  displayName: Publish artifacts
  jobs:
  - job: Publish
    displayName: Publish
    pool:
      vmImage: $(vmImageName)
    steps:
    - upload: k8s
      artifact: k8s
- stage: Deploy
  displayName: Deploy stage
  dependsOn: Publish
  jobs:
  - deployment: Deploy
    displayName: Deploy
    pool:
      vmImage: $(vmImageName)
    environment: 'App Production AKS'
    strategy:
      runOnce:
        deploy:
          steps:
          - task: KubernetesManifest@0
            displayName: Create imagePullSecret
            inputs:
              action: createSecret
              secretName: $(imagePullSecret)
              kubernetesServiceConnection: 'App Production AKS'
              dockerRegistryEndpoint: $(dockerRegistryServiceConnection)        
          - task: KubernetesManifest@0
            displayName: Deploy to api Kubernetes cluster
            inputs:
              action: deploy
              kubernetesServiceConnection: 'App Production AKS'
              manifests: |
                $(Pipeline.Workspace)/k8s/aks/api.yaml
              imagePullSecrets: |
                $(imagePullSecret)
              containers: |
                $(containerRegistry)/$(imageRepository)-api:$(tag)