Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Set Up and Deploy to Kubernetes Using Azure DevOps (CI/CD)

DZone 's Guide to

Set Up and Deploy to Kubernetes Using Azure DevOps (CI/CD)

Build Docker images, push to a container registry, and deploy into Kubernetes.

Free Resource

This article demonstrates how to build docker images, push to a container registry, and deploy that registry into Kubernetes.

Prerequisites

  • Azure Subscription credentials, Create an Azure container registry (ACR).

  • AKS Managed cluster.

Create an Azure Container Registry (ACR) Using CLI

The Azure container registry is a private Docker registry in Azure that stores Docker container images and uses Docker commands to push a container image into a registry. In the end, it pulls and runs the image from the registry. In order to use this tool, you need to: 

  •  Install Azure command-line interface.

  • Check the version of azure-CLI version with the following command.

az --version


  • Use the following command to set the subscription id or name of the subscription.
  • az account set --subscription "$(id or name)"


    •  Create a resource group.

    az group create --name $(resource group) --location westus


  • Create a container registry by using the following command:
  • az acr create --resource-group (myResourceGroup) --name myContainerRegistry007 --sku Basic


    This command gives output in a JSON format and takes note of the login server name, which is a container registry name.

    • Before pulling and pushing images into the ACR, you need to log in to ACR by using the following command.

    az acr login --name <acrName>


    Continuous Integration (CI)

    Use the azure-pipelines.yml, shown in full at the end of this post at the root of your repository and adjust variables to work for your needs. This .yaml file will create a build pipeline for your project. Modify this file and commit it back to your repository so that your build/deploy processes are also treated as code.

    Follow all instructions in "Introduction to Azure Pipelines" to create a build pipeline to build docker images for .NET or NodeJS applications.

    Steps

    • Azure pipelines have an option to build and deploy using Microsoft-hosted agents. Each time you build or release a pipeline, you get a fresh virtual machine (VM) for the build.
    • If Microsoft-hosted agents don't work, use a self-hosted agent that will act as a system host.
    pool:
       name: Hosted Ubuntu 1604


    • Build, push, or run a container Docker application. The task can be used with Docker or Azure Container registry.

    Build Container Image Using docker-compose.yaml

    This task will build the Docker image from the docker-compose file mentioned the ACR  and subscription details.

    steps:
    - task: DockerCompose@0
      displayName: 'Build services'
      inputs:
        azureSubscription: '(xxxx-xxxx-xxx-xxx)'
        azureContainerRegistry: '{"loginServer":"iotci.azurecr.io", "id" : "/subscriptions/a476/resourceGroups/xxxaa/providers/Microsoft.ContainerRegistry/registries/XXXX"}'
        dockerComposeFile: 'docker-compose.yml'
        action: 'Build services'
        additionalImageTags: '$(Build.BuildId)'
        includeLatestTag: true
    


    • Push a container image to Azure container registry(ACR)
    steps:
    - task: DockerCompose@0
      displayName: 'Push services'
      inputs:
        azureSubscription: 'SIOT-CI-01 (XXXX-XXXX-XXX-XXX-XXX)'
        azureContainerRegistry: '{"loginServer":"iotci.azurecr.io", "id" : "/subscriptions/XXXX-XXX-XXX-XXX/resourceGroups/iotcicd/providers/Microsoft.ContainerRegistry/registries/iotcicd9fa3"}'
        dockerComposeFile: 'docker-compose.yml'
        action: 'Push services'
        additionalImageTags: '$(Build.BuildId)'
    
    


    • Use of this task in the build pipeline to publish the build artifacts to the Azure pipelines file share.  Artifacts of the build store it in the Azure DevOps server.

    steps:
    - task: PublishBuildArtifacts@1
      displayName: 'Publish Artifact: drop'
    


    Release Pipeline (CD)

    Before creating a release pipeline, you need to create an AKS (Azure Kubernetes Cluster) manually by using Azure CLI or Azure Portal. AKS is a managed Kubernetes cluster used to quickly deploy and manage the cluster.

    Create a Kubernetes Cluster

    Use the following command to create an AKS cluster with one node.

    az aks create \
        --resource-group myResourceGroup \
        --name myAKSCluster \
        --node-count 1 \
        --enable-addons monitoring \
        --generate-ssh-keys
    


    • Manage kubernetes cluster with the kubectl command line; this will communicate with the kubernetes API cluster.
    • Use the following command to download credentials and configure the Kubernetes CLI.
    az aks get-credentials --resource-group myResourceGroup --name myAKSCluster


  • Verify the connection to the cluster; use the kubectl get command to list the nodes
  • kubectl get nodes


  • Make sure that status is Ready
  • Run the Application

    Kubernetes describes a desired state of the cluster and what container images to run. A manifest is used to create all objects needed; it can create a deployment, service, ingress, config map. Create a namespace with the following command.

    kubectl create ns <namespace-name>


    Create a file name with azure-svc.yaml, azure-dep.yaml and load balancer for service to expose the outside world. The Yaml definition will use these manifest files to deploy objects into a cluster.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: azure-vote-back
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: azure-vote-back
      template:
        metadata:
          labels:
            app: azure-vote-back
        spec:
          nodeSelector:
            "beta.kubernetes.io/os": linux
          containers:
          - name: azure-vote-back
            image: redis
            resources:
              requests:
                cpu: 100m
                memory: 128Mi
              limits:
                cpu: 250m
                memory: 256Mi
            ports:
            - containerPort: 6379
              name: redis
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: azure-vote-back
    spec:
      ports:
      - port: 6379
      selector:
        app: azure-vote-back
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: azure-vote-front
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: azure-vote-front
      template:
        metadata:
          labels:
            app: azure-vote-front
        spec:
          nodeSelector:
            "beta.kubernetes.io/os": linux
          containers:
          - name: azure-vote-front
            image: microsoft/azure-vote-front:v1
            resources:
              requests:
                cpu: 100m
                memory: 128Mi
              limits:
                cpu: 250m
                memory: 256Mi
            ports:
            - containerPort: 80
            env:
            - name: REDIS
              value: "azure-vote-back"
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: azure-vote-front
    spec:
      type: LoadBalancer
      ports:
      - port: 80
      selector:
        app: azure-vote-front


    Deploy the application in AKS by using Kubectl to apply the following task.

    variables:
      cluster_rg: 'DefaultResourceGroup-EUS'
      kube_cluster: 'test'
    
    steps:
    - task: Kubernetes@1
      displayName: 'kubectl apply'
      inputs:
        connectionType: 'Azure Resource Manager'
        azureSubscriptionEndpoint: 
        azureResourceGroup: '$(cluster_rg)'
        kubernetesCluster: '$(kube_cluster)'
        command: apply
        useConfigurationFile: true
        configuration: 'c:/azure.yaml'
        secretType: generic
        secretName: 'acr-authentication'
        versionSpec: 1.8.1
    


         Verify each task logs for Build (CI) and Release pipeline(CD) . Verifying task logs for Build (CI) and release pipeline (CD)


    An azure-pipelines.yml is shown here.

    # Build(CI) pipeline to build docker image and push into a Container,nodejs application code.
    pool:
      vmImage: 'Ubuntu 16.04'
    steps:
    - task: NodeTool@0
      inputs:
        versionSpec: '8.x'
      displayName: 'Install Node.js'
    - script: |
        cd result
        npm install
        npm run build
      displayName: 'npm install and build'
    
    steps:
    - task: DockerCompose@0
      displayName: 'Build services'
      inputs:
        azureSubscription: '(xxxx-xxxx-xxx-xxx)'
        azureContainerRegistry: '{"loginServer":"iotci.azurecr.io", "id" : "/subscriptions/a476/resourceGroups/xxxaa/providers/Microsoft.ContainerRegistry/registries/XXXX"}'
        dockerComposeFile: 'docker-compose.yml'
        action: 'Build services'
        additionalImageTags: '$(Build.BuildId)'
        includeLatestTag: true
    steps:
    - task: DockerCompose@0
      displayName: 'Push services'
      inputs:
        azureSubscription: 'IoT (XXXX-XXXX-XXX-XXX-XXX)'
        azureContainerRegistry: '{"loginServer":"iotci.azurecr.io", "id" : "/subscriptions/XXXX-XXX-XXX-XXX/resourceGroups/iotcicd/providers/Microsoft.ContainerRegistry/registries/iotcicd9fa3"}'
        dockerComposeFile: 'docker-compose.yml'
        action: 'Push services'
    steps:
    - task: PublishBuildArtifacts@1
      displayName: 'Publish Artifact: drop'
    #Release(CD) pipeline to deploy into a nodejs application.
    az aks get-credentials --resource-group $(cluster_rg) --name $(kube_cluster)
    variables:
      cluster_rg: 'DefaultResourceGroup-EUS'
      kube_cluster: 'test'
    
    steps:
    - task: Kubernetes@1
      displayName: 'kubectl apply'
      inputs:
        connectionType: 'Azure Resource Manager'
        azureSubscriptionEndpoint: 'Subscription name (XXXX-XXXX-XXXX-XXXX)'
        azureResourceGroup: '$(cluster_rg)'
        kubernetesCluster: '$(kube_cluster)'
        command: apply
        useConfigurationFile: true
        configuration: 'c:/test.yaml'
        secretType: generic
        secretName: 'authenticate'
        versionSpec: 1.8.1
    
    Topics:
    azure devops ,kubernetes ,docker

    Opinions expressed by DZone contributors are their own.

    {{ parent.title || parent.header.title}}

    {{ parent.tldr }}

    {{ parent.urlSource.name }}