SSL Terminated Kubernetes Load Balancers in AWS
Launching services in Kubernetes that utilize an AWS Elastic Load Balancer has long been fairly simple - just launch a service with type: LoadBalancer
. Where it becomes more complicated and not nearly as well documented is when you want to do SSL termination at the ELB level, a common practice when using ELBs. Luckily, there are a few annotations you can use on your service to make this happen.
The first annotation is service.beta.kubernetes.io/aws-load-balancer-ssl-ports
. This tells the ELB which port to listen on for https
traffic. It will almost always be set to "443"
.
Second, we have the service.beta.kubernetes.io/aws-load-balancer-ssl-cert
annotation. This annotation is used to provide the arn
(Amazon identifier) for the SSL certificate you have stored in AWS Certificate Manager. It should look something like arn:aws:acm:region:accountNumber:certificate/certificateName
.
Last but not least, we have service.beta.kubernetes.io/aws-load-balancer-backend-protocol
. This is the bread and butter of this, which tells the ELB that the servers it is balancing the load between is expecting the traffic to come in as http
traffic.
Here's what this looks like all put together:
kind: Service
apiVersion: v1
metadata:
name: my-deployment-name
namespace: my-namespace
annotations:
service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443"
service.beta.kubernetes.io/aws-load-balancer-ssl-cert: "arn:aws:acm:us-west-2:accountNumber:certificate/certificateName"
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: "http"
spec:
selector:
deployment: my-deployment-name
ports:
- name: http
protocol: TCP
port: 80
targetPort: 80
- name: https
protocol: TCP
port: 443
targetPort: 80
type: LoadBalancer
For more information, see the source.