Kubernetes cert-manager doesn’t just automate TLS certificates; it fundamentally changes how you think about certificate lifecycle management from a distributed systems perspective.

Let’s see cert-manager in action. Imagine you have a Kubernetes deployment for a web application, and you want it to be accessible via https://myapp.example.com.

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: myapp-tls
  namespace: default
spec:
  secretName: myapp-tls-secret # This is where the certificate will be stored
  dnsNames:
  - myapp.example.com
  issuerRef:
    name: letsencrypt-prod # This references an Issuer resource
    kind: Issuer

When you apply this Certificate resource, cert-manager takes over. It sees the dnsNames and the issuerRef. It then communicates with the specified Issuer (in this case, a Let’s Encrypt production issuer). If the issuer is configured to use the ACME protocol, cert-manager will initiate a challenge with Let’s Encrypt to prove you control myapp.example.com. Once validated, Let’s Encrypt issues a certificate, which cert-manager then stores in the myapp-tls-secret Kubernetes Secret. Your Ingress controller or application can then mount this secret to serve TLS traffic.

The core problem cert-manager solves is the manual, error-prone, and time-consuming process of obtaining, renewing, and distributing TLS certificates. Before cert-manager, this often involved:

  1. Manually generating a Certificate Signing Request (CSR).
  2. Submitting the CSR to a Certificate Authority (CA) like Let’s Encrypt.
  3. Completing domain validation (e.g., HTTP-01 or DNS-01 challenges).
  4. Downloading the issued certificate and private key.
  5. Creating a Kubernetes Secret with these files.
  6. Updating Ingress resources to point to the new secret.
  7. Manually renewing certificates before they expire and repeating the entire process.

cert-manager automates all of this. It acts as a Kubernetes controller, constantly watching for Certificate resources. When it finds one, it orchestrates the ACME flow. For HTTP-01 challenges, it typically spins up a temporary Pod that responds to Let’s Encrypt’s requests on port 80. For DNS-01 challenges, it configures your DNS provider (via a ClusterIssuer or Issuer configured with a specific provider) to add a TXT record that Let’s Encrypt can query.

The Issuer and ClusterIssuer resources are key to configuring how cert-manager interacts with CAs. An Issuer is namespaced, while a ClusterIssuer is cluster-wide.

Here’s an example of a ClusterIssuer for Let’s Encrypt’s production ACME endpoint:

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: your-email@example.com
    privateKeySecretRef:
      name: letsencrypt-prod-private-key # Stores cert-manager's ACME account private key
    solvers:
    - http01:
        ingress: nginx # Or your specific ingress controller
      selector: {} # Apply to all Ingresses that don't have a specific issuer selector

The email field is crucial; it’s used by Let’s Encrypt for important notifications, including expiry warnings. The privateKeySecretRef stores the ACME account key for cert-manager itself, allowing it to identify itself to the ACME server across multiple certificate requests. The solvers section defines how challenges should be attempted. Here, http01 is configured, instructing cert-manager to use the Ingress controller for validation.

cert-manager also handles renewals automatically. It checks the expiration date of certificates it manages and initiates the renewal process well in advance of expiry, ensuring minimal disruption. If a renewal fails, cert-manager will continue to retry and update its status, providing visibility into any ongoing issues.

The most surprising aspect of cert-manager’s internal workings is how it manages the ACME account key. When you create an Issuer or ClusterIssuer with spec.acme.privateKeySecretRef, cert-manager doesn’t just store your ACME account private key there; it generates a new, unique private key for your ACME account if one doesn’t exist. This key is essential for identifying your account to the ACME server. If you were to delete this secret, cert-manager would create a new ACME account the next time it needed to interact with the CA, which could lead to rate limit issues with Let’s Encrypt and a new account registration.

Once your certificates are managed by cert-manager, you’ll likely want to explore how to integrate them seamlessly with your Ingress resources for automatic routing and TLS termination.

Want structured learning?

Take the full Kubernetes course →