Building Your Own Home Kubernetes Cluster with k0s and Remote Access

DevOps & Cloud Engineer — building scalable, automated, and intelligent systems. Developer of sorts | Automator | Innovator
Search for a command to run...

DevOps & Cloud Engineer — building scalable, automated, and intelligent systems. Developer of sorts | Automator | Innovator
Artificial Intelligence has become one of the biggest talking points in software engineering. Every week, a new tool promises to automate deployments, fix production incidents, or replace developers a

You spin up a Kubernetes workload. You connect to PostgreSQL. You add sslmode=require because security matters. And then PostgreSQL replies with: server does not support SSL, but SSL was required Wai

When you first approach Tencent Cloud, it feels familiar if you come from AWS or Azure. There are VPCs, Kubernetes clusters, load balancers, object storage, IAM, everything you would expect. But once

When I first automated Docker builds and deployments, I thought the hard part would be writing the YAML. It was not. The real challenges were versioning, preventing accidental rollbacks, handling envi

For a long time, Docker Compose felt like the perfect solution. Simple YAML, fast local setup, predictable behavior. For a single service or even a small stack, it works beautifully. But at some point, reality catches up. As the application grew, tra...

CodeOps Studies
40 posts
Simple write-ups on day to day code or devops experiments, tests etc.
Kubernetes is the powerhouse of modern container orchestration, but setting it up at home or on minimal infrastructure can feel daunting. In this blog, I will walk you through creating a lightweight, fully functional Kubernetes cluster using k0s, complete with a control plane and a worker node, and make it accessible remotely via a Pangolin tunnel.
By the end, you will have a cluster you can experiment on from anywhere.
k0s is a lightweight, all-in-one Kubernetes distribution that simplifies the setup process:
Single binary for control plane and worker.
Minimal resource usage: ideal for home servers or VMs.
Easy to manage, yet fully compliant with Kubernetes APIs.
Perfect for learning, experimentation, or small production projects.
This makes it ideal for our goal: a home lab cluster with remote access.
The control plane is the “brain” of the Kubernetes cluster: it manages nodes, schedules workloads, and exposes the API server.
sudo apt update && sudo apt install curl -y
curl -sSLf https://get.k0s.sh | sudo bash
k0s version
Next, install the controller and start it:
sudo k0s install controller
sudo k0s start
sudo k0s status
Output example:
Version: v1.34.1+k0s.1
Role: controller
Workloads: false
SingleNode: false
This confirms the control plane is running.
To interact with Kubernetes, we need kubectl, the CLI tool.
mkdir -p ~/.kube
sudo k0s kubeconfig admin > ~/.kube/config
chmod 600 ~/.kube/config
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
kubectl get nodes
At this point, you have a single-node control plane ready.
The worker node is where your workloads (pods, deployments, services) will actually run.
sudo k0s token create --role=worker
sudo apt update && sudo apt install curl -y
curl -sSLf https://get.k0s.sh | sudo bash
nano tokenfile # paste the token from control plane
sudo k0s install worker --token-file tokenfile
sudo k0s start
sudo systemctl enable --now k0sworker
sudo journalctl -fu k0sworker
kubectl get nodes -o wide
Output:
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
ubuntu-workernode Ready <none> 20m v1.34.1+k0s 192.168.29.39 <none> Ubuntu 24.04.3 LTS 6.8.0-87-generic containerd://1.7.28
One of the most exciting parts is accessing your cluster from outside your network. For this, we will use a Pangolin tunnel to expose the control plane.
You can follow my previous blog regarding Pangolin setup:
https://blog.nyzex.in/self-hosting-pangolin-newt-on-your-own-server
#first create the kubeconfig file in the controlplane vm
sudo k0s kubeconfig admin > ~/.kube/config
chmod 600 ~/.kube/config
cat ~/.kube/config
server: field to your Pangolin hostname (after copying this config to our remote machine):clusters:
- cluster:
server: https://tunnel.nyzex.in:6443
insecure-skip-tls-verify: true
name: local
Note:
insecure-skip-tls-verify: truebypasses the TLS hostname check since our certificate is for internal names. This is fine for personal labs, but not recommended for production.
export KUBECONFIG=$(pwd)/kubeconfig
kubectl get nodes -o wide
You should see both the control plane and worker node, now accessible remotely.
Here’s a simple view of the setup:

Control Plane: API server and cluster management.
Worker Node: Runs workloads.
Remote Machine: Access via Pangolin tunnel.
For production-grade security, generate a certificate that includes your external hostname instead of skipping TLS verification.
Add more workers to scale your cluster.
Deploy your first workloads and explore Kubernetes features.
With a few steps, you now have a home Kubernetes lab:
Control plane + worker node cluster.
Remote kubectl access via Pangolin tunnel.
Fully functional, ready to deploy workloads.
This setup is perfect for experimenting with Kubernetes, testing CI/CD pipelines, or just learning cluster management hands-on.