EKS Load Balancers with Static IP

If you’ve used Amazon Elastic Container Service for Kubernetes (EKS), you must be familiar with the Load Balancers that it creates.

Whenever you spin up a Service Type Load Balancer by defining Type: LoadBalancer, boom! You have a shiny new ELB created which exposes your Kubernetes application over an FQDN assigned randomly by AWS.

However, these load balancers are so random by default. Their names, FQDN, and even IP addresses are random every time.

This might not be a problem if you are deploying a simple application once. But what if your use case needs more prediction and finer control over these load balancers?

AWS Load Balancer Controller comes to the rescue! According to AWS documentation, Cloud providers provision a basic ELB., and only important security patches apply to it. However, it would not receive any feature updates. When you define a service Type: LoadBalancer, by default, it goes to the cloud provider provisioner.

With some configurations, you will be able to use AWS Load Balancer Controller to provision Load Balancers from your k8s cluster instead, where you can enjoy the full set of features AWS Load Balancers have to offer with a Network Lod Balancer (NLB), including setting static IP addresses for private load balancers and setting specific Elastic IP Addresses (EIP) for public load balancers. Additionally, it let you choose better descriptive name for your load balancer instead of random hash and even set proxy protocol settings.


You can follow AWS documentation on how to get this controller installed. AWS documentation is straightforward. However, there are Terraform scripts (that I might write about in the next update) that can automate role and service account creations.

After configuring roles and policies in your AWS console and Kubernetes, the Helm chart provided by AWS will set up the provisioner.

AWS Load Balancer Controller as provisioner

Now, it's annotations time.

You need to set your load balancer type to ‘external’ so the new provisioner takes control of provisioning:

service.beta.kubernetes.io/aws-load-balancer-type: external

If your service Type: LoadBalancer with the above annotation gets stuck in Pending mode, please check logs from your AWS Load Balancer Controller pod to ensure the configuration steps above are done correctly.

Additionally, make sure the IP addresses that you have requested are available and not in use.

We can use the following annotation to set IP address for public load balancer:

service.beta.kubernetes.io/aws-load-balancer-eip-allocations: eipalloc-xxxxxxxxxxxxxxxxx,eipalloc-yyyyyyyyyyyyyyyyy

For this to work, you need to create those Elastic IP addresses in region where your cluster is running. and the amount of Elastic IP resources must match same number of subnets as the Kubernetes cluster.

If your Load Balancer is internal/private, then you can use following annotations:


Make sure those IP addresses are within range of your private subnet network. and not in use by any other pod or service.

and let's not forget about:

service.beta.kubernetes.io/aws-load-balancer-internal: “true”

Please note that this annotation is different from than load balancer type external we define above. Load Balancer type external is to signal Kubernetes cluster to not use its legacy cloud provisioner to create the load balancer. and this one is to define internal/private load balancer.

If you would like to have a customized name showing up in your AWS console instead of hashes, you can configure it this way:

service.beta.kubernetes.io/aws-load-balancer-name: “YourCustomName”

A note about your Ingress controllers

When you are installing your ingress controllers (be Nginx, HAproxy, Traefik or any other ingress controller), all you need to do is to add the above annotations to their service definition.

AWS Load Balancer Controller also comes with ALB Ingress. but that is optional to use. If you use ALB ingress that comes with it, it will then create an Application Load Balancer (ALB) linked to your ingress resources. However focus of this article is on NLB with Static IP address and not ALB. ALB have it’s own set of features and configurations.




Coders changed the world. To be continued…

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

CS 371p Spring 2020: Week of 3/30

Start your MSA with Spring Boot — (1) Understanding of MSA

Case study: Building high-level framework for quick development of fintech web applications

CS373 Fall 2020: Jesse Zou

Customize your Git bash like this

State of Lambda Functions in 2020 by Dashbird

Best of the Week — February 1/7

Could not get the primary storage key for the public config storage account…

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
Armin Nikdel

Armin Nikdel

Coders changed the world. To be continued…

More from Medium

GitOps with Kubernetes: Managing Application using GitLab and Argo CD

Newsletter of Carlos Santana — Issue #35

From GIT to Kubernetes with Argo CD

Kubernetes & Helm apps debugging 101