拆分构建和部署管道,无法弄清楚 k8s 清单上传需要去哪里
Splitting out build and deployment pipelines and can't figure out where the k8s manifest uploads need to go
所以我采用了系统生成的 azure-pipelines.yml
,现在我将其拆分为 build.yaml
和 deployment.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)
所以我采用了系统生成的 azure-pipelines.yml
,现在我将其拆分为 build.yaml
和 deployment.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)