Happy Dussehra! May good always win. Happy Diwali! Wishing you a bright year ahead. Merry Christmas! Warm wishes from Vizag. Happy New Year! Here’s to a great year ahead.

Archive · Kubernetes

MicroK8s 1.31 on Ubuntu 24.04: Install and Core Add-ons

Install a single-node MicroK8s 1.31 cluster, enable DNS, storage, ingress, metrics and RBAC, deploy a sample app, and learn upgrade and removal commands.

4 min read

  • MicroK8s 1.31
  • Kubernetes 1.31
  • Ubuntu 24.04 LTS
  • snap

MicroK8s is Canonical’s lightweight, certified Kubernetes distribution, installed as a snap. It suits labs, edge servers, CI and small production clusters. This post installs a single node and enables the add-ons most clusters need.

Versions in use on this date. MicroK8s 1.31 followed upstream Kubernetes 1.31 (released 13 August 2024) and reached the snap store on 14 August 2024. Ubuntu 24.04 LTS (Noble) has been available since April 2024. Newer tracks appear on the Kubernetes cadence, so run snap info microk8s to see which are available when you read this; this post stays on 1.31/stable.

Architecture of a single node

flowchart TB
  U[kubectl and users] -->|16443 API server| N
  subgraph N[Ubuntu 24.04 node - MicroK8s snap]
    API[kube-apiserver and controllers] --> DQ[(dqlite datastore)]
    API --> KL[kubelet and containerd]
    KL --> POD[Pods]
    ADD[Add-ons<br/>CoreDNS hostpath-storage ingress<br/>metrics-server rbac]
  end
  POD --> DISK[(hostpath storage<br/>/var/snap/microk8s/common/default-storage)]
  ING[Ingress controller ports 80 and 443] --> POD
  C[Clients] -->|HTTP and HTTPS| ING

All control-plane parts run inside the snap with dqlite as the datastore (instead of etcd), which keeps the footprint small: around 1 vCPU and 2 GB RAM is a workable minimum for the cluster itself.

Install

sudo snap install microk8s --classic --channel=1.31/stable
sudo usermod -a -G microk8s $USER
mkdir -p ~/.kube && chmod 0700 ~/.kube
newgrp microk8s
microk8s status --wait-ready
microk8s kubectl get nodes -o wide

Add an alias if you want plain kubectl: sudo snap alias microk8s.kubectl kubectl. To use an external kubectl, export the kubeconfig: microk8s config > ~/.kube/config. Open the API port (16443) only to trusted networks.

Enable the add-ons

microk8s enable dns
microk8s enable hostpath-storage
microk8s enable ingress
microk8s enable metrics-server
microk8s enable rbac
microk8s status
Add-on Purpose
dns CoreDNS, needed for service discovery (enable first)
hostpath-storage Default StorageClass using a directory on the node
ingress NGINX ingress controller, using ingress class public
metrics-server Enables kubectl top and horizontal autoscaling
rbac Turns on role-based access control; not enabled by default

Enable rbac early on any cluster other than a throwaway lab, then create users or service accounts with specific roles. hostpath-storage keeps data on a single node’s disk, which is not replicated; for important data use a replicated storage option or external storage.

Deploy a sample application

# demo.yaml
apiVersion: apps/v1
kind: Deployment
metadata: { name: web, namespace: demo }
spec:
  replicas: 2
  selector: { matchLabels: { app: web } }
  template:
    metadata: { labels: { app: web } }
    spec:
      containers:
        - name: web
          image: nginx:1.27
          ports: [{ containerPort: 80 }]
          resources:
            requests: { cpu: 50m, memory: 64Mi }
            limits: { memory: 128Mi }
          readinessProbe: { httpGet: { path: /, port: 80 } }
---
apiVersion: v1
kind: Service
metadata: { name: web, namespace: demo }
spec:
  selector: { app: web }
  ports: [{ port: 80, targetPort: 80 }]
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata: { name: web, namespace: demo }
spec:
  ingressClassName: public
  rules:
    - host: web.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend: { service: { name: web, port: { number: 80 } } }
microk8s kubectl create namespace demo
microk8s kubectl apply -f demo.yaml
microk8s kubectl -n demo get pods,svc,ingress
curl -H "Host: web.example.com" http://localhost/

Day-two commands

microk8s inspect                  # collects logs and flags problems
microk8s kubectl top nodes
snap list microk8s                # shows the installed revision and tracking channel
sudo snap refresh microk8s --channel=1.31/stable    # patch updates inside the track
microk8s disable <addon>
sudo snap remove microk8s --purge # deletes the cluster and its data

Snap refreshes can restart the cluster at unplanned times. Hold them with sudo snap refresh --hold=720h microk8s (or configure a refresh timer) and update during a maintenance window. To move to a newer Kubernetes minor version, change the channel one minor version at a time on a test cluster first, since upgrades are one-way.

Common problems

  • permission denied for kubectl: log out and in after adding yourself to the microk8s group.
  • Pods stuck in ContainerCreating behind a proxy: configure /var/snap/microk8s/current/args/containerd-env and restart.
  • Pending PVC: hostpath-storage not enabled, or no default StorageClass.
  • Port 80 unreachable: the host firewall (ufw) blocks it; allow 80, 443 and 16443 as required.