Skip to content

Cert-Manager

Cert-Manager automates the management and issuance of TLS certificates in Kubernetes clusters.

Overview

Cert-Manager is deployed as part of the infrastructure stack to provide automatic certificate provisioning and renewal for the RCIIS platform.

Configuration

Deployment Location

  • Configuration: apps/infra/cert-manager/
  • Environments: Local, Staging
  • Chart: Official cert-manager Helm chart

Values Structure

apps/infra/cert-manager/
├── local/
│   ├── values.yaml
│   └── extra/
│       └── cluster-issuer.yaml
├── staging/
│   └── values.yaml
└── extra/
    └── cluster-issuer.yaml

Certificate Issuers

Let's Encrypt (Production)

ClusterIssuer Configuration:

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

Let's Encrypt (Staging)

ClusterIssuer Configuration:

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

Self-Signed (Development)

ClusterIssuer Configuration:

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: selfsigned-issuer
spec:
  selfSigned: {}

Certificate Management

Automatic Certificate Issuance

Ingress Annotation Method:

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

Certificate Resource Method

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

DNS Challenge Support

Cloudflare DNS Challenge

Configuration:

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

Secret Management: - Cloudflare API tokens stored in apps/infra/secrets/staging/cloudflare-api-key.yaml - SOPS-encrypted for security - Automatically deployed via KSOPS

Monitoring and Troubleshooting

Certificate Status

Check Certificate Status:

# List all certificates
kubectl get certificates --all-namespaces

# Check certificate details
kubectl describe certificate <cert-name> -n <namespace>

# Check certificate issuer status
kubectl describe clusterissuer <issuer-name>

Common Issues

HTTP-01 Challenge Failures: - Verify ingress controller is running - Check DNS resolution for domain - Ensure port 80 is accessible

DNS-01 Challenge Failures: - Verify DNS provider API credentials - Check DNS propagation - Validate domain ownership

Logs and Events

Cert-Manager Logs:

# Controller logs
kubectl logs -n cert-manager deployment/cert-manager

# Webhook logs
kubectl logs -n cert-manager deployment/cert-manager-webhook

# CA Injector logs
kubectl logs -n cert-manager deployment/cert-manager-cainjector

Certificate Events:

# Check certificate events
kubectl describe certificate <cert-name> -n <namespace>

# Check challenge events
kubectl get challenges --all-namespaces
kubectl describe challenge <challenge-name> -n <namespace>

Security Considerations

Private Key Protection

  • Private keys stored as Kubernetes secrets
  • RBAC controls access to certificate secrets
  • Regular key rotation through automatic renewal

Certificate Validation

  • Domain validation through ACME challenges
  • Certificate transparency logging
  • Automated renewal before expiration

Best Practices

Certificate Lifecycle

  1. Issuance: Automatic through ingress annotations
  2. Renewal: Automatic 30 days before expiration
  3. Revocation: Manual process when needed
  4. Cleanup: Automatic removal of expired certificates

Environment-Specific Considerations

Local Development: - Use self-signed certificates - Skip certificate validation in applications - Focus on functionality over security

Staging Environment: - Use Let's Encrypt staging for testing - Validate certificate issuance process - Test automatic renewal

Production Environment: - Use Let's Encrypt production - Monitor certificate expiration - Implement certificate monitoring alerts