Goal
Deploy a minimal K3s cluster to front homelab services with Gateway API, Cert-Manager (DNS-01), and Cloudflare Tunnel for safe external reachability. Use External Secrets to sync credentials without baking them into manifests.
Prereqs
- 3 small nodes (or 1-2 for lab) with 2+ vCPU, 4-8 GB RAM each.
- Cloudflare API token for DNS-01.
- Cloudflare Tunnel token or existing connector host.
Install K3s
- Install K3s with Traefik disabled (
--disable traefik). - Label nodes if you want dedicated ingress (e.g.,
edge=true). - Set up
kubectlaccess from your workstation.
Gateway API & Ingress
- Install Gateway API CRDs; deploy an ingress controller that supports it (Traefik v3 beta or Envoy Gateway).
- Create a
GatewayClassand aGatewaybound to your edge nodes. - Point Cloudflare Tunnel origin to the Gateway service; no WAN ports opened.
Certificates
- Install Cert-Manager; add Cloudflare DNS solver with scoped token.
- Issue a wildcard or per-app cert via
ClusterIssuerusing DNS-01. - Ensure Tunnel connector hostname matches DNS records you publish.
External Secrets
- Install External Secrets Operator.
- Pick a backend (1Password, Vault, SSM); store API tokens and app secrets there.
- Create
ExternalSecretobjects per namespace; mount as env/secret volumes.
Example App Route
- Deploy an app (e.g., Grafana) with Service on port 3000.
- Create
HTTPRouteforgrafana.lab.example.comto that Service. - Apply
Certificatefor the hostname; point DNS CNAME to the Tunnel.
Observability
- Enable access logs on Gateway; ship to Loki/Promtail.
- Monitor cert expiry, Tunnel status, and pod health.
- Set resource limits on ingress pods to avoid runaway memory.
Security
- Use ForwardAuth/SSO at the edge for admin paths.
- Restrict egress from the cluster; allow only DNS-01 + Tunnel endpoints.
- Rotate Cloudflare tokens; keep External Secrets backend locked down.