Skip to main content

Cert-Manager Deployment Guide

Overview​

This guide provides instructions for deploying and configuring cert-manager on TKE to automate TLS certificate management for applications.

Prerequisites​

Cluster Requirements​

  • Kubernetes cluster version 1.16+
  • Cluster-admin permissions
  • Access to certificate issuer (Let's Encrypt, internal CA, etc.)

Network Requirements​

  • Internet access for Let's Encrypt validation
  • DNS configuration for domain validation
  • Proper firewall rules for HTTP-01/HTTP-01 challenges

Installation​

Method 1: Helm Installation​

# Add jetstack helm repository
helm repo add jetstack https://charts.jetstack.io
helm repo update

# Install cert-manager
helm install cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--version v1.13.0 \
--set installCRDs=true

Method 2: kubectl Installation​

# Install Custom Resource Definitions (CRDs)
kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.13.0/cert-manager.crds.yaml

# Create namespace
kubectl create namespace cert-manager

# Install cert-manager
kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v1.13.0/cert-manager.yaml

Configuration​

Cluster Issuer Configuration​

Let's Encrypt Production​

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-private-key
solvers:
- http01:
ingress:
class: nginx

Let's Encrypt Staging​

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-private-key
solvers:
- http01:
ingress:
class: nginx

Issuer Configuration (Namespace-scoped)​

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

Certificate Management​

Basic Certificate​

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: example-com-tls
namespace: default
spec:
secretName: example-com-tls
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
commonName: example.com
dnsNames:
- example.com
- www.example.com

Wildcard Certificate​

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: wildcard-example-com-tls
namespace: default
spec:
secretName: wildcard-example-com-tls
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
commonName: "*.example.com"
dnsNames:
- "*.example.com"

Integration with Ingress​

Automatic TLS with Ingress​

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

Manual Certificate Reference​

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app-ingress
spec:
tls:
- hosts:
- example.com
secretName: example-com-tls
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-app
port:
number: 80

Challenge Solvers​

HTTP-01 Challenge​

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

DNS-01 Challenge​

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-dns01
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: admin@example.com
privateKeySecretRef:
name: letsencrypt-private-key
solvers:
- dns01:
cloudflare:
email: admin@example.com
apiKeySecretRef:
name: cloudflare-api-key
key: api-key

Monitoring and Troubleshooting​

Check Certificate Status​

# List certificates
kubectl get certificates --all-namespaces

# Describe certificate details
kubectl describe certificate example-com-tls

# Check certificate orders
kubectl get orders --all-namespaces

# Check challenges
kubectl get challenges --all-namespaces

Common Issues​

Certificate Not Issuing​

  • Check issuer status: kubectl describe clusterissuer letsencrypt-prod
  • Verify DNS configuration
  • Check challenge solver configuration

Certificate Renewal Issues​

  • Check certificate expiration
  • Verify issuer configuration
  • Monitor renewal events

Logs and Debugging​

# Check cert-manager pod logs
kubectl logs -n cert-manager -l app=cert-manager

# Check webhook logs
kubectl logs -n cert-manager -l app=webhook

# Check cainjector logs
kubectl logs -n cert-manager -l app=cainjector

Best Practices​

Security​

  • Use separate issuers for production and staging
  • Secure private keys with proper RBAC
  • Implement certificate rotation policies

Performance​

  • Monitor certificate renewal cycles
  • Use appropriate challenge types based on environment
  • Implement backup and recovery procedures

Maintenance​

  • Regularly update cert-manager to latest version
  • Monitor certificate expiration dates
  • Test certificate renewal procedures

Advanced Configurations​

Certificate Duration and Renewal​

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: long-duration-cert
spec:
secretName: long-duration-tls
duration: 2160h # 90 days
renewBefore: 360h # 15 days before expiration
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
commonName: example.com
dnsNames:
- example.com

Private CA Integration​

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: private-ca
spec:
ca:
secretName: private-ca-secret