say.farewell.cloud admin

K8s Learning: Step 04 — Install cert-manager

04 — Install cert-manager

Script: 04_install_cert_manager.sh · Automatic TLS certificates

Installs cert-manager and configures it with a Let's Encrypt ClusterIssuer. After this, any Ingress you create can get automatic HTTPS by adding a single annotation.

Required environment variable:

  • K3S_EMAIL_ADDRESS_FOR_EXPIRY_NOTICE — Let's Encrypt expiry notification email

1. Install cert-manager

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

Downloads the manifest and creates everything: a cert-manager namespace, three Deployments (controller, webhook, cainjector), Custom Resource Definitions (CRDs), and RBAC permissions.


2. Wait for readiness

kubectl -n cert-manager rollout status deployment cert-manager
kubectl -n cert-manager rollout status deployment cert-manager-webhook
kubectl -n cert-manager rollout status deployment cert-manager-cainjector

rollout status blocks until a Deployment is fully running. The three components:

  • cert-manager — main controller, talks to Let's Encrypt
  • webhook — validates your configs before accepting them
  • cainjector — injects CA certs into webhook configurations

3. Create the ClusterIssuer

sed "s/{{EMAIL_ADDRESS}}/$K3S_EMAIL_ADDRESS_FOR_EXPIRY_NOTICE/" \
  cluster-issuer.yaml | kubectl apply -f -

The ClusterIssuer YAML:

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: you@example.com
    privateKeySecretRef:
      name: letsencrypt-prod-key
    solvers:
      - http01:
          ingress:
            class: traefik
  • ClusterIssuer (vs Issuer) — works across all namespaces
  • acme.server — Let's Encrypt production endpoint
  • privateKeySecretRef — where the ACME account key is stored
  • solvers: http01 — proves domain ownership via HTTP challenge
  • ingress.class: traefik — uses Traefik for challenge routing

The HTTP-01 Challenge Flow

Certificate flow

4. Verify the ClusterIssuer

kubectl get clusterissuer letsencrypt-prod \
  -o jsonpath='{.status.conditions[?(@.type=="Ready")].status}'

If it returns True, cert-manager is fully operational.

💡 One-time setup: cert-manager is infrastructure — install once per cluster. Every subsequent app just needs the right annotation on its Ingress.
← Back to homepage