NatronTech Logo
Networking

Cert-Manager & Certificates

Stage
Experimental
Requires

Cluster Issuer

Configuration and usage of ClusterIssuers for TLS certificates.

What is a ClusterIssuer?

A ClusterIssuer is a resource in Kubernetes provided by cert-manager that represents a certificate authority (CA) capable of generating signed certificates. Unlike a regular Issuer, which is namespaced, a ClusterIssuer can be referenced by resources in any namespace. This is perfect for setting up a single "Let's Encrypt" account for the entire cluster to secure your Ingresses with HTTPS.

Official cert-manager Documentation

Quick Start (HTTP-01)

The simplest way to get valid TLS certificates is using the ACME HTTP-01 challenge. This method works for any public domain pointing to your Ingress Controller's LoadBalancer IP.

1. Create the ClusterIssuer

Create a file named cluster-issuer.yaml:

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

2. Configure your Ingress

Add the following annotation to your Ingress resource to request a certificate:

metadata:
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  tls:
  - hosts:
    - example.com
    secretName: example-com-tls

Challenge Types: HTTP-01 vs DNS-01

FeatureHTTP-01DNS-01
ComplexityLowMedium
RequirementsPublicly accessible HTTP port 80API access to DNS Provider
Wildcards (*.example.com)NoYes
Internal SitesNo (must be public)Yes (can be private IP)

Use HTTP-01 for most standard public websites. Use DNS-01 if you need Wildcard certificates or want to secure internal services that are not reachable from the public internet.

DNS Providers (Cloudflare)

To use DNS-01 challenges (required for Wildcards), you need to provide cert-manager with credentials to your DNS provider.

1. Create API Token Secret

Create a Kubernetes Secret containing your Cloudflare API Token:

apiVersion: v1
kind: Secret
metadata:
  name: cloudflare-api-token
  namespace: cert-manager
type: Opaque
stringData:
  api-token: <YOUR_CLOUDFLARE_API_TOKEN>

2. Configure ClusterIssuer for Cloudflare

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

Wildcard Certificates

Wildcard certificates (e.g., *.example.com) allow you to secure app1.example.com, app2.example.com, etc., with a single certificate.

Requirements:

  • You MUST use the DNS-01 challenge type.
  • Your Ingress structure remains the same, but the host is a wildcard:
spec:
  tls:
  - hosts:
    - "*.example.com"
    secretName: wildcard-example-com-tls

Production vs Staging

Let's Encrypt has strict rate limits on their production environment (e.g., 50 certificates per week).

Always use the Staging environment while testing!

Staging ClusterIssuer

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-staging
spec:
  acme:
    # Staging URL
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    email: info@natron.io
    privateKeySecretRef:
      name: letsencrypt-staging
    solvers:
    - http01:
        ingress:
          class: nginx

Staging certificates are not trusted by browsers (you will see a warning), but they verify that your configuration works without burning through your production rate limits.

Best Practices

We recommend the following settings for your Ingress resources to ensure high security hardening:

  • Key Algorithm: Use ECDSA instead of RSA for better performance and security.
  • Rotation: Set rotation policy to Always.

See Ingress NGINX for specific annotation examples.

On this page