TLS/SSL encryption is essential for securing traffic in production environments. Envoy Gateway provides comprehensive TLS support through the Gateway API, including TLS termination, certificate management, and mTLS. This comprehensive guide covers everything you need to know about configuring TLS with Envoy Gateway.
Understanding TLS in Envoy Gateway
TLS Support in Gateway API
Envoy Gateway supports:
- TLS Termination: Decrypt at gateway
- TLS Passthrough: Forward encrypted traffic
- mTLS: Mutual TLS authentication
- SNI: Server Name Indication
- Certificate Management: Kubernetes secrets and cert-manager
TLS Modes
Terminate: Decrypt at gateway, forward plain HTTP
Passthrough: Forward encrypted traffic unchanged
Mutual TLS: Client and server authentication
Why TLS Matters
- Security: Encrypt data in transit
- Compliance: Meet security requirements
- Trust: Build user trust
- SEO: HTTPS ranking factor
Prerequisites
Before configuring TLS, ensure you have:
- Envoy Gateway Installed: With Gateway API support
- Domain Names: Configured DNS
- Certificates: TLS certificates (or Let's Encrypt)
- cert-manager (optional): For automatic certificates
- kubectl Access: With secret creation permissions
- Understanding: Basic TLS concepts
Step-by-Step: Basic TLS Configuration
Step 1: Create TLS Secret
Create Kubernetes secret with certificate:
# Create TLS secret from files
kubectl create secret tls example-tls \
--cert=path/to/certificate.crt \
--key=path/to/private.key \
--namespace=default
# Or create from existing secret
kubectl create secret tls example-tls \
--cert=<(echo "$CERT") \
--key=<(echo "$KEY") \
--namespace=default
# Verify secret
kubectl get secret example-tls -o yaml
Step 2: Configure Gateway with TLS
# tls-gateway.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: tls-gateway
namespace: default
spec:
gatewayClassName: envoy
listeners:
- name: https
protocol: HTTPS
port: 443
hostname: example.com
tls:
mode: Terminate
certificateRefs:
- name: example-tls
kind: Secret
allowedRoutes:
namespaces:
from: All
Configuration Explained:
protocol: HTTPS: HTTPS listenerport: 443: Standard HTTPS porthostname: Optional hostname restrictionmode: Terminate: Decrypt at gatewaycertificateRefs: Reference to TLS secret
Step 3: Create HTTPRoute
# tls-httproute.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: tls-route
namespace: default
spec:
parentRefs:
- name: tls-gateway
hostnames:
- example.com
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: web-service
port: 80
weight: 100
Step 4: Apply and Verify
# Apply Gateway
kubectl apply -f tls-gateway.yaml
# Apply HTTPRoute
kubectl apply -f tls-httproute.yaml
# Verify Gateway
kubectl get gateway tls-gateway
kubectl describe gateway tls-gateway
# Test HTTPS
curl -v https://example.com
Let's Encrypt Integration
Method 1: cert-manager (Recommended)
Step 1: Install cert-manager
# Install cert-manager
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.0/cert-manager.yaml
# Verify installation
kubectl get pods -n cert-manager
Step 2: Create ClusterIssuer
# 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-key
solvers:
- http01:
ingress:
class: envoy
Step 3: Create Certificate
# certificate.yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: example-com-tls
namespace: default
spec:
secretName: example-com-tls-secret
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
dnsNames:
- example.com
- www.example.com
Step 4: Use Certificate in Gateway
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: letsencrypt-gateway
spec:
gatewayClassName: envoy
listeners:
- name: https
protocol: HTTPS
port: 443
hostname: example.com
tls:
mode: Terminate
certificateRefs:
- name: example-com-tls-secret
kind: Secret
Advanced TLS Configuration
Multiple Certificates
Support multiple hostnames:
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: multi-cert-gateway
spec:
gatewayClassName: envoy
listeners:
- name: https-example
protocol: HTTPS
port: 443
hostname: example.com
tls:
mode: Terminate
certificateRefs:
- name: example-tls
kind: Secret
- name: https-api
protocol: HTTPS
port: 443
hostname: api.example.com
tls:
mode: Terminate
certificateRefs:
- name: api-tls
kind: Secret
TLS Passthrough
Forward encrypted traffic without decryption:
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: passthrough-gateway
spec:
gatewayClassName: envoy
listeners:
- name: https-passthrough
protocol: HTTPS
port: 443
hostname: backend.example.com
tls:
mode: Passthrough
TLS Options
Configure TLS protocols and ciphers:
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: secure-tls-gateway
spec:
gatewayClassName: envoy
listeners:
- name: https
protocol: HTTPS
port: 443
hostname: secure.example.com
tls:
mode: Terminate
certificateRefs:
- name: secure-tls
kind: Secret
options:
tls:
minVersion: "1.2"
maxVersion: "1.3"
cipherSuites:
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
Mutual TLS (mTLS)
Configure mTLS
Require client certificates:
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: mtls-gateway
spec:
gatewayClassName: envoy
listeners:
- name: https-mtls
protocol: HTTPS
port: 443
hostname: secure.example.com
tls:
mode: Terminate
certificateRefs:
- name: server-tls
kind: Secret
options:
tls:
clientCertificateRefs:
- name: ca-cert
kind: Secret
Wildcard Certificates
DNS-01 Challenge
For wildcard certificates, use DNS challenge:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-dns
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: your-email@example.com
privateKeySecretRef:
name: letsencrypt-dns-key
solvers:
- dns01:
cloudflare:
email: cloudflare@example.com
apiKeySecretRef:
name: cloudflare-api-key
key: api-key
Wildcard Certificate
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: wildcard-tls
spec:
secretName: wildcard-tls-secret
issuerRef:
name: letsencrypt-dns
kind: ClusterIssuer
dnsNames:
- "*.example.com"
- example.com
Certificate Monitoring
Monitor Certificate Expiration
# Check certificate status
kubectl get certificate -A
# View certificate details
kubectl describe certificate example-com-tls
# Check expiration
kubectl get secret example-com-tls-secret -o jsonpath='{.data.tls\.crt}' | \
base64 -d | openssl x509 -noout -dates
Set Up Alerts
Monitor certificate expiration:
- Alert 30 days before expiration
- Alert on renewal failures
- Monitor cert-manager logs
Troubleshooting
Issue 1: Certificate Not Working
Symptoms: HTTPS connection fails.
Solutions:
- Verify certificate secret exists
- Check certificate is valid
- Verify hostname matches
- Check Gateway status
Issue 2: Certificate Not Renewing
Symptoms: Certificate expires.
Solutions:
- Check cert-manager logs
- Verify ClusterIssuer configuration
- Check DNS/HTTP challenge access
- Verify certificate resource status
Best Practices
- Use Let's Encrypt: Free, automatic certificates
- Monitor Expiration: Set up alerts
- Use Strong Ciphers: TLS 1.2+ only
- Wildcard Certificates: For multiple subdomains
- Test Renewal: Verify automatic renewal
Conclusion
Envoy Gateway provides comprehensive TLS support. By following this guide:
- TLS Termination: Decrypt at gateway
- cert-manager: Automatic certificate management
- Let's Encrypt: Free certificates
- mTLS: Mutual authentication
- Production Ready: Enterprise TLS
Key Takeaways:
- Use cert-manager for automatic certificates
- Monitor certificate expiration
- Use strong TLS configuration
- Test TLS setup thoroughly
- Document certificate management
Next Steps:
- Create TLS secrets
- Configure Gateway with TLS
- Set up cert-manager
- Monitor certificates
- Test HTTPS connections
With proper TLS configuration, Envoy Gateway provides secure, encrypted connections for your services.