Running Kubernetes on a Single Node AKS: What I Learned and What I Would Not Do Again

DevOps & Cloud Engineer — building scalable, automated, and intelligent systems. Developer of sorts | Automator | Innovator
Introduction
Most Kubernetes tutorials assume a cluster with multiple worker nodes, autoscaling groups, and enough resources to run almost anything. In reality, many developers experiment with Kubernetes on very small footprints. Cloud providers make this more accessible by offering managed clusters where the control plane is handled for you.
I decided to run a single-node Azure Kubernetes Service (AKS) cluster on the Standard_D3_v2 instance type. This is a relatively modest virtual machine with:
4 vCPUs
14 GB RAM
Local SSD temporary storage
The goal was to run a few microservices, collect distributed traces with Jaeger, and expose services through an ingress.
This blog is about what worked smoothly, what struggled, and what I would do differently if I had to start again.
Why I Chose Single-Node AKS
I wanted:
A real managed control plane (no need to manage etcd, API server, certificates)
Integration with Azure networking, DNS, and private container registry
A predictable monthly cost
A minimal setup that behaves like a “real” production cluster
A single node seemed like a sweet spot between low cost and enough realism to learn.
What Works Surprisingly Well
1. Scheduling and Service Discovery
Even with one node, Kubernetes job scheduling, service networking, and DNS resolution work exactly as they would in a larger cluster. Deployments, Services, and Ingress behave normally.
2. Rolling Deployments
Rolling updates are smooth because Kubernetes manages container restart order. Even on one node, as long as resource requests are reasonable, deployments remain safe.
3. Logs and Metrics
kubectl logsworks fine.Prometheus and Grafana can run in small modes and still give useful insight.
No special tuning required here.
Where Things Get Difficult
1. Resource Pressure Comes Fast
Even a lightweight stack can push the cluster close to memory pressure. On this node size, these caused issues:
Jaeger collector + query + agent
Ingress controller
Application workloads
Once memory pressure reaches a threshold, Kubernetes starts evicting pods.
Not crashing: just quietly killing and rescheduling which leads to:
Lost traces
App downtime spikes
Confusing debugging moments
2. No Room for Spikes
In a multi-node cluster, traffic spikes are absorbed by other nodes.
In a single-node cluster, any spike is everyone’s problem.
3. Storage Is Limited and Important
If your workloads require persistence, you end up allocating Azure Disks.
Disks are reliable, but they add cost very quickly.
What I Changed to Make It Stable
1. Reduced Jaeger Footprint
I switched Jaeger from the default memory backend to Badger (a local embedded key-value store).
This significantly lowered memory usage and stopped most eviction events. I wrote about this in a previous blog, make sure to have a look!
How I Reduced Jaeger Trace Loss in a Small AKS Cluster
2. Set Realistic Resource Requests
I reviewed each deployment and tuned:
requests.cpurequests.memorylimits.memory
This prevents the scheduler from overcommitting the node.
3. Disable Autoscaling (For Now)
Horizontal Pod Autoscalers work poorly in single-node clusters because increases cannot be distributed.
I removed autoscaling and instead tuned replicas manually.
When a Single-Node AKS is a Good Choice
| Good Fit | Not a Good Fit |
| Learning Kubernetes | Production workloads |
| Demo or portfolio projects | Workloads needing horizontal scaling |
| Small internal tools | High availability systems |
| Running lightweight apps | Anything with traffic bursts |
What I Would Do Differently Next Time
If I were doing this again, I would:
Start with K3s on my home server or an inexpensive VM, to gain flexibility.
Only move to a cloud managed cluster once I needed high availability.
Use Jaeger only when I truly need tracing, not by default.
Conclusion
A single-node AKS cluster is a great way to learn real Kubernetes with minimal setup. It behaves like a complete managed cluster and is perfect for experimenting with deployments, ingress, observability, and microservice patterns.
However, it has very real limitations. Resource pressure arrives quickly, scaling is almost non-existent, and services like Jaeger require careful tuning to avoid pod evictions and instability.
If your goal is learning, this environment is excellent.
If your goal is production reliability, it is better to scale to at least two worker nodes.






