MicroK8s reference cluster
Bring up a generic MicroK8s cluster ready to receive a Dibbla install.
MicroK8s is Canonical’s snap-based Kubernetes distribution. It’s a good fit when you’re already on Ubuntu and want addon-managed components (ingress, DNS, storage, cert-manager) without writing manifests.
This page is the cluster bootstrap. Once you’re done, continue to Install with Helm.
Sizing
Same numbers as the k3s page — the underlying Dibbla footprint is identical.
Install MicroK8s
On a clean Ubuntu host:
sudo snap install microk8s --classic
sudo usermod -a -G microk8s $USER
newgrp microk8s
microk8s status --wait-ready
To use kubectl directly:
microk8s config > ~/.kube/config-microk8s
export KUBECONFIG=~/.kube/config-microk8s
kubectl get nodes
(Or use microk8s kubectl … for everything — it works the same.)
Enable required addons
microk8s enable dns
microk8s enable hostpath-storage
microk8s enable ingress
microk8s enable cert-manager
What each one does:
- dns — CoreDNS. Required for in-cluster service discovery.
- hostpath-storage — provides a
microk8s-hostpathStorageClass for PVCs (PostgreSQL, container registry). - ingress — installs the upstream nginx-ingress controller. The ingress class name is
publicon recent MicroK8s; check withkubectl get ingressclass. - cert-manager — installs cert-manager. You’ll still need to create a
ClusterIssuer— see the Helm install page.
Multi-node
On the first node:
microk8s add-node
This prints a microk8s join … command. Run that command on each additional node.
Verify from the first node:
microk8s kubectl get nodes
DNS
Point a wildcard A record at the IP of the node running the ingress controller:
*.example.com. IN A <your-node-ip>
example.com. IN A <your-node-ip>
Helm values overrides for MicroK8s
When you reach the Helm install, set the ingress class to whatever kubectl get ingressclass reports (typically public):
api-gateway:
ingress:
type: standard
className: public
deploy-api:
ingressClass: public
Quirks worth knowing
- AppArmor confinement. MicroK8s confines workloads via AppArmor. BuildKit runs as a privileged container; if it fails to start, check the BuildKit pod’s events for AppArmor denials and follow the upstream MicroK8s privileged-pod docs to relax the profile or run BuildKit on a node where it’s permitted.
- Snap upgrades.
snap refresh microk8swill upgrade Kubernetes versions, occasionally with breaking changes. Pin the snap channel (--channel=1.30/stable) for predictability.
First-install gotchas
Two failure modes that hit fresh MicroK8s installs even with everything else configured correctly. The chart ships a values-microk8s.yaml overlay that sidesteps both.
Kubelet ↔ containerd image pull. Even with a correct kubernetes.io/dockerconfigjson Secret on the pod, MicroK8s’ kubelet sometimes 403s on private GHCR packages while a direct microk8s ctr image pull --user user:pat … succeeds with the exact same credentials. Workaround: pre-pull the platform images into containerd’s k8s.io namespace and switch imagePullPolicy: IfNotPresent so kubelet uses the local cache:
GH_USER=<your-github-username>
GH_PAT=<your-ghcr-pat>
for img in api-gateway:<sha> auth-service:<sha> deploy-api:<sha> \
workflow-server:<sha> go-toolserver:<sha> feedback-service:<sha>; do
sudo microk8s ctr -n k8s.io image pull \
--user "$GH_USER:$GH_PAT" "ghcr.io/dibbla-agents/$img"
done
storageClass: "" doesn’t fall through. The bundled MinIO and Loki charts default persistence.storageClass: "", which Kubernetes treats as “no class — bind nothing” rather than “use the cluster default”. Set them explicitly to microk8s-hostpath (the chart’s values-microk8s.yaml does this for you). The local Postgres + Redis subcharts handle this correctly and don’t need the override.
Both are handled by the values-microk8s.yaml overlay shipped at charts/dibbla/values-microk8s.yaml in the chart repo — use it as a starting point or copy the relevant blocks into your own values file. See the chart’s README for the full long-form workaround.
Next
Continue to Install with Helm to deploy the platform onto your new cluster.