Skip to content

Verify the install

Run these from inside the tooling container: task docker:exec.

Cluster

kubectl get nodes -o wide

Every node Ready, every node on the same version, and worker architectures as expected.

kubectl get pods -A --field-selector=status.phase!=Running

Should be empty, or only Completed jobs.

Networking

cilium status                          # kubeadm path only
kubectl get svc -A --field-selector spec.type=LoadBalancer

Every LoadBalancer service must have an EXTERNAL-IP. A <pending> here means MetalLB is missing or has no free address in its pool. See localhost_post_setup. Nothing in the platform is reachable until this is resolved.

Storage

kubectl get storageclass
kubectl get pvc -A

Longhorn should be the default StorageClass, and no PVC should be stuck Pending.

Metrics

kubectl top nodes

An error here means metrics-server did not install. Horizontal pod autoscaling and the Grafana node dashboards both depend on it.

Certificates

kubectl get certificate -A

Every certificate READY=True. A stuck certificate is usually DNS: the HTTP-01 challenge needs the name to resolve to your ingress from outside.

kubectl describe certificaterequest -A | tail -40

Web UIs

Each is behind OAuth2 Proxy and Auth0, at service.domain.local:

Service Module
Grafana monitoring
ArgoCD argocd
GitLab gitlab-platform
Longhorn longhorn-storage
MinIO minio-object-storage
Kibana logging
Kubecost monitoring-kubecost

A TLS warning means the certificate is not issued yet. A 500 from the proxy usually means the Auth0 callback URL does not match the ingress hostname.

The version convergence contract

Play 5 of the playbook already asserted this, but to check it yourself:

kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.nodeInfo.kubeletVersion}{"\n"}{end}'

Every kubelet on the version pinned in stage1/inventories/inventory.yml. See Version pins.

If something is wrong