Kort svar
cert-manager er en Kubernetes-controller der automatiserer TLS-certifikater. Du definerer en Issuer (eller ClusterIssuer) der ved hvordan certifikater udstedes — typisk via ACME mod Let's Encrypt — og en Certificate-ressource der beskriver hvilke domæner du vil dække. cert-manager udsteder certifikatet, gemmer det i en Kubernetes-Secret, og fornyer det automatisk før udløb.
De fire ressourcetyper
- Issuer — udsteder certifikater i ét namespace.
- ClusterIssuer — som Issuer, men gælder hele clusteret. Vælg denne hvis flere namespaces skal dele samme ACME-konto.
- Certificate — din ønskede tilstand: hvilke
dnsNames, hvilken issuer, og navnet på den Secret resultatet skal lægges i. - Secret — den genererede TLS-secret (
tls.crt+tls.key) som dine ingress og pods bruger.
1. ClusterIssuer med ACME HTTP-01
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: ops@example.com
privateKeySecretRef:
name: letsencrypt-prod-account-key
solvers:
- http01:
ingress:
class: nginx
HTTP-01-solveren får cert-manager til midlertidigt at oprette en pod og en ingress-rute for /.well-known/acme-challenge/…, så Let's Encrypt kan validere domænet. Det kræver at clusteret er offentligt tilgængeligt på port 80.
2. Certificate-ressourcen
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: example-tls
namespace: web
spec:
secretName: example-tls
duration: 2160h # 90 dage
renewBefore: 360h # forny 15 dage før udløb
dnsNames:
- example.com
- www.example.com
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
Når du applyer denne, opretter cert-manager en CertificateRequest, kører challenge'en, og skriver resultatet til Secret'en example-tls. renewBefore styrer hvornår fornyelsen sker.
3. Wildcard kræver DNS-01
HTTP-01 kan ikke udstede wildcards. Til *.example.com bruger du en DNS-01-solver, fx via Cloudflare:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-dns
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: ops@example.com
privateKeySecretRef:
name: letsencrypt-dns-account-key
solvers:
- dns01:
cloudflare:
apiTokenSecretRef:
name: cloudflare-api-token
key: api-token
cert-manager opretter selv _acme-challenge TXT-recorden via DNS-udbyderens API og rydder op igen bagefter.
Brug certifikatet i en Ingress
Du kan også lade cert-manager udstede automatisk ud fra en annotation på en Ingress — så behøver du ikke skrive Certificate-ressourcen selv:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web
namespace: web
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
tls:
- hosts: [example.com, www.example.com]
secretName: example-tls
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web
port:
number: 80
Fejlfinding: hvorfor er certifikatet ikke Ready?
Følg kæden Certificate → CertificateRequest → Order → Challenge:
kubectl describe certificate example-tls -n web kubectl get challenges -A kubectl describe order -n web
De typiske årsager er en blokeret HTTP-01-rute, en forkert DNS-token, eller at man har ramt Let's Encrypts rate limits ved at teste mod prod i stedet for staging-serveren. Se også ACME-pillaren for challenge-typerne og mTLS i Kubernetes hvis du udsteder klientcertifikater til services.
cert-manager automatiserer — men ser ikke clusteret udefra
cert-manager ved at en Secret blev fornyet, men ikke om certifikatet faktisk serveres korrekt til omverdenen — om kæden er komplet, om en gammel ingress stadig peger på en udløbet Secret, eller om en app der cachede certifikatet ved opstart skal have en rullende genstart, eller om et endpoint helt uden for clusteret er blevet glemt. CertControl scanner alle jeres endpoints udefra og samler dem ét sted, så cert-manager-styrede og ikke-automatiserede certifikater fanges af samme overvågning.
Ofte stillede spørgsmål
Hvad er forskellen på Issuer og ClusterIssuer?
En Issuer udsteder kun certifikater i sit eget namespace. En ClusterIssuer er cluster-bred og kan bruges fra alle namespaces. Vælg ClusterIssuer hvis flere namespaces skal dele samme ACME-konto.
Hvor ender certifikatet?
I en Kubernetes-Secret af typen kubernetes.io/tls med felterne tls.crt og tls.key. Dine ingress og pods refererer til den Secret via secretName.
Kan cert-manager lave wildcard-certifikater?
Ja, men kun med en DNS-01-solver, fordi wildcard kræver DNS-validering. HTTP-01 kan ikke udstede wildcards.
Hvordan fejlfinder jeg et certifikat der hænger i 'not ready'?
Følg kæden med kubectl describe på Certificate, derefter CertificateRequest, Order og Challenge. Beskederne dér peger oftest på en blokeret challenge-rute, et forkert DNS-token eller en ramt rate limit.
Hvordan undgår jeg Let's Encrypts rate limits under test?
Brug Let's Encrypts staging-server (acme-staging-v02) i en separat ClusterIssuer mens du tester. Staging har langt højere limits, og certifikaterne er ikke betroet — perfekt til at validere opsætningen.