Skip to main content

Kubernetes TLS Termination & Managing Certificates Lab

· 3 min read

The Manual Approach: Using Kubernetes Secrets​

Before automating, it's crucial to understand how Kubernetes handles certificates natively. Kubernetes stores TLS certificates as a specific type of Secret (kubernetes.io/tls).

Step 1: Create the TLS Secret​

If you already have a certificate (tls.crt) and a private key (tls.key), you can store them in your cluster using kubectl:

kubectl create secret tls my-website-tls \
--cert=path/to/tls.crt \
--key=path/to/tls.key \
-n my-namespace

Step 2: Configure the Ingress Resource​

Once the secret exists, you reference it in your Ingress manifest under the tls section:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-website-ingress
namespace: my-namespace
spec:
ingressClassName: nginx
tls:
- hosts:
- www.mywebsite.com
secretName: my-website-tls # Matches the secret created above
rules:
- host: www.mywebsite.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-website-service
port:
number: 80

The Automated Approach: Mastering cert-manager​

To truly master certificate management in Kubernetes, you must automate it. cert-manager is the industry-standard Kubernetes add-on that automates the issuance and renewal of TLS certificates.

Core Components of cert-manager​

  • Issuer / ClusterIssuer: Resources that represent certificate authorities (CAs) like Let's Encrypt. An Issuer is scoped to a single namespace, while a ClusterIssuer works across the entire cluster.

  • Certificate: A resource that requests a certificate from an Issuer and ensures it is kept up to date.

  • CertificateRequest: Used internally by cert-manager to request the actual signed certificate.

Step 1: Install cert-manager​

The easiest way to install it is via Helm:

Bash

helm repo add jetstack https://charts.jetstack.io
helm repo update
helm install cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--set installCRDs=true

Step 2: Create a Let's Encrypt ClusterIssuer​

We'll use Let's Encrypt with an HTTP-01 challenge. This tells Let's Encrypt to verify your domain ownership by placing a specific file on your web server.

YAML

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
# The ACME server URL
server: https://acme-v02.api.letsencrypt.org/directory
# Email address used for ACME registration
email: admin@mywebsite.com
# Name of a secret used to store the ACME account private key
privateKeySecretRef:
name: letsencrypt-prod-account-key
# Enable the HTTP-01 challenge provider
solvers:
- http01:
ingress:
class: nginx

Step 3: Automate the Ingress​

Now, simply add an annotation to your Ingress resource. cert-manager will automatically detect it, talk to Let's Encrypt, complete the challenge, create the secret, and keep it renewed!

YAML

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-website-ingress
namespace: my-namespace
annotations:
# This triggers cert-manager to use our ClusterIssuer
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
ingressClassName: nginx
tls:
- hosts:
- www.mywebsite.com
secretName: my-website-tls-auto # cert-manager creates this secret for you
rules:
- host: www.mywebsite.com
http:
# ... backend service config ...