MicroK8s is a lightweight, CNCF-conformant Kubernetes distribution from Canonical, installed as a single snap. Features such as DNS, ingress, storage, metrics and cert-manager are add-ons you enable with one command. It’s a quick way to run Kubernetes on one Ubuntu VPS, or a small multi-node cluster.
Alternatives: k3s (also lightweight) and kubeadm (upstream, more manual). Do you need Kubernetes at all? See Kubernetes vs Docker Compose.
Requirements
- Ubuntu 22.04 or 24.04 (other distributions with snapd work too).
- 2 vCPU and 4 GB RAM recommended for real workloads (it runs on less, but leaves little room for apps). See Ubuntu VPS.
- A KVM VPS (containers need kernel features unavailable in OpenVZ/LXC). See what is KVM virtualization.
Install
sudo snap install microk8s --classic --channel=1.31/stable
sudo usermod -aG microk8s $USER
mkdir -p ~/.kube && sudo chown -R $USER ~/.kube
newgrp microk8s
microk8s status --wait-ready
Choose the channel (Kubernetes version) explicitly, so upgrades are deliberate. List channels with snap info microk8s.
kubectl
MicroK8s includes kubectl:
microk8s kubectl get nodes
alias kubectl='microk8s kubectl'
# or export a kubeconfig for a standalone kubectl / tools like k9s:
microk8s config > ~/.kube/config
See kubectl cheat sheet and k9s.
Enable add-ons
microk8s enable dns # CoreDNS (needed by most apps)
microk8s enable hostpath-storage # simple PersistentVolumes on the node's disk
microk8s enable ingress # NGINX ingress controller on ports 80/443
microk8s enable cert-manager # Let's Encrypt certificates
microk8s enable metrics-server # kubectl top, HPA
microk8s enable helm3 # Helm (or install Helm separately)
microk8s status # what's enabled
Other add-ons include metallb (LoadBalancer IPs), observability (Prometheus, Grafana, Loki), registry (local image registry) and rbac. See Kubernetes ingress, cert-manager, and persistent volumes.
Deploy something
microk8s kubectl create deployment web --image=nginx:1.27
microk8s kubectl expose deployment web --port=80
microk8s kubectl get pods,svc
Then add an Ingress for your domain. See Kubernetes deployments and services.
Multi-node and high availability
On the first node:
microk8s add-node
# prints a join command, e.g. microk8s join 10.0.0.1:25000/<token>
Run the join command on each new node (same MicroK8s channel). With three or more nodes, MicroK8s automatically enables HA for its datastore (dqlite). Connect nodes over a private network or VPN, and open the required ports only between them. See WireGuard.
Firewall
Public: 80 and 443 (ingress), and SSH. Between nodes: the Kubernetes API (16443), the cluster agent (25000), kubelet (10250) and the CNI’s ports. Don’t expose 16443 publicly unless you need remote kubectl, and then restrict it by IP. See UFW.
Upgrades and removal
sudo snap refresh microk8s --channel=1.32/stable # one minor version at a time
sudo snap remove microk8s # removes everything
Snaps auto-refresh within a channel. Hold refreshes during critical periods with sudo snap refresh --hold microk8s. See snap packages.
MicroK8s vs k3s
| MicroK8s | k3s | |
|---|---|---|
| Packaging | Snap | Single binary / install script |
| Defaults | Minimal; enable add-ons | Batteries included (Traefik, ServiceLB, local-path) |
| Datastore HA | dqlite (3+ nodes) | Embedded etcd or external DB |
| Best fit | Ubuntu users, add-on convenience | Small VPS, edge, minimal footprint |
Quick reference
| Task | Command |
|---|---|
| Install | snap install microk8s --classic --channel=1.31/stable |
| Ready? | microk8s status --wait-ready |
| kubectl | microk8s kubectl … |
| Add-ons | microk8s enable dns ingress hostpath-storage cert-manager |
| Join node | microk8s add-node → microk8s join … |
| Kubeconfig | microk8s config |
Related: Helm tutorial and Kubernetes security basics.