SSL/TLS certificates are essential for encrypted communication between clients and services, ensuring secure data transmission by upgrading connections from HTTP to HTTPS. Self-signed certificates are unsuitable for public-facing production environments but are ideal for testing or internal use within corporate Kubernetes clusters.
Using HTTPS in Kubernetes (AKS/EKS) is essential for:
- Securing traffic between clients and services
- Preventing man-in-the-middle (MITM) attacks
- Ensuring data integrity and confidentiality
- Meeting compliance requirements (PCI-DSS, HIPAA, etc.)
I have tested this on AKS and EKS, but the concepts apply to all Kubernetes environments including GKE, OpenShift, and self-managed clusters.
Contents
(i) Install OpenSSL Library
Ensure that OpenSSL is installed before proceeding.
# For Ubuntu/Debian sudo apt-get update && sudo apt-get install openssl -y # For RHEL/CentOS/Fedora sudo yum install openssl -y # For macOS brew install openssl # Verify installation openssl version(ii) Generate an Encrypted Private Key
openssl genrsa -des3 -out domain.key 2048
Command breakdown:
genrsa: Generates an RSA private key-des3: Encrypts the private key with Triple-DES encryption-out domain.key: Saves the private key to a file nameddomain.key2048: Specifies a key length of 2048 bits (recommended for strong encryption)
Create a configuration file (openssl.cnf) with the necessary certificate details:
[ req ] default_md = sha256 prompt = no req_extensions = req_ext distinguished_name = req_distinguished_name [ req_distinguished_name ] C = IN ST = Gujarat L = Ahmedabad O = YourOrganization OU = DevOps CN = ui-myapp emailAddress = admin@yourcompany.com [ req_ext ] keyUsage = keyEncipherment, dataEncipherment extendedKeyUsage = serverAuth subjectAltName = @alt_names [ alt_names ] IP.0 = 10.20.30.40 DNS.0 = ui.myapp.com DNS.1 = www.ui.myapp.com
Important: The IP field is optional. If specified, you can access the service via IP (e.g., https://10.20.30.40). Use a unique CN for different subdomains to easily identify applications (e.g., ui-myapp, api-myapp).
# Generate CSR using the config file openssl req -key domain.key -new -out domain.csr -config openssl.cnf # Verify the CSR content openssl req -text -noout -verify -in domain.csr(v) Generate Self-Signed Certificate
For self-signed certificates (development/testing):
# Generate self-signed certificate valid for 365 days openssl x509 -req -days 365 -in domain.csr -signkey domain.key -out domain.crt -extensions req_ext -extfile openssl.cnf # Remove passphrase from key (optional, for Kubernetes) openssl rsa -in domain.key -out domain-unencrypted.key
For production environments, submit the CSR to a trusted Certificate Authority (CA) like DigiCert, or your internal PKI.
The Subject Alternative Name (SAN) extension is a critical component of modern SSL/TLS certificates. It allows a single certificate to secure multiple domain names and IP addresses.
Why is SAN Important?- Multi-Domain Support: Secure multiple domains (e.g.,
myapp.com,www.myapp.com,api.myapp.com) with one certificate - Browser Compatibility: Modern browsers (Chrome 58+) primarily use SAN for validation, ignoring the CN field
- Cost Efficiency: Reduce certificate management overhead by using fewer certificates
- Microservices Ready: Perfect for Kubernetes where services have multiple endpoints
- IP Address Support: Include IP addresses for direct IP-based access
| Aspect | Common Name (CN) | Subject Alternative Name (SAN) |
|---|---|---|
| Domain Support | Single domain only | Multiple domains and IPs |
| Browser Support | Deprecated for validation | Primary validation method |
| Wildcard Support | Yes | Yes (per entry) |
| IP Address | Not supported | Fully supported |
[ alt_names ] # DNS entries for domain names DNS.0 = myapp.com DNS.1 = www.myapp.com DNS.2 = api.myapp.com DNS.3 = *.staging.myapp.com # Wildcard for staging subdomains # IP addresses (useful for internal services) IP.0 = 10.0.0.100 # Internal load balancer IP IP.1 = 192.168.1.50 # Development server IP
Best Practice: Always include both the bare domain (myapp.com) and www subdomain (www.myapp.com) in your SAN entries to avoid certificate mismatch errors.
Kubernetes uses Secrets to store sensitive data like TLS certificates. There are multiple ways to create TLS secrets:
Method 1: Using kubectl (Recommended)# Create TLS secret directly from certificate files kubectl create secret tls my-tls-secret \ --cert=domain.crt \ --key=domain-unencrypted.key \ --namespace=your-namespace # Verify the secret was created kubectl get secret my-tls-secret -n your-namespace kubectl describe secret my-tls-secret -n your-namespaceMethod 2: Using YAML Manifest (Base64 Encoded)
First, convert your certificate and key to base64:
# Encode certificate and key to base64 base64 -w 0 domain.crt > domain.crt.b64 base64 -w 0 domain-unencrypted.key > domain.key.b64
Create the secret manifest (tls-secret.yaml):
apiVersion: v1 kind: Secret metadata: name: my-tls-secret namespace: your-namespace type: kubernetes.io/tls data: tls.crt: <base64-encoded-certificate> tls.key: <base64-encoded-key>
Apply the manifest:
kubectl apply -f tls-secret.yaml
Security Warning: Never use online base64 tools for encoding certificates and private keys. Always use local command-line tools to protect sensitive data.
Ingress controllers manage external access to services in a Kubernetes cluster and can terminate TLS connections. Create an Ingress resource (ingress-tls.yaml) that uses your TLS secret:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-ingress
namespace: your-namespace
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- ui.myapp.com
- api.myapp.com
secretName: my-tls-secret
rules:
- host: ui.myapp.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: ui-service
port:
number: 80
- host: api.myapp.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080
Apply the Ingress:
kubectl apply -f ingress-tls.yaml
Note: The TLS secret must exist in the same namespace as your Ingress resource. The ssl-redirect annotation automatically redirects HTTP traffic to HTTPS.
Securing your Kubernetes applications with SSL/TLS certificates is essential for protecting data in transit. Key takeaways:
- Use SAN (Subject Alternative Name) to support multiple domains with a single certificate
- Store certificates securely in Kubernetes Secrets
- Configure Ingress controllers to terminate TLS at the edge
Self-signed certificates are ideal for development, testing, and internal corporate environments. For public-facing production, consider using trusted Certificate Authorities.