Skip to content

How to Set Up Let's Encrypt TLS with cert-manager in Kubernetes

DodaTech 2 min read

In this tutorial, you'll learn about How to Set Up Let's Encrypt TLS with cert. We cover key concepts, practical examples, and best practices.

The Problem

Your Kubernetes Ingress uses a self-signed certificate or no TLS at all. Browsers show NET::ERR_CERT_AUTHORITY_INVALID or Not Secure warnings. You need automated, trusted TLS certificates from Let's Encrypt.

Quick Fix

Step 1: Install cert-manager

Deploy cert-manager into your cluster:

kubectl apply -f https://github.com/cert-manager/cert-manager/releases/latest/download/cert-manager.yaml

Wait for all pods to be ready:

kubectl get pods -n cert-manager
NAME                                       READY   STATUS    RESTARTS
cert-manager-5c4b5b6d7c-abcde              1/1     Running   0
cert-manager-cainjector-6f7f8f9f8f-xyzab   1/1     Running   0
cert-manager-webhook-9c8d7e6f5-12345       1/1     Running   0

Step 2: Create a ClusterIssuer for Let's Encrypt

Define a production issuer that auto-renews certificates:

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: admin@example.com
    privateKeySecretRef:
      name: letsencrypt-prod-key
    solvers:
      - http01:
          ingress:
            class: nginx

Step 3: Create a test issuer for staging

Use the staging environment first to avoid rate limits:

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-staging
spec:
  acme:
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    email: admin@example.com
    privateKeySecretRef:
      name: letsencrypt-staging-key
    solvers:
      - http01:
          ingress:
            class: nginx

Step 4: Annotate the Ingress to request a certificate

Add TLS configuration and cert-manager annotations:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-app-ingress
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - app.example.com
      secretName: app-example-tls
  rules:
    - host: app.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: my-app-service
                port:
                  number: 80

Step 5: Verify the certificate

Check the certificate status:

kubectl get certificate
NAME               READY   SECRET             AGE
app-example-tls    True    app-example-tls    2m

If READY is False, check the CertificateRequest:

kubectl describe certificaterequest

Alternative Solutions

Use a static TLS secret instead of cert-manager

For one-off certificates, create the secret manually:

kubectl create secret tls my-tls --cert=tls.crt --key=tls.key

Use DNS-01 challenge for wildcard certificates

Wildcard certificates require DNS-01 instead of HTTP-01:

solvers:
  - dns01:
      cloudflare:
        apiTokenSecretRef:
          name: cloudflare-token
          key: api-token

Common Mistakes to Avoid

Using the staging issuer in production. Staging certificates are not trusted by browsers. Switch to the production issuer for real deployments.

Not waiting for DNS propagation. Let's Encrypt must reach your domain to validate ownership. Wait for DNS to propagate before requesting a certificate.

Hitting Let's Encrypt rate limits. The production environment limits certificates to 50 per week. Use the staging environment for testing.

Pro Tips

Monitor certificate expiry with cert-manager's status. Check kubectl get certificate -A -w to see when certificates are approaching expiry.

Use ClusterIssuer for shared issuers. A ClusterIssuer works across all namespaces, while Issuer is limited to one namespace.

Use the cert-manager approver policy for security. Approve only specific certificate requests that meet your security criteria before they are signed.

Prevention

  • Use the Let's Encrypt staging issuer first to test without hitting rate limits.
  • Ensure your domain DNS resolves to the Ingress load balancer before requesting certificates.
  • Monitor certificate expiry with kubectl get certificate and set up renewal alerts.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro