Home > Enterprise >  Is Azure Pipelines supposed to generate my Kubernetes Manifest files? If so, why isn't mine?
Is Azure Pipelines supposed to generate my Kubernetes Manifest files? If so, why isn't mine?

Time:12-21

I've been struggling with this for weeks, so I'm finally reaching out.

From what I understand, Azure DevOps pipelines are able to generate a start-to-finish YAML file that builds and pushes docker files into Azure Container Registry, and then employs Kubernetes to generate manifests files as artifacts and subsequently use the generated manifests files to deploy our multi-container application into Azure Kubernetes Service. Is that a bad understanding? Do I need to have my manifest files written myself before using the pipeline? If so, is there a better way to generate the manifests files? Currently I've tried doing it by hand, line by line, but I'm running into issues.

I've attached the auto-generated YAML file to this post - I've gone through and hidden personal/private details from the code. I've been able to get it to do the first stage without issue - composing/pushing docker files to ACR, but the deploy stage fails every time. For various reasons - I'm guessing because my manifest files are incorrectly written.

# Starter pipeline
# Start with a minimal pipeline that you can customize to build and deploy your code.
# Add steps that build, run tests, deploy, and more:
# https://aka.ms/yaml

trigger:
- master

resources:
- repo: self

variables:

  # Container registry service connection established during pipeline creation
  dockerRegistryServiceConnection: 'HIDDEN'
  imageRepository: 'dec7'
  containerRegistry: 'HIDDEN'
  dockerfilePath: '**/Dockerfile'
  buildContext: 1.x/trunk/src/
  tag: '$(Build.BuildId)'
  imagePullSecret: 'HIDDEN'

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

  # Name of the new namespace being created to deploy the PR changes.
  k8sNamespaceForPR: 'review-app-$(System.PullRequest.PullRequestId)'

stages: 
- stage: Build
  displayName: Build stage
  jobs:
  - job: Build
    displayName: Build
    pool:
      vmImage: $(vmImageName)
    steps:
    - task: DockerCompose@0
      displayName: 'Build services'
      inputs:
        containerregistrytype: 'Azure Container Registry'
        azureSubscription: HIDDEN
        azureContainerRegistry: 'HIDDEN'
        dockerComposeFile: '1.x/trunk/src/docker-compose.yml'
        dockerComposeFileArgs: 'DOCKER_BUILD_SOURCE='
        action: 'Build services'
        additionalImageTags: '$(Build.BuildId)'

    - task: DockerCompose@0
      displayName: 'Push services'
      inputs:
        containerregistrytype: 'Azure Container Registry'
        azureSubscription: HIDDEN
        azureContainerRegistry: 'HIDDEN'
        dockerComposeFile: '1.x/trunk/src/docker-compose.yml'
        dockerComposeFileArgs: 'DOCKER_BUILD_SOURCE='
        action: 'Push services'
        additionalImageTags: '$(Build.BuildId)'

    - task: DockerCompose@0
      displayName: 'Lock services'
      inputs:
        containerregistrytype: 'Azure Container Registry'
        azureSubscription: HIDDEN
        azureContainerRegistry: 'HIDDEN'
        dockerComposeFile: '1.x/trunk/src/docker-compose.yml'
        dockerComposeFileArgs: 'DOCKER_BUILD_SOURCE='
        action: 'Lock services'
        outputDockerComposeFile: '$(Build.StagingDirectory)/docker-compose.yml'

    - upload: manifests
      artifact: manifests

- stage: Deploy
  displayName: Deploy stage
  dependsOn: Build

  jobs:
  - deployment: Deploy
    condition: and(succeeded(), not(startsWith(variables['Build.SourceBranch'], 'refs/pull/')))
    displayName: Deploy
    pool:
      vmImage: $(vmImageName)
    environment: HIDDEN
    strategy:
      runOnce:
        deploy:
          steps:
          - checkout: self
          - task: KubernetesManifest@0
            displayName: Create imagePullSecret
            inputs:
              action: 'createSecret'
              kubernetesServiceConnection: 'AKSServiceConnectionDec6'
              secretType: 'dockerRegistry'
              secretName: '$(imagePullSecret)'
              dockerRegistryEndpoint: '$(dockerRegistryServiceConnection)'

          - task: KubernetesManifest@0
            displayName: Deploy to Kubernetes cluster
            inputs:
              action: 'deploy'
              kubernetesServiceConnection: 'AKSServiceConnectionDec6'
              manifests: |
                $(Pipeline.Workspace)/manifests/deployment.yml
                $(Pipeline.Workspace)/manifests/service.yml
              containers: '$(containerRegistry)/$(imageRepository):$(tag)'
              imagePullSecrets: '$(imagePullSecret)'

  - deployment: DeployPullRequest
    displayName: Deploy Pull request
    condition: and(succeeded(), startsWith(variables['Build.SourceBranch'], 'refs/pull/'))
    pool:
      vmImage: $(vmImageName)

    environment: 'HIDDEN$(k8sNamespaceForPR)'
    strategy:
      runOnce:
        deploy:
          steps:
          - reviewApp: HIDDEN

          - task: Kubernetes@1
            displayName: 'Create a new namespace for the pull request'
            inputs:
              connectionType: 'Kubernetes Service Connection'
              kubernetesServiceEndpoint: 'AKSServiceConnectionDec6'
              command: 'apply'
              useConfigurationFile: true
              secretType: 'dockerRegistry'
              containerRegistryType: 'Azure Container Registry'

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

          - task: KubernetesManifest@0
            displayName: Deploy to the new namespace in the Kubernetes cluster
            inputs:
              action: 'deploy'
              kubernetesServiceConnection: 'AKSServiceConnectionDec6'
              namespace: '$(k8sNamespaceForPR)'
              manifests: |
                $(Pipeline.Workspace)/manifests/deployment.yml
                $(Pipeline.Workspace)/manifests/service.yml
              containers: '$(containerRegistry)/$(imageRepository):$(tag)'
              imagePullSecrets: '$(imagePullSecret)'

          - task: Kubernetes@1
            name: get
            displayName: 'Get services in the new namespace'
            continueOnError: true
            inputs:
              connectionType: 'Kubernetes Service Connection'
              kubernetesServiceEndpoint: 'AKSServiceConnectionDec6'
              namespace: '$(k8sNamespaceForPR)'
              command: 'get'
              arguments: 'svc'
              secretType: 'dockerRegistry'
              containerRegistryType: 'Azure Container Registry'
              outputFormat: 'jsonpath=''http://{.items[0].status.loadBalancer.ingress[0].ip}:{.items[0].spec.ports[0].port}'''

          # Getting the IP of the deployed service and writing it to a variable for posing comment
          - script: |
              url="$(get.KubectlOutput)"
              message="Your review app has been deployed"
              if [ ! -z "$url" -a "$url" != "http://:" ]
              then
                message="${message} and is available at $url.<br><br>[Learn More](https://aka.ms/testwithreviewapps) about how to test and provide feedback for the app."
              fi
              echo "##vso[task.setvariable variable=GITHUB_COMMENT]$message"

I've tried generating new pipelines from scratch using both the classic editor as well as the new editor Microsoft provides. I get an issue with the build stage not being able to find the working directory. I fix this by specifying that manually. However, once the pipeline gets to the deploy stage I get the following error:

##[error]No manifest file(s) matching /home/vsts/work/1/manifests/deployment.yml,/home/vsts/work/1/manifests/service.yml was found.

This tells me that the pipeline isn't generating manifest files like I thought it was supposed to. So I wrote one myself, probably incorrectly, and it ran once - but timed out. Now I get the following error after running the deploy stage with an altered manifest file:

error: deployment "v4deployment" exceeded its progress deadline
##[error]Error: error: deployment "v4deployment" exceeded its progress deadline

CodePudding user response:

Is that a bad understanding?

Yes. You still have to author your deployment manifests. The pipeline can apply the manifests to the cluster, but it's not going to generate anything for you.

CodePudding user response:

Assmption: Your cluster is AKS

Is that a bad understanding?

Nope its correct understading. When you create new pipeline and select option Deploy to Azure Kubernetes Service, this option will ask for Azure Subscription and seleting all option will generate pipeline yaml along with kubernetes manifest file inside manifest folder under root of your repository. You can modify/ updated these manifest files as per your need. I have removed some of personal details from snapshot. enter image description here

##[error]No manifest file(s) matching /home/vsts/work/1/manifests/deployment.yml,/home/vsts/work/1/manifests/service.yml was found.

You have to check the path of manifest files generated inside your repo and provide the absolute path inside your pipeline yaml file. eg for our case manifest files were hosted under root --> manifests --> framework --> develop. So my yaml was like this.

          - task: KubernetesManifest@0
            displayName: Deploy to Kubernetes cluster
            inputs:
              action: deploy
              manifests: |
                $(Pipeline.Workspace)/manifests/framework/develop/deployment.yml
                $(Pipeline.Workspace)/manifests/framework/develop/service.yml
                imagePullSecrets: |
                $(imagePullSecret)
              containers: |
                $(containerRegistry)/$(imageRepository):$(tag)

error: deployment "v4deployment" exceeded its progress deadline ##[error]Error: error: deployment "v4deployment" exceeded its progress deadline

This error indicates that your deployment is done. Now deployment is waiting for all application pods to be in running state but somehow pods are not getting ready due to error. To check the error you can access your cluster (kubeconfig or dashboard) and check the namespace events or you can check pod events / logs directly. These two commands will give you enough evidence why your pods are not healthy.

kubectl describe pod your-pod-name -n your-namespace
kubectl logs -f your-pod-name -n your-namespace
  • Related