I’ve been searching for a better solution to monitor our on-prem applications. I know these apps do their job just fine but I don’t like the way they stop working without my acknowledgement. One day a message came from the sales team asking “hey I won a quote but I didn’t see it in Navision”. I then had a look in the server and realized that the service somehow stopped working. So I restarted the service and it went back to normal. This is just a simple example of how we manage our apps manually. I’d like to have them automated. It’s time to enter Kubernetes.
In general, these are the types of applications I often build:
- Web apps/APIs – stateless, trigger based on user requests
- Web jobs – can be stateful/stateless, stateful if it’s hosted in a Windows service, stateless if it is an Azure function
- Windows services – background/endless running apps
- SSIS packages – stateless, mostly triggered by agents
A brief introduction
Kubernetes, to put it simply, looks similar to virtualization architecture. It works around clusters and nodes. A cluster in Kubernetes is like a type 1 hypervisor (eg. hyper-v, esxi), and a node is similar to our physical PC or VM. In fact a node can be a physical or virtual machine in Kubernetes.
Kubernetes is an orchestrator so it manages our nodes. The level of workload determines the number of nodes required to make it efficient. You can have a VM in Azure just as little as 1 core, 1 GB memory or a raspberry pi device if running on on-prem.
Kubernetes can run locally or on the cloud. If Azure didn’t exist, we could even run Kubernetes across all of our raspberry pi devices.
Pods are individual components that live in a node. Pods can live and die but Kubenetes ensures their instance is not destroyed. Say we deploy a containerized app to a node with a replica = 1, this simply means that we only want 1 pod to run this app. If this pod somehow dies, Kubernetes will make sure another copy of this pod is created and running, trashing out the death pod.
A pod can have many containers(either Linux or windows) that can talk to each other. Pods can run continuously or by schedule. Fire-forget apps like web apps/web jobs/functions can be hosted in a scheduled pod, while long-running tasks like windows services or ssis packages can run in a continuous pod.
Let’s say we want to have a sync job that’s triggered at 9 AM every day and it runs for about 2 hours. In this case, it’s suitable to use a scheduled pod. When the execution is completed, that pod then goes to sleep. This is great for optimizing resource consumption since pay-as-you go subscription in Azure bills on resource usage, (eg.how much CPU/RAM did it use to run that job).
Taken from the Microsoft docs:
Only pay for the virtual machines instances, storage and networking resources consumed by your Kubernetes cluster.
You may ask why not use Azure functions or web jobs for this kind of scheduled task? Azure functions execution time is limited to 5 mins. Web jobs in Azure are usually hosted inside a web app. If it is a free one then you have to wake it up first before it can execute. If it’s not free (with always-on enabled), then you have to pay for an extra. The standard plan costs around $80/month.
I spent quite a bit of time in the last few days doing networking in Azure. My goal is to let our Azure apps have access to our on-prem resources. This was solved by using Azure virtual network. Nodes and pods in AKS have their own IP address. The way their IP gets assigned is dependent on the way we configure, sub-netting was part of it. I was able to use one IP from the existing Azure VNet (the one that connects to on-prem) for the whole cluster components (eg.nodes, pods, controllers).
At the moment, I am running a cluster with only one node within it in Azure but if the workload increases, I can scale it up as needed. It is more likely to have scheduled or fire-forget apps running in this cluster so we’re billed at the resources the cluster use to run these tasks.