Kubernetes and Azure Pipeline in action. Detailed guide.

Serhii Korol - Jun 21 '23 - - Dev Community

Entry

In the previous article, I showed how to create a pipeline on GitHub. Today, I would like to show you how to create the pipeline in Azure DevOps. In the previous article, I haven't built containers and checked them. It might be helpful if you want to deploy your application to Azure. I'll not show how to deploy your application, but I show how to prepare the application, create Kubernetes configuration, and configure Azure Pipeline. Sit back, and let's start.

Preconditions

Before we start, I want to enumerate preconditions for a better understanding of this material. For this practice work, you should have:

  • Should be installed IDE or text editor and Docker Desktop.
  • Also you should have experience with Docker.

Project

I'll not create a new template project since it'll be too simple and uninteresting. Instead, let's clone to any convenient folder the finished project from GitHub:

git clone https://github.com/SergKorol/ManagementSystem.git
Enter fullscreen mode Exit fullscreen mode

And now, let's ensure that your Docker Desktop is already run and Kubernetes is also enabled and run. Both services should be green.

Docker left panel

If everything is OK, build the project and ensure that it's not having errors, and also build up the Docker image. You should ensure that the project is opening through Docker.

Kubernetes

Now, let's start creating the configuration for Kubernetes. I'll create it in ShopManagementSystem.Dashboard project, however, you can create into any different folder at your discretion.

cd src/ShopManagementSystem/ShopManagementSystem.Dashboard
Enter fullscreen mode Exit fullscreen mode

And create a YAML file in this folder:

touch k8s.deploy.yaml
Enter fullscreen mode Exit fullscreen mode

Open it in any editor and paste this code:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: shop-system
  labels:
    app: shop-system-app
spec:
  replicas: 1
  selector:
    matchLabels:
      service: shop-system
  template:
    metadata:
      labels:
        app: shop-system-app
        service: shop-system
    spec:
      containers:
        - name: shop-system
          image: managementsystem-webmvc
          imagePullPolicy: Never
          ports:
            - containerPort: 80
              protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
  name: shop-system
  labels:
    app: shop-system-app
    service: shop-system
spec:
  type: LoadBalancer
  ports:
    - port: 11000
      targetPort: 80
      protocol: TCP
  selector:
    service: shop-system
Enter fullscreen mode Exit fullscreen mode

The configuration file is divided into two parts. In the first part, the configuration of Kubernetes and mounting existing built Docker image. It's a simplified configuration with one replica, but injected service that is described below. The service type of LoadBalancer.
Save this file and let's apply it. Important, your Kubernetes should work!. Paste this command to the terminal:

kubectl apply -f k8s.deploy.yaml
Enter fullscreen mode Exit fullscreen mode

If everything is OK, you'll see the message like this:

deployment.apps/shop-system configured
service/shop-system created
Enter fullscreen mode Exit fullscreen mode

Let's check out and see our pods, put this command:

kubectl get pod
Enter fullscreen mode Exit fullscreen mode

You should see this table:

NAME                           READY   STATUS              RESTARTS   AGE
shop-system-7f5dc5f85f-czp7q   1/1     Running             0          3h17m
Enter fullscreen mode Exit fullscreen mode

With the pod is OK. Next, let's check the service. Put this command:

 kubectl get service
Enter fullscreen mode Exit fullscreen mode

You should see cluster and service, like this:

NAME          TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)           AGE
kubernetes    ClusterIP      10.96.0.1       <none>        443/TCP           15h
shop-system   LoadBalancer   10.98.254.189   localhost     11000:31224/TCP   3h6m
Enter fullscreen mode Exit fullscreen mode

Pay attention, your service should have external IP. If it has a "pending" status, you should wait or delete it and create it again. And let's check out the work and type localhost:11000 in the browser. It should work fine.

Pipeline

The Azure Pipeline is similar to GitHub Actions, however, I'm gonna make it more difficult and add create a cluster. Go to the root folder of this project and paste the command and open it:

touch azure-pipelines.yml
Enter fullscreen mode Exit fullscreen mode

Next step, paste this code:

trigger:
  branches:
    include:
      - main

pool:
  vmImage: 'ubuntu-latest'

variables:
  buildConfiguration: 'Release'

jobs:
- job: Build
  displayName: 'Build Solution'
  steps:
  - task: UseDotNet@2
    displayName: 'Install .NET SDK'
    inputs:
      packageType: 'sdk'
      version: '7.x'
      installationPath: '$(Agent.ToolsDirectory)/dotnet'

  - script: dotnet restore
    displayName: 'Restore NuGet packages'
    workingDirectory: '$(Build.SourcesDirectory)/src/ShopManagementSystem'

  - script: dotnet build --configuration $(buildConfiguration) --no-restore
    displayName: 'Build Solution'
    workingDirectory: '$(Build.SourcesDirectory)/src/ShopManagementSystem'

- job: Test
  displayName: 'Run Tests'
  dependsOn: Build
  steps:
  - script: dotnet restore
    displayName: 'Restore NuGet packages'
    workingDirectory: '$(Build.SourcesDirectory)/src/ShopManagementSystem'
  - script: dotnet build --configuration $(buildConfiguration) --no-restore --output $(Build.ArtifactStagingDirectory)/$(buildConfiguration)
    displayName: 'Build Output'
    workingDirectory: '$(Build.SourcesDirectory)/src/ShopManagementSystem'
  - script: dotnet test $(Build.ArtifactStagingDirectory)/$(buildConfiguration)/ShopManagementSystem.UnitTests.dll --configuration $(buildConfiguration) --no-build --collect "Code Coverage"
    displayName: 'Run Unit Tests'
    workingDirectory: '$(Build.SourcesDirectory)/src/ShopManagementSystem'

- job: Publish
  displayName: 'Publish Artifacts'
  dependsOn: Test
  steps:
  - script: dotnet publish --configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)
    displayName: 'Publish Solution'
    workingDirectory: '$(Build.SourcesDirectory)/src/ShopManagementSystem'

  - task: CmdLine@2
    displayName: 'Build Docker Image'
    inputs:
      script: 'docker-compose -f docker-compose.yml build'
      workingDirectory: '$(Build.SourcesDirectory)'

  - task: CopyFiles@2
    displayName: 'Copy Kubernetes Deployment Files'
    inputs:
      SourceFolder: '$(Build.SourcesDirectory)/src/ShopManagementSystem/ShopManagementSystem.Dashboard'
      Contents: '**/k8s.deploy.yaml'
      TargetFolder: '$(Build.ArtifactStagingDirectory)'
      CleanTargetFolder: true
      OverWrite: true
      flattenFolders: true

  - task: PublishBuildArtifacts@1
    displayName: 'Publish Artifacts'
    inputs:
      PathtoPublish: '$(Build.ArtifactStagingDirectory)'
      ArtifactName: 'drop'
      publishLocation: 'AzureBlob'
Enter fullscreen mode Exit fullscreen mode

As I already mentioned, It's similar to GitHub Actions and also has a trigger for the branch. Sure, it also has the same jobs. The first job run building the project, install of SDK, making of restore. If this job was passed, the next job will run a unit test. This job requires restoring and building, otherwise, you'll get fail. The next job is composite with several tasks, that build images, create clusters and services and publish artifacts.

Azure

For adding a pipeline to Azure DevOps, you should log in to https://dev.azure.com/ and make several actions:

start page

  • Create a project

create project

  • In the left panel add a repo. If you use the Azure repo then push your changes, otherwise inject your existing updated repo to Azure from GitHub.

repo

  • Go to pipelines in the left panel and create a new pipeline. Select your Azure repo or external repo, and add a configuration file.

add pipeline

  • Your pipeline should finish successfully.

You'll see a pipeline report like this:

Pipeline

Conclusion

Azure Pipeline isn't more complicated than GitHub Actions. However more flexible. This approach consists of deploying the whole project to Azure. You'll have the base cluster and services if you decide to deploy to the Azure instance.

Happy coding!

Buy Me A Beer

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .