Deploying an Application on Kubernetes.
Tags: kubernetes, devops, tutorial, docker
Published: 2023-05-21 20:48:21

**Introduction**
Kubernetes is an open source technology used to autonomously deploy, scale, and manage applications that use containers. It is a popular container orchestration solution since it enables the control of several containers as a single entity as an alternative to managing each container separately.

This is a walkthrough of deploying an application to Azure Kubernetes Service similar to [my previous article walkthrough](https://github.com/KeneOjiteli/deploy-container-app-on-k8s-cluster).

**What will be covered**
- Azure Kubernetes Service 
- Azure Container Registry
- Docker Container
- Azure CLI
- Kubectl
- Simple Node app

**Overview**
A note keeper app written in node js will be containerized and pushed to ACR, after which one Kubernetes cluster will be created on AKS and a deployment and a service will be created having 4 pod replicas via a manifest file.

**Prerequisites**
- Terminal and Azure CLI installed on local machine - some of the steps for this project (such as connecting to kubernetes cluster will be done using Azure CLI).
- Docker installed on local machine - which will be used to build an image and push to a registry (Azure Container Registry in this demo).
- Azure account with active subscription.
- Code Editor or IDE - which will be used to write code that will be containerized.
- Terraform installed - an IAC tool that will be used to provision infrastructure on Azure.

**Note**: The required services can be created using either **terraform, Azure portal or Azure CLI**.


**Getting Started**
- Testing sample app locally
  - Write the code or fork and clone app from [Github](https://github.com/KeneOjiteli/sca-final-project)
  - Navigate to application folder on terminal using `cd <foldername>`
  - Install dependencies using `npm install`
  - Run app to test using `node <filename>` or `npm <filename>`

![Test on local](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ov2s0gn0yqd78viiw31z.png)
- Login to azure using `az login` on terminal.

![Login on azure CLI](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/iirdko3rhy9oflr6d6tl.png)
- Provision infrastructure on Azure with terraform using the following commands: `terraform init` `terraform fmt` `terraform validate` `terraform plan` `terraform apply`(note that a terraform file has a .tf extension)

![terraform init](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hs5blyib7jnzu453098f.png)
![format terraform file](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2v2sg0p0ww7zs5iqc3wl.png)
![terraform plan](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zfhrv1zv2j58j94hwswx.png)
![terraform apply](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/tjeqnffq9vsljvzh83b0.png)

Head to azure portal to confirm if infrastructure is provisioned

![ACR dashboard](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3q4209hhbj40v4y9c0kp.png)

![AKS dashboard](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1n9qz6hr1zqn7jsvajp7.png) 
**Containerize the application**  
 
- After resources have been provisioned on azure, we need to login to ACR using credentials (which includes login server, username and password) from `container registry => settings => access keys`

- Navigate to your project directory via terminal and login using the details from the step above `docker login <login server> --username <username> --password <password>`

- Build docker image using this command `docker build -t <name>:<tag> .` where `.` is the current directory.

![build image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kkh3l6s27e6y9mh93q5d.png)  
- Check the image exists using `docker images` command ( this lists all available images, the first image is my newly created image).
![List of docker images](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/j3e2v8upig933r4fe1zi.png)
- Push the image to ACR using `docker push <name>:<tag>`

![docker push](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/csur46mee4uk5m3wzi98.png)
- Going over to `azure portal => container registry`, to verify the push is successful.

![image on azure portal](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/9ptyl23xe8lrkk27q9zd.png)
- I created a container using my image (exercising how to forward ports, run container in a detached mode, give container a specified name and run the app using the forwarded port on my local machine)

![docker run](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/433cz8zodnbebhdnkgve.png)
![localhost](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qfue3vf6au1gtw3ncqcm.png)

**Connect to Cluster**
  - **kubectl** will be used to manage the Kubernetes cluster. Run the command `az aks get-credentials --resource-group <resourcegroupname> --name <clustername>` to configure kubectl and connect to the cluster we previously created and also verify connection using `kubectl get nodes` to return a list of the cluster nodes.

![configure kubectl](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vzgrlcakkr8g1wkqs0lz.png)

- **Kubernetes Deployment**: A Deployment is one of the Kubernetes objects that is used to manage Pods via ReplicaSets in a declarative way. It provides updates, control as well as rollback functionalities. This deployment file will be used to:
- Create a deployment (which automatically creates a replicaset), service and pods.

![deployment](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h6mkexzworpgl7hvz4qn.png)
- Lists all objects created at once using `kubectl get` command

![All objects](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ovpe33lsvrkvaodcij66.png)

- Get more details about the deployment, use `kubectl describe deployments <deploymentname>` command

![describe](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wgkdm4qjur1d1true9p7.png)
- Scale down replica set from 2 to 4

![scale down](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5uotwznvcgr33dr05cui.png)
- And also seeing the change in the events log

![describe](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bbthmsj5fw97h42d6ykc.png)
![event](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x03d99w8fo1l8flqk8q1.png)
- Deleting a pod and showing how a deployment always ensures the desired number of pods is always present.

![delete pod](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x0fksgt323o997a5ynz2.png)
- Head to `azure portal => kubernetes cluster => kubernetes resources => services and ingresses` to view ports and pods.

![view service](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/led1cpmaz8x2gqsf78zx.png)
![view ports](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fzvb937ixji4ewqhlano.png)
![view pods](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s2xhml9vrd18gkmhu6n2.png)

- The app can be accessed using external IP of the service.

![Note keeper app](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dmmra8iwz6syf3vv50ez.png)

**Challenges encountered during this project**
- Creating a new azure account due to credit card issues
- I encountered the `ImagePullBackOff` and `ErrImagePull` error which was as a result of not properly connecting my azure container registry to my kubernetes cluster, this was detected while debugging .

![debug](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/33mjdqi1vfn3fb757ten.png)
- Changing my demo app from a note keeper app to a basic node app and back to my note keeper app due to `ImagePullBackOff` and `ErrImagePull` error.

**Conclusion**
This tutorial shows how to:

- Create a Docker image for a node application
- Push the image on ACR.
- Deploy on kubernetes

The End.

Thank you for reading