AWS EKS and TLS terminated Load Balancer

ismail yenigül
Feb 26, 2019 · 4 min read
Image for post
Image for post

At this time, TLS termination with AWS Network Load Balancer(NLB) is not supported by Kubernetes. Also AWS NLB support is a new feature in Kubernetes that is currently in Alpha version and for that reason AWS does not recommend using it on production environments.

UPDATE: Mar 10, 2020
AWS EKS support for configuring TLS termination on NLB load balancers. https://aws.amazon.com/about-aws/whats-new/2020/03/amazon-eks-now-supports-kubernetes-version-1-15/

We have two options: Classical Load Balancer or AWS ALB Ingress Controller for Kubernetes.

AWS ALB Ingress Controller is a 3rd party resource and therefore out of AWS support scope. It uses a different approach to deploy an Application Load Balancer by using ingress resources instead of the LoadBalancer service type from Kubernetes.

I will give sample yaml files for Classical LoadBalancer and AWS ALB Ingress Controller here.

apiVersion: v1
kind: Service
metadata:
annotations:
service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:eu-west-1:xxx:certificate/xxx
labels:
app: myapp
name: myapp
spec:
type: LoadBalancer
ports:
- protocol: TCP
port: 443
targetPort: 8080
selector:
app: myapp

Replace service.beta.kubernetes.io/aws-load-balancer-ssl-cert value with your SSL certificate ARN. You can get the ARN from AWS Certificate Manager Console.

If your backend is HTTP and if you need to get X-Forwarded-Proto headers in your backend service, you need to set backend as http. to set the backend protocol as HTTP add the following lines in the annotations

service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http

From https://github.com/kubernetes/kubernetes/blob/master/staging/src/k8s.io/legacy-cloud-providers/aws/aws.go

// ServiceAnnotationLoadBalancerBEProtocol is the annotation used on the service                       
// to specify the protocol spoken by the backend (pod) behind a listener.
// If `http` (default) or `https`, an HTTPS listener that terminates
// the connection and parses headers is created. // If set to `ssl` or `tcp`, a "raw" SSL listener is used. // If set to `http` and `aws-load-balancer-ssl-cert` is not used // then
// a HTTP listener is used. const ServiceAnnotationLoadBalancerBEProtocol = "service.beta.kubernetes.io/aws-load-balancer-backend-protocol"

If you want to listen port 80 too in the Load balancer, you can change the service as following.

  1. You must give a name to all ports.
  2. You must configure service.beta.kubernetes.io/aws-load-balancer-ssl-ports Otherwise, The load balancer will listen port 80 as HTTPS
apiVersion: v1
kind: Service
metadata:
annotations:
service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:eu-west-1:xxx:certificate/xxx
service.beta.kubernetes.io/aws-load-balancer-backend-protocol: http
service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443"
labels:
app: myapp
name: myapp
spec:
type: LoadBalancer
ports:
- name: http
protocol: TCP
port: 80
targetPort: 8080
- name: https
protocol: TCP
port: 443
targetPort: 8080
selector:
app: myapp

To use AWS ALB Ingress Controller at https://github.com/kubernetes-sigs/aws-alb-ingress-controller/ I assume that you deployed AWS ALB Ingress Controller correctly.

If you are trying to deploy v.1.1 please use iam-policy.json from master branch. v1.1.1 does not contain the following permissions to get SSL certs from ACM.

"elasticloadbalancing:DescribeListenerCertificates",
"elasticloadbalancing:AddListenerCertificates",
"elasticloadbalancing:RemoveListenerCertificates"

Also don’t forget to add tag kubernetes.io/role/elb for your subnets

kubernetes.io/role/elb should be set to 1 or an empty tag value for internet-facing load balancers.

Create a service with NodePort type, replace targetPort with your Pod exposed port.

apiVersion: v1
kind: Service
metadata:
labels:
app: myapp
name: myapp
spec:
ports:
- port: 80
targetPort: 8080
protocol: TCP
type: NodePort
selector:
app: myapp

Then create an Ingress

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: myapp
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
alb.ingress.kubernetes.io/group: myapp
alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:eu-west-1:xxx:certificate/xxx
spec:
rules:
- host: app.mydomain.com
http:
paths:
- path: /*
backend:
serviceName: myapp
servicePort: 80

servicePort in Ingress must match with port value in service yaml. Your HTTP and HTTPS will be forwarded to myapp service’s port 80

Now you can create your loadbalancer with kubectl

Ismail YENIGUL

Devops Engineer at Feedstock Inc.

Image for post
Image for post

Follow us on Twitter 🐦 and Facebook 👥 and join our Facebook Group 💬.

To join our community Slack 🗣️ and read our weekly Faun topics 🗞️, click here⬇

Image for post
Image for post

FAUN

The Must-Read Publication for Creative Developers & DevOps Enthusiasts

By FAUN

Medium’s largest and most followed independent DevOps publication. Join thousands of aspiring developers and DevOps enthusiasts Take a look

By signing up, you will create a Medium account if you don’t already have one. Review our Privacy Policy for more information about our privacy practices.

Check your inbox
Medium sent you an email at to complete your subscription.

ismail yenigül

Written by

Devops Engineer

FAUN

FAUN

The Must-Read Publication for Creative Developers & DevOps Enthusiasts. Medium’s largest DevOps publication.

ismail yenigül

Written by

Devops Engineer

FAUN

FAUN

The Must-Read Publication for Creative Developers & DevOps Enthusiasts. Medium’s largest DevOps publication.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store