Skip to content

TLS Termination

TLS Termination and Certificate Management

In Kubernetes, TLS termination at the ingress layer offloads cryptographic operations from application servers, simplifying backend architecture. This section explains how to configure TLS termination using Ingress resources and automate certificate management with tools like Cert-Manager.


Configuring TLS Termination with Ingress

To enable TLS termination, define an Ingress resource with a tls block. This specifies the certificate secret and the hosts it protects. The certificate must be stored in a Kubernetes secret in PEM format.

Example: Ingress with TLS

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  tls:
  - secretName: example-tls-secret
    hosts:
    - www.example.com
    - api.example.com
  rules:
  - http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: example-service
            port:
              number: 80

Key requirements: - The secret must contain both the certificate (tls.crt) and private key (tls.key). - The hosts field must match the domain names in the certificate. - The Ingress controller must support TLS termination (e.g., NGINX Ingress Controller).


Automating Certificate Management with Cert-Manager

Cert-Manager automates certificate issuance and renewal via the ACME protocol (e.g., Let's Encrypt). It integrates with Ingress resources to manage secrets dynamically.

Step-by-Step Setup

  1. Install Cert-Manager
    Deploy the controller using Helm or Kubernetes manifests. Example:

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

  2. Create an Issuer
    Define an Issuer for ACME validation. For Let's Encrypt:

    apiVersion: cert-manager.io/v1
    kind: Issuer
    metadata:
      name: letsencrypt-prod
    spec:
      acme:
        server: https://acme-v02.api.letsencrypt.org/directory
        email: [email protected]
        privateKeySecretRef:
          name: letsencrypt-prod-private-key
        solvers:
        - http01:
            ingress:
              ingressClass: nginx
    

  3. Request a Certificate
    Create a Certificate resource referencing the Issuer:

    apiVersion: cert-manager.io/v1
    kind: Certificate
    metadata:
      name: example-certificate
    spec:
      secretName: example-tls-secret
      issuerRef:
        name: letsencrypt-prod
      dnsNames:
      - www.example.com
      - api.example.com
      privateKey: true
      privateKeyAlgorithm: RSA4096
    

Cert-Manager automatically creates the secret (example-tls-secret) and updates it when renewals are needed.


Verification and Troubleshooting

  1. Check Certificate Status
    Use kubectl describe certificate example-certificate to verify issuance status. Look for Ready or Pending states.

  2. Validate TLS Configuration
    Use openssl to inspect the secret:

    openssl x509 -in /path/to/tls.crt -text -noout
    

  3. Troubleshoot DNS Validation
    If certificate issuance fails, ensure:

  4. The DNS record for www.example.com points to the Ingress controller's public IP.
  5. The Ingress controller's domain is correctly configured in the Issuer (e.g., nginx.ingress.kubernetes.io/controller-domain).

Key takeaways

  • TLS termination at the ingress layer simplifies backend security by offloading cryptographic operations.
  • Cert-Manager automates certificate issuance and renewal via ACME, reducing manual intervention.
  • Proper DNS validation and secret management are critical for successful certificate integration.
  • Always verify certificate status and ensure the Ingress controller supports TLS termination.