Learn how to set up a production-ready Kubernetes cluster with automatic SSL certificate management using cert-manager and Let's Encrypt. This guide will walk you through the entire process from cluster creation to SSL automation.
First, we'll create a Kubernetes cluster. This example uses Google Kubernetes Engine (GKE), but the SSL setup will work with any Kubernetes cluster.
# Create a GKE cluster with 3 nodes
gcloud container clusters create my-cluster \
--num-nodes=3 \
--zone=us-central1-a \
--enable-autoscaling \
--min-nodes=1 \
--max-nodes=5 \
--machine-type=e2-medium
# Get cluster credentials
gcloud container clusters get-credentials my-cluster --zone=us-central1-aFor AWS EKS or Azure AKS, use their respective CLI tools to create a cluster.
Install the NGINX Ingress Controller to handle incoming traffic and SSL termination.
# Add the ingress-nginx Helm repository
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
# Install NGINX Ingress Controller
helm install ingress-nginx ingress-nginx/ingress-nginx \
--namespace ingress-nginx \
--create-namespace \
--set controller.service.type=LoadBalancer
# Wait for the external IP
kubectl get service -n ingress-nginx ingress-nginx-controller --watchcert-manager will automatically request and manage SSL certificates from Let's Encrypt.
# Add the 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
# Verify installation
kubectl get pods -n cert-managerCreate a ClusterIssuer that will use Let's Encrypt to issue certificates for your domains.
# Create letsencrypt-issuer.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: your-email@example.com
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: nginx# Apply the ClusterIssuer
kubectl apply -f letsencrypt-issuer.yaml
# Verify the ClusterIssuer
kubectl get clusterissuerDeploy a sample application and configure it to use automatic SSL certificates.
# Create sample-app.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-app
spec:
replicas: 2
selector:
matchLabels:
app: sample-app
template:
metadata:
labels:
app: sample-app
spec:
containers:
- name: sample-app
image: nginx:latest
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: sample-app-service
spec:
selector:
app: sample-app
ports:
- protocol: TCP
port: 80
targetPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: sample-app-ingress
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
tls:
- hosts:
- your-domain.com
secretName: sample-app-tls
rules:
- host: your-domain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: sample-app-service
port:
number: 80# Deploy the application
kubectl apply -f sample-app.yaml
# Check certificate status
kubectl get certificate
kubectl describe certificate sample-app-tlsVerify that your SSL certificate is working correctly and automatically renewing.
# Check certificate details
kubectl get certificate -o wide
# Check certificate events
kubectl describe certificate sample-app-tls
# Test SSL certificate
curl -I https://your-domain.com
# Check certificate expiration
echo | openssl s_client -connect your-domain.com:443 2>/dev/null | \
openssl x509 -noout -datesYou now have a production-ready Kubernetes cluster with automatic SSL certificate management! Your certificates will automatically renew before expiration, ensuring your applications remain secure without manual intervention.
This setup provides a robust foundation for deploying secure applications in Kubernetes. Remember to monitor your certificates and keep your cluster components updated for optimal security.