KubernetesCXIV · Certificate and TLS OperationsCertificate and TLS operations
ACME issuers — Let's Encrypt and the ACME protocol
What you'll learn
- Configure ACME issuers with Let's Encrypt
- Use http-01 and dns-01 challenge solvers
- Issue wildcard certificates
- Apply the operational discipline of ACME issuers
Prerequisites
Verified against Kubernetes 1.34.x · kubeadm 1.34.x · kubectl 1.34.x · etcd 3.6.x · CoreDNS 1.11.x · containerd 1.7.x / 2.x · 2026-08-16
ACME is the protocol for automatic certificate issuance; Let’s Encrypt is the most common public ACME server. This lesson walks the protocol, the challenge solvers, wildcards, rate limits, and the discipline.
The ACME protocol
flowchart LR
A["ACME client: cert-manager"] --> B["ACME server: Let's Encrypt"]
A -->|1. Register account| B
A -->|2. Request certificate| B
B -->|3. Challenge| A
A -->|4. Solve challenge| B
B -->|5. Verify challenge| A
A -->|6. Issue certificate| B
The ACME protocol:
- Register. The client registers with the ACME server; the server returns an account URL.
- Order. The client requests a certificate for specific domains.
- Challenge. The server returns a challenge (http-01 or dns-01).
- Solve. The client solves the challenge (proves control of the domain).
- Verify. The server verifies the challenge.
- Issue. The server issues the certificate.
Let’s Encrypt staging vs production
# Staging (for testing)
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
server: https://acme-staging-v02.api.letsencrypt.org/directory
email: ops@example.com
privateKeySecretRef:
name: letsencrypt-staging-account
solvers:
- http01:
ingress:
class: nginx
---
# Production
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
solvers:
- http01:
ingress:
class: nginx
The URLs:
- Staging.
acme-staging-v02.api.letsencrypt.org; certificates are not trusted by browsers; no rate limits. - Production.
acme-v02.api.letsencrypt.org; certificates are trusted; strict rate limits.
Challenge solvers
flowchart LR
A[Challenge solvers] --> B[http-01]
B --> B1[HTTP validation]
B --> B2[Requires Ingress]
B --> B3[Cannot do wildcard]
A --> C[dns-01]
C --> C1[DNS validation]
C --> C2[Requires DNS provider creds]
C --> C3[Can do wildcard]
Two solvers:
- http-01. ACME server requests a specific URL on port 80 of the domain. cert-manager creates an Ingress to serve the URL. Requires HTTP port 80 to reach the cluster.
- dns-01. ACME server requests a specific TXT record in the domain’s DNS. cert-manager creates the TXT record via the DNS provider’s API. Requires DNS provider credentials. Supports wildcard certificates.
A wildcard certificate
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: wildcard-example
namespace: prod-app
spec:
secretName: wildcard-example-tls
dnsNames:
- "*.example.com"
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
duration: 2160h # 90 days
The wildcard certificate covers *.example.com. The
dns-01 solver validates control of example.com.
# dns-01 solver in the ClusterIssuer
solvers:
- dns01:
route53:
region: us-east-1
accessKeyIDSecretRef:
name: aws-credentials
key: access-key-id
secretAccessKeySecretRef:
name: aws-credentials
key: secret-access-key
The Route 53 solver requires AWS credentials in a Secret.
Rate limits
flowchart LR
A[Let's Encrypt rate limits] --> B[50 certs per domain per week]
A --> C[5 duplicate certs per week]
A --> D[5 certs with same SAN set per week]
B --> E[Test with staging!]
C --> E
D --> E
The rate limits:
- 50 certificates per registered domain per week.
- 5 duplicate certificates per week.
- 5 certificates with the same set of names per week.
A misconfigured ClusterIssuer can quickly exhaust the quota. The discipline is to test with staging and to monitor the rate limit.
Quiz
Knowledge check · 4 questions
Q1. Why should a new ACME configuration be tested against Let's Encrypt staging first?
Q2. Exhausting a Let's Encrypt rate limit is resolved by creating a new ACME account.
Q3. Get a wildcard certificate issued after the ACME order stalls on the wrong challenge type.
A Certificate requests the single name *.example.com from the letsencrypt-prod ClusterIssuer, whose only configured solver is http01 with the nginx ingress class. After an hour, `kubectl get order -n prod-app` shows the order pending and `kubectl describe challenge` shows an http-01 challenge that has never been validated. Route 53 hosts the example.com zone and the team holds an IAM key for it.
Q4. What record does the dns-01 challenge create and at what name, and what are Let's Encrypt's duplicate-certificate and per-registered-domain weekly limits?
Passing score: 75%. Answers are checked in this browser.
The operational discipline
ACME issuers in production rest on five non-negotiable elements:
- Test with staging. Use Let’s Encrypt staging before production.
- Use dns-01 for wildcards. http-01 cannot do wildcards.
- Monitor rate limits. Alert on issuance errors near the limit.
- Document the solvers. Which solver is used for which certificate.
- Back up the ACME account key. The Secret stores the account key; losing it means losing the account.
ACME is production certificate management. The discipline is to test, monitor, and document.