Baeldung Pro – Ops – NPI EA (cat = Baeldung on Ops)
announcement - icon

Learn through the super-clean Baeldung Pro experience:

>> Membership and Baeldung Pro.

No ads, dark-mode and 6 months free of IntelliJ Idea Ultimate to start with.

1. Overview

In Kubernetes, Load Balancer services enable us to seamlessly expose workloads to the internet by automatically provisioning an external IP address. While this works for many scenarios, some applications like APIs or web services rely on having a consistent, static IP address to ensure reliable communication. For systems where stability and integration are critical, a static IP becomes essential.

In this article, we’ll walk through the steps to assign a static IP address to a Kubernetes Load Balancer service on Amazon Elastic Kubernetes Service (EKS) to keep applications accessible and predictable.

2. Understanding Kubernetes Load Balancers on EKS

When we use a Load Balancer service on Amazon EKS, it integrates with Amazon Elastic Load Balancer (ELB). Thus, the load balancer routes external traffic to Kubernetes pods. By default, EKS assigns a dynamically allocated IP address to the ELB. While this setup works well for many scenarios, it can create challenges for services that need a fixed IP address, such as APIs or systems with strict integration requirements. Assigning a static IP helps us maintain consistent connectivity, simplifies integration, and minimizes DNS propagation delays during service updates.

EKS supports the Network Load Balancer (NLB), which is optimized for high throughput and low latency and supports static IP allocation. This combination makes NLB the preferred choice for most production-grade workloads, ensuring the consistent performance of applications and the reliability of their external connections even under heavy traffic.

3. Reserving a Static IP Address in AWS

When we want to assign a static IP address to a Kubernetes Load Balancer in AWS, the first step is to reserve an Elastic IP (EIP). In short, Elastic IP addresses (or Elastic IPs) act as static public IPs that we can attach to resources like Network Load Balancers (NLBs). This ensures applications have a reliable and consistent endpoint, which is especially useful for services that require a fixed IP. Let’s walk through the steps to reserve and configure an Elastic IP for an EKS cluster.

3.1. Allocate an Elastic IP

To reserve a static IP address for a Kubernetes Load Balancer, we can allocate an Elastic IP using the AWS CLI. To be clear, Elastic IPs are static public IPs that can be assigned to AWS resources, ensuring a consistent endpoint for external communication.

It’s important to allocate the Elastic IP within the vpc domain, as this makes it compatible with modern AWS networking resources like Network Load Balancers (NLBs):

$ aws ec2 allocate-address --domain vpc
{  
    "PublicIp": "18.225.3.242",  
    "AllocationId": "eipalloc-5f747653"  
}  

The output provides two key-value pairs:

  • PublicIp: static IP address we should assign to our Load Balancer
  • AllocationId: unique identifier that we should preserve and attach the Elastic IP to the NLB in later steps

Thus, reserving an Elastic IP ensures that we have a static and reusable IP address. This way, applications should be more stable and easier to integrate with external systems that depend on consistent endpoints.

3.2. Tag the Elastic IP for Kubernetes

To make sure Kubernetes uses the Elastic IP, we tag it with the correct information for the respective EKS cluster:

$ aws ec2 create-tags --resources eipalloc-5f747653 \
    --tags Key=kubernetes.io/cluster/baeldung-ops-cluster,Value=shared

In fact, without this tag, Kubernetes won’t be able to associate the Elastic IP with the baeldung-ops-cluster. This could lead to configuration issues or prevent the Load Balancer from using the reserved IP. So, by tagging the EIP correctly, we ensure seamless integration between AWS resources and the Kubernetes workloads.

4. Configuring a Kubernetes Load Balancer Service With a Static IP

Now that we reserved and tagged the Elastic IP, it’s time to configure a Kubernetes Load Balancer service to use it. By setting up the right annotations and service manifest, we link the Load Balancer to the static IP we created.

4.1. Adding Required Annotations

To begin with, annotations play a key role in customizing the behavior of the Load Balancer service in EKS. Furthermore, to ensure a proper configuration, we associate Elastic IP with the Network Load Balancer (NLB). This is done using specific annotations in the service manifest:

  • service.beta.kubernetes.io/aws-load-balancer-type
  • service.beta.kubernetes.io/aws-load-balancer-eip-allocations

In this case, the first annotation instructs Kubernetes to use an NLB, seamlessly integrating with the load-balancing functionality of AWS. On the other hand, the second annotation specifies the allocation ID of the Elastic IP, ensuring correct association with the NLB.

By including these annotations, we ensure Kubernetes provisions the NLB and links it to the reserved static IP.

4.2. Writing the Service Manifest

Next, let’s create the YAML manifest for the Load Balancer service:

$ cat service.yaml
apiVersion: v1
kind: Service
metadata:
  name: baeldung-ops-loadbalancer-service
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: nlb
    service.beta.kubernetes.io/aws-load-balancer-eip-allocations: eipalloc-5f747653
spec:
  type: LoadBalancer
  ports:
    - port: 80
      targetPort: 8000
      protocol: TCP
  selector:
    app: ops-app

This manifest defines the service type as LoadBalancer and includes the necessary annotations to integrate the Network Load Balancer (NLB) with the Elastic IP on AWS.

So, let’s break down the key components in the manifest:

  • annotations: These annotations configure the load balancer to use a Network Load Balancer (NLB) and associate our reserved Elastic IP with the service.
  • selector: This section specifies which pods receive the traffic. In our case, it routes traffic to pods labeled with app: ops-app.
  • ports: Here, we define the external port (80) and the internal target port (8000) for communication.

In short, we ensured that traffic coming to port 80 on the Load Balancer gets forwarded to port 8000 on the pods.

4.3. Applying the Service Manifest

Now that we created the manifest, we can deploy the service to the Kubernetes cluster:

$ kubectl apply -f service.yaml
service/baeldung-ops-loadbalancer-service created

This command creates the Load Balancer service and provisions the NLB with the static IP associated with the AllocationId (eipalloc-5f747653) that we specified.

4.4. Verifying the Static IP Configuration

After deploying the service, it’s important to verify that the static IP has been successfully assigned to the Load Balancer:

$ kubectl get service baeldung-ops-loadbalancer-service
NAME                              TYPE           CLUSTER-IP    EXTERNAL-IP      PORT(S)        AGE
baeldung-ops-loadbalancer-service LoadBalancer   10.0.1.50     18.225.3.242	80:30080/TCP   2m

In this case, the EXTERNAL-IP column of this output shows the reserved Elastic IP as 18.225.3.242, confirming that the configuration is correct and the Load Balancer is ready for traffic.

4.5. Key Considerations

To ensure everything runs smoothly, let’s go over a few considerations:

  • Elastic IP Location: It’s important to ensure the Elastic IP is in the same region as the EKS cluster. If they are in different regions, Kubernetes won’t be able to associate the IP with the NLB.
  • Pod Health: It’s a good idea to double-check that the backend pods are healthy and correctly labeled to match the service selector (app: ops-app). If any pod isn’t available or doesn’t match the selector, traffic won’t be routed to it.
  • Security Groups: It’s crucial that we use AWS security group rules that allow traffic to the NLB on the required ports. Without the right rules, traffic won’t be able to reach the Load Balancer.

So, going through this short checklist should avoid unnecessary troubleshooting.

5. Best Practices

There are a number of best practices to ensure smooth and secure management of static Load Balancer IPs:

  • Stick to least-privilege IAM policies: It’s best to limit permissions on a per-need basis. By restricting who can create, modify, or delete Elastic IPs and load balancers, we reduce security risks and maintain better control.
  • Automate with Infrastructure as Code (IaC): Using tools like Terraform or CloudFormation usually makes managing configurations much easier, keeping the environments consistent, simplifying version control, and making deployments more reliable.
  • Monitor Load Balancer health: AWS CloudWatch and Kubernetes events are great tools for tracking load balancer performance. By continuously monitoring traffic and detecting misconfigurations early, we can keep things running smoothly.
  • Secure Load Balancer: It’s important to use AWS security groups for restricting traffic, limiting it to trusted IP ranges. This reduces the risk of unauthorized access and ensures that only legitimate traffic reaches our services.
  • Test in staging before production: It’s paramount to test deployments in a staging (pre-prod) environment before deploying them to production. This gives us the chance to resolve any issues without disrupting live systems.

In general, these proactive approaches help us catch potential issues before they escalate into bigger problems.

6. Conclusion

In this article, we discussed and went through the steps of specifying a static IP address for a Kubernetes Load Balancer.

By leveraging Elastic IPs, annotations, and proper configuration, we establish predictable networking for external-facing workloads. This approach not only enhances stability but also improves scalability and resilience. As network conditions and external dependencies evolve, following best practices helps Kubernetes deployments maintain optimal performance.

In summary, assigning a static IP to a Kubernetes Load Balancer service ensures reliable and consistent connectivity for applications.