cert-manager

Expired certificates cause some of the most avoidable outages in software. cert-manager removes the manual work: it runs in a Kubernetes cluster, requests certificates from certificate authorities such as Let's Encrypt or an internal CA, stores them as Kubernetes Secrets, and renews them well before they expire. Ingress controllers, gateways, and applications simply mount the Secret.

The model is declarative. You describe who issues certificates (an Issuer or ClusterIssuer) and what certificate you want (a Certificate), and cert-manager does the rest — including solving ACME challenges, retrying failures, and rotating keys. When something goes wrong, the chain of resources it creates explains exactly where.

TL;DR

Quick Example

A ClusterIssuer for Let's Encrypt using HTTP-01 through an NGINX ingress, and a Certificate for one hostname:

When the Certificate shows Ready=True, the Secret shop-example-com-tls holds the key and certificate chain, and cert-manager will renew it automatically.

Core Concepts

Resources

ACME Challenges

DNS-01 needs credentials for your DNS provider; scope them to the zones and records cert-manager needs.

Renewal

By default cert-manager renews a certificate when two thirds of its lifetime has passed, and renewBefore or renewBeforePercentage can change that. Certificate lifetimes across the industry are getting shorter, which makes reliable automation and monitoring more important, not less.

Ingress and Gateway Integration

Adding cert-manager.io/cluster-issuer: letsencrypt-prod to an Ingress with a tls section makes cert-manager create the Certificate automatically. Similar support exists for Gateway API listeners. Explicit Certificate resources are clearer for anything shared or important.

Monitoring

cert-manager exposes Prometheus metrics including certmanager_certificate_expiration_timestamp_seconds and certmanager_certificate_ready_status. Alert on:

Diagnosing Failed Issuance

Follow the chain of resources; each one's events and status explain the next step:

The cmctl CLI adds helpers such as cmctl status certificate and cmctl renew to force a renewal after fixing a problem.

Best Practices

Start With Staging

Point a separate ClusterIssuer at Let's Encrypt's staging directory while you set things up. Its certificates are not trusted by browsers, but its rate limits are generous.

Prefer DNS-01 for Wildcards and Internal Names

DNS-01 avoids exposing internal services to the internet and is the only ACME method that issues wildcard certificates.

Use Internal CAs for Service-to-Service TLS

For internal mutual TLS, issue from a private CA (cert-manager's CA issuer, Vault, or a cloud private CA) with short lifetimes. Public CAs are for public names. See HTTPS & TLS.

Alert on Expiry Even With Automation

Automation removes routine work, not the need to know when it breaks. The expiry alert is the safety net for every failure mode above.

Common Mistakes

Testing Against Production ACME

HTTP-01 Behind a Forced HTTPS Redirect or Wrong Ingress Class

No Expiry Monitoring

FAQ

What is cert-manager?

A Kubernetes controller that requests, stores, and renews TLS certificates automatically from issuers such as Let's Encrypt, private certificate authorities, or Vault, based on declarative Issuer and Certificate resources.

What is the difference between an Issuer and a ClusterIssuer?

An Issuer can only issue certificates in its own namespace; a ClusterIssuer can issue certificates in any namespace. Platform teams usually provide ClusterIssuers, while namespaced Issuers suit team-specific CAs.

Should I use HTTP-01 or DNS-01?

HTTP-01 for public hostnames reachable on port 80 — it needs no DNS credentials. DNS-01 for wildcard certificates, internal services, and anything not reachable from the internet.

How do I force a certificate to renew?

Fix the underlying problem first, then use cmctl renew <certificate> or trigger a reissue by updating the Certificate. Repeated forced renewals against a public CA can hit rate limits.

Why is my certificate stuck at "Issuing"?

Look at the CertificateRequest, Order, and Challenge resources in the same namespace. The Challenge's status and events usually show the exact reason, such as an unreachable challenge URL or missing DNS permissions.

Related Topics

References