Skip to content

Prerequisites

Before going any further it’s worth being honest about what this guide assumes is already in place. I built this on top of an existing setup, and some of the “prerequisites” are really just the previous guide’s outputs.

  • A running K3s cluster (single-node or HA, both fine).
  • Traefik present as the Ingress controller. K3s ships it by default, which is half of why I picked K3s.
  • Argo CD installed and pointed at this repo’s src/manifests/ainur tree. It’s the thing that actually deploys Dex, Headlamp and the cert portal.

If you followed Multiple Nodes & Leader election you already have all three.

Internal hostnames need to resolve to the cluster Ingress. I run this on a flat home LAN with dnsmasq on the router pointing the kidd.network zone at my K3s node IPs. The names this guide cares about:

HostServed by
dex.kidd.networkDex
headlamp.kidd.networkHeadlamp
argocd.kidd.networkArgo CD
cert.kidd.networkCA download portal (optional)

These get installed automatically by k3s’ HelmChart controller via staged manifests from cloud-init:

You don’t have to apply these by hand. The cloud-init flow stages them into /etc/k3s-manifests/ and k3s’ HelmChart controller picks them up on boot.

There’s one thing that’s not in the repo: the Root CA key itself. gen-lab-certs.sh (user-data:232-302) generates it once on the node and then materialises it as a Kubernetes Secret:

Terminal window
# excerpt from gen-lab-certs.sh
CA_CRT=/etc/rancher/k3s/oidc/lab-ca.crt
CA_KEY=/etc/k3s-certs/lab-ca.key
if [ ! -s "$CA_CRT" ] || [ ! -s "$CA_KEY" ]; then
openssl genrsa -out "$CA_KEY" 4096
openssl req -x509 -new -nodes -key "$CA_KEY" -sha256 -days 3650 \
-subj "/CN=Lab Root CA" -addext "basicConstraints=critical,CA:true" -out "$CA_CRT"
fi
# bind it into the cluster as cert-manager/cluster-root-ca
kubectl -n cert-manager create secret tls cluster-root-ca \
--cert="$CA_CRT" --key="$CA_KEY" -o yaml --dry-run=client | kubectl apply -f -

The key never leaves the node. The Secret it produces is what the rest of the guide refers to as cert-manager/cluster-root-ca — you don’t create it manually, it’s just present.

  • kubectl admin access via /etc/rancher/k3s/k3s.yaml.
  • A browser to test OIDC flows.
  • An honest assessment of whether you trust the certs that are about to start showing up in your browser’s history. If you mean to run any of this outside the LAN, ACME is a saner story than a local CA.

Configuring cert-manager for a Self-Signed CA breaks down what those staged manifests actually do, in plain English, so the next time something breaks you know which knob to turn.