TLS
TLS certificate prerequisites for Scrydon ingress
All services must be served over HTTPS. For a public hostname that reaches Traefik directly, we recommend cert-manager with Let's Encrypt for automatic certificate provisioning.
If your hostname is private-only (app.internal, something.local, or another zone that is not delegated in public DNS), Let's Encrypt cannot issue a certificate for it. Use an internal ACME CA such as step-ca, or bring your own corporate certificate. If TLS terminates at an upstream load balancer, follow TLS Offloading. See TLS Certificates for the full decision guide.
1. Install cert-manager
# Install cert-manager (if not already present)
helm repo add jetstack https://charts.jetstack.io
helm install cert-manager jetstack/cert-manager \
--namespace cert-manager --create-namespace \
--set crds.enabled=true2. Create a ClusterIssuer
The chart does not create the issuer for you. When ingress.tls.enabled: true (the default), the chart annotates its Ingress with cert-manager.io/cluster-issuer: letsencrypt-prod, but you must create a ClusterIssuer of that exact name. Without it the certificate stays stuck (READY=False, "Issuing certificate as Secret does not exist") and no ACME challenge is ever attempted.
# clusterissuer-letsencrypt-prod.yaml — apply once, after cert-manager is running
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod # MUST match ingress.tls.clusterIssuer (chart default)
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: admin@yourdomain.com # a real address — Let's Encrypt emails expiry notices here
privateKeySecretRef:
name: letsencrypt-prod-account-key # cert-manager CREATES this Secret; do not pre-create it
solvers:
- http01:
ingress:
class: traefik # must match your ingress controller classkubectl apply -f clusterissuer-letsencrypt-prod.yaml
kubectl get clusterissuer letsencrypt-prod # wait for READY=True
privateKeySecretRef.nameis not a secret you supply. cert-manager generates an ACME account key on first reconcile and stores it under that name in thecert-managernamespace. The only value you must provide is a real
Point DNS at the Traefik LoadBalancer IP before creating a production issuer. Let's Encrypt validates over HTTP-01 by fetching
http://<your-host>/.well-known/acme-challenge/..., so the hostname must resolve publicly to the ingress IP and port 80 must be reachable. Issuing against prod while DNS is wrong can trip the "5 failed validations per hostname per hour" limit. De-risk the first run with the staging server (https://acme-staging-v02.api.letsencrypt.org/directory, issuer nameletsencrypt-staging, andingress.tls.clusterIssuer: letsencrypt-staging), confirm a cert issues, then switch to prod.
If you use a different issuer name, set it in your values:
ingress:
tls:
enabled: true
clusterIssuer: my-issuer # defaults to letsencrypt-prod3. Verify issuance
kubectl get clusterissuer # No resources found here = the cause; go back to step 2
kubectl get certificate -A # the chart's cert flips to READY=True
kubectl describe challenge -A # if stuck: shows the HTTP-01 / DNS errorAlternatively, you can supply your own certificates as Kubernetes TLS Secrets, use an internal ACME issuer, or terminate TLS at a load balancer in front of the cluster. See TLS Certificates and TLS Offloading.