Cert Manager
On this page

This is the known good design for cert-manager using Helm or Argo CD.
Overview
Cert Manager Overview
cert-manager is a Kubernetes-native controller that automates issuing and renewing TLS certificates. It integrates with certificate authorities such as Let’s Encrypt (ACME), HashiCorp Vault, and private CAs, and stores the resulting certificates in Kubernetes Secrets. Rancher depends on it for Rancher-generated and Let’s Encrypt certificates.
Key Features
- Automated Certificate Renewal: Renews certificates before they expire.
- Support for Multiple Certificate Authorities: ACME, Vault, CA, and self-signed issuers, plus external issuers.
- ACME Challenge Types: HTTP-01 (through an Ingress or a Gateway API HTTPRoute) and DNS-01.
- Custom Resource Definitions (CRDs):
Certificate,Issuer,ClusterIssuer, and related resources. - Ingress and Gateway Integration: Annotate an Ingress or a Gateway with an issuer and cert-manager creates the certificate.
Supported Versions
As of October 2026, the cert-manager supported releases page lists 1.21 (released July 8, 2026) and 1.20 (March 10, 2026) as supported; 1.22 is expected around November 2026. The latest patch is v1.21.2. Older examples that pin v1.9 or v1.16 are end of life: v1.9 reached EOL on January 11, 2023 and v1.16 on June 10, 2025.

Implementation Details
Option A: Helm Installation
Step 1: Install Cert Manager
The cert-manager Helm guide recommends the OCI chart:
helm install cert-manager oci://quay.io/jetstack/charts/cert-manager \
--namespace cert-manager \
--create-namespace \
--version v1.21.2 \
--set crds.enabled=trueThe legacy repository still works and is updated a few hours after the OCI chart:
helm repo add jetstack https://charts.jetstack.io --force-update
helm install cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--version v1.21.2 \
--set crds.enabled=truecrds.enabled=true replaces the deprecated installCRDs=true. The chart also defaults crds.keep=true, which keeps the CRDs (and therefore your certificates) if the Helm release is uninstalled.
For deploying cert-manager through Argo CD, see Option B below and the Argo CD design.
For Rancher-specific guidance, see the cert-manager step in the Rancher Helm install guide.
Step 2: Verify Installation
Check if the cert-manager pods are running:
kubectl get pods -n cert-managerExpected output:
NAME READY STATUS RESTARTS AGE
cert-manager-xxxxxxx-xxxxx 1/1 Running 0 1m
cert-manager-cainjector-xxxxxxx-xxxxx 1/1 Running 0 1m
cert-manager-webhook-xxxxxxx-xxxxx 1/1 Running 0 1mStep 3: Create a ClusterIssuer
The ClusterIssuer defines the certificate authority used for issuing certificates. For Let’s Encrypt with an Ingress controller, use ingressClassName, which the cert-manager HTTP-01 docs call the recommended way to select the controller (since v1.12). The older class field is only recommended for ingress-gce.
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
solvers:
- http01:
ingress:
ingressClassName: traefikUse the IngressClass of your controller. traefik is the class on RKE2 v1.36 and later and in the Traefik designs on this site. Do not build new issuers around nginx: the Kubernetes Ingress NGINX project was retired in March 2026 (announcement).
Apply the ClusterIssuer:
kubectl apply -f cluster-issuer.yamlOptional: Gateway API
cert-manager can solve HTTP-01 challenges through a Gateway API HTTPRoute and issue certificates for Gateway listeners. Per the cert-manager Gateway docs, enable it with the config.gatewayAPI.enabled value, and install the Gateway API CRDs before cert-manager starts (restart cert-manager if you add them later):
helm upgrade --install cert-manager oci://quay.io/jetstack/charts/cert-manager \
--namespace cert-manager \
--version v1.21.2 \
--set crds.enabled=true \
--set config.gatewayAPI.enabled=trueA solver that uses an existing Gateway (it needs a listener on port 80):
solvers:
- http01:
gatewayHTTPRoute:
parentRefs:
- name: <gateway-name> # find it with: kubectl get gateway -A
namespace: <gateway-namespace>
kind: GatewayThen annotate the Gateway with cert-manager.io/cluster-issuer: letsencrypt-prod to have cert-manager create certificates for its HTTPS listeners.
Option B: ArgoCD Installation
Step 1: Install Cert Manager
To automate cert-manager deployment using Argo CD, create the following Application resource:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: cert-manager
namespace: argocd
spec:
destination:
namespace: cert-manager
server: https://kubernetes.default.svc
project: cluster-services
source:
chart: cert-manager
repoURL: https://charts.jetstack.io
targetRevision: v1.21.2
helm:
valuesObject:
crds:
enabled: true
keep: true
prometheus:
enabled: true
servicemonitor:
enabled: true
dns01RecursiveNameservers: "1.1.1.1:53,8.8.8.8:53"
dns01RecursiveNameserversOnly: true
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=trueNotes on these values (all from the v1.21.2 chart values.yaml):
prometheus.servicemonitor.enabledis lowercaseservicemonitor. It creates a ServiceMonitor and requires the Prometheus Operator CRDs. The ServiceMonitor is created in the cert-manager namespace unless you setprometheus.servicemonitor.namespace.dns01RecursiveNameserversis the chart value for the DNS-01 self-check nameservers. It replaces passing--dns01-recursive-nameserversthroughextraArgs.- The
ServerSideApplyfeature gate is alpha and off by default in v1.21, so it is not set here.
Apply this configuration to Argo CD:
kubectl apply -f cert-manager-argocd.yamlMonitoring and Troubleshooting
Monitoring Certificates
cert-manager exposes Prometheus metrics, including certificate expiry timestamps. With the Prometheus Operator installed, let the chart create the ServiceMonitor (prometheus.servicemonitor.enabled=true) rather than writing one by hand; the chart sets the correct selector and port. Alert on certmanager_certificate_expiration_timestamp_seconds approaching the current time and on certmanager_certificate_ready_status{condition="False"}.
Common Issues
- Challenge Validation Failure: Check that DNS points at your load balancer, that port 80 is reachable from the internet for HTTP-01, and that the solver’s
ingressClassName(or GatewayparentRefs) matches a controller that is actually running.kubectl describe challenge -Ashows the reason. - Rate Limits: Use the Let’s Encrypt staging server (
https://acme-staging-v02.api.letsencrypt.org/directory) while testing.
Considerations
- High Availability: The chart runs one replica of each component by default. For more, raise
replicaCount,webhook.replicaCount, andcainjector.replicaCount, and enable the matchingpodDisruptionBudget.enabledvalues, as the chart comments advise. - Namespace Scope: Use
Issuerfor certificates within a namespace andClusterIssuerfor cluster-wide certificates. - Backup Certificates: Back up the ACME account key Secret and important certificate Secrets so a restore does not trigger mass reissuance and rate limits.
- Upgrades: Only the two most recent minor releases receive fixes, so plan to upgrade at least every few months and read the release notes first.