Configuring Ingress and TLS Certificates with Traefik and Cert-Manager
Cloudflare API Token
You must give cert-manager permission to edit your DNS records.
-
Go to the Cloudflare Dashboard.
-
Create Token -> Use the Edit zone DNS template.
-
Permissions: *
Zone->DNS->Edit-
Zone->Zone->Read
-
-
Zone Resources:
Include->Specific zone->penguincave.link. -
Copy the Token (e.g.,
zXy...).
Install Traefik
We will use Helm to install Traefik. We'll manually assign your Kube-Vip IP so it remains static.
# Add the Traefik repo
helm repo add traefik https://traefik.github.io/charts
helm repo update
# Create a namespace for networking
kubectl create namespace traefik
# Delete if there's an existing config
# Install Traefik
# Replace 192.168.1.50 with your actual Kube-Vip IP
kubectl delete ingressclass traefik --ignore-not-found=true
helm install traefik traefik/traefik \
--namespace traefik \
--create-namespace \
--set deployment.replicas=2 \
--set service.type=LoadBalancer \
--set "service.annotations.kube-vip\\.io/loadbalancerIPs=192.168.100.101" \
--set "ports.web.redirections.entryPoint.to=websecure" \
--set "ports.web.redirections.entryPoint.scheme=https" \
--set "ports.web.redirections.entryPoint.permanent=true"
-
What this does: It sets up two Traefik pods for HA and tells Kube-Vip to bind them to your specific IP. It also forces all HTTP traffic to jump to HTTPS automatically.
Deploy Support Tools (Cert-Manager & Reflector)
We need the "Secretary" to manage the certs and the "Mirror" to share them.
# 1. Install Cert-Manager
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.0/cert-manager.yaml
# 2. Install Reflector via OCI registry (standard for new versions)
helm upgrade --install reflector oci://ghcr.io/emberstack/helm-charts/reflector \
--namespace kube-system
Phase 3: Cloudflare DNS-01 Setup
This part connects your Cloudflare API to the cluster and requests the certificate.
1. Create the API Token Secret
kubectl create secret generic cloudflare-api-token-secret \
-n cert-manager \
--from-literal=api-token=YOUR_ACTUAL_CLOUDFLARE_TOKEN
2. Create the ClusterIssuer (issuer.yaml): Note: Use a real email address to avoid ACME registration errors.
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-cloudflare
spec:
acme:
email: your-real-email@gmail.com
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-cloudflare-account-key
solvers:
- dns01:
cloudflare:
apiTokenSecretRef:
name: cloudflare-api-token-secret
key: api-token
Phase 4: The Wildcard Certificate
This creates the master certificate in the traefik namespace. Reflector then mirrors it cluster-wide.
Create wildcard-cert.yaml:
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: homelab-wildcard
namespace: traefik
spec:
secretName: homelab-wildcard-tls
issuerRef:
name: letsencrypt-cloudflare
kind: ClusterIssuer
dnsNames:
- "*.homelab.penguincave.link"
secretTemplate:
annotations:
reflector.v1.k8s.emberstack.com/reflection-allowed: "true"
reflector.v1.k8s.emberstack.com/reflection-auto-enabled: "true"
Phase 5: High Availability Test (NGINX)
This ensures 3 replicas are spread across your 3 master nodes using Pod Anti-Affinity.
Create nginx-ha.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-ha
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values: ["nginx"]
topologyKey: "kubernetes.io/hostname"
containers:
- name: nginx
image: nginx:latest
---
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
selector:
app: nginx
ports:
- port: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: nginx-ingress
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
spec:
ingressClassName: traefik
tls:
- hosts: ["nginx.homelab.penguincave.link"]
secretName: homelab-wildcard-tls
rules:
- host: nginx.homelab.penguincave.link
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-svc
port:
number: 80
Troubleshooting Commands
-
Check Cert Status:
kubectl get cert -n traefik -
Check DNS Challenge:
kubectl describe challenge -n traefik -
Check Secret Mirroring:
kubectl get secret homelab-wildcard-tls -n longhorn-system -
Check Pod Distribution:
kubectl get pods -o wide
Would you like me to create a single bash script that automates these installations for future node resets?