Kubernetes LoadBalancer service for On-Premises

Mahdi Mallaki
ITNEXT
Published in
5 min readJul 9, 2023

--

Configuring a Virtual IP for the Load-Balancer service using MetalLB in Kubernetes

Introduction

When it comes to exposing your Kubernetes service to external clients, you have various options to choose from. Two commonly used methods are NodePort and LoadBalancer. In this article, we will delve into the differences between these two approaches and understand when each one is suitable for your specific needs.

The subsequent section of this article is designed to guide you through the installation of MetalLB on Kubernetes, providing you with a method to define Virtual IPs.

NodePort VS LoadBalancer Service

There are various ways to expose your Kubernetes service to external clients. One option is to use NodePort, which assigns a port between 30000 and 32767 on all your worker nodes. However, it has limitations. You need to handle load balancing yourself, and if one of your worker nodes goes down, you must be aware of it and avoid sending requests to it until it comes back up.

In the diagram below, you can see an example where I deployed a sample nginx app with 2 replicas using a NodePort service with the port number 31415. The client should send its requests to one of the worker nodes. It doesn’t matter whether the pod exists on that particular node or not, as Kubernetes will automatically proxy your requests to a worker node where the pod is located:

On the other hand, The LoadBalancer service will create a virtual IP (VIP) for your service and the client does not need to know the worker’s machine IPs. As you can see in the image below, a VIP created by Kubernetes (the 192.168.2.1IP) and the LoadBalancer will automatically find the pods on the worker nodes and send them requests directly.

In general, using the LoadBalancer service is preferable to NodePort, but its feasibility depends on the availability of a Virtual IP (VIP) in your infrastructure. In a cloud environment like AWS or Azure, you can easily utilize the LoadBalancer service without requiring any additional tools. However, in an on-premises environment, you would need tools like MetalLB to handle this functionality for you.

MetalLB Installation (only for on-premises)

If you’re in an on-premises environment, you’ll need a tool like MetalLB to create VIPs. If you only require a Kubernetes cluster for testing purposes, you can use https://killercoda.com to create a free Kubernetes cluster, which will automatically terminate after 1 hour.

To install MetalLB easily (assuming you’re using the default L2 mode), you can use the following helm commands on your Kubernetes cluster (helm ≥ 3.10 is required):

$ kubectl create ns metallb-system
$ helm upgrade --install -n metallb-system metallb \
oci://registry-1.docker.io/bitnamicharts/metallb

Next, you need to define your IP range pool in a .yaml file. For example, you can name this file L2-range-allocation.yaml, but the name is not crucial, and you can choose any name you prefer.

apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: example
namespace: metallb-system
spec:
addresses:
- 192.168.2.0/24
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: empty
namespace: metallb-system

In the provided file, replace 192.168.2.0/24 with your desired CIDR range. The /24 represents the subnet mask, indicating an IP range between 192.168.2.0 and 192.168.2.256. Feel free to modify it according to your requirements. Once you’ve made the necessary changes, you can apply the configuration using the following command:

kubectl apply -f ./L2-range-allocation.yaml

Afterwards, you should see something similar to the following output (the metallb-speaker is a DaemonSet, and the number of instances depends on the count of your Kubernetes workers):

$ kubectl get pods -n metallb-system
NAME READY STATUS RESTARTS AGE
metallb-controller-85748d679-mcvws 1/1 Running 0 84m
metallb-speaker-85vfn 1/1 Running 0 84m
metallb-speaker-8f9bt 1/1 Running 0 84m
metallb-speaker-tt9hg 1/1 Running 0 84m
metallb-speaker-wsr4s 1/1 Running 0 84m

Generate the first VIP

Generating the initial VIP Alright, now you can leverage the LoadBalancer service type in Kubernetes and obtain an actual VIP using MetalLB. Let’s assume you want to deploy a sample application, such as Nginx, and obtain a VIP for it to handle requests without requiring NodePort:

apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
strategy:
type: Recreate
selector:
matchLabels:
app: nginx
replicas: 1
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx
labels:
app: nginx
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
type: LoadBalancer

From the example file above, you can observe that I have created a sample deployment of Nginx along with a LoadBalancer service (notice the type: LoadBalancer section).

To proceed, you can save the aforementioned .yaml file as a sample file, for instance, deployment.yaml and apply it using the following command:

$ kubectl apply -f deployment.yaml

then you can see your service with the following command:

$ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 31d
nginx LoadBalancer 10.43.177.15 192.168.2.1 80:32186/TCP 2m18s

As evident from the output above, the EXTERNAL-IP (or VIP) is 192.168.2.1, which belongs to the IP range 192.168.2.0/24. You can send requests to this IP by using the following address:

$ curl 192.168.2.1:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

Conclusion

In conclusion, understanding the differences between NodePort and LoadBalancer services empowers you to make informed decisions based on your infrastructure requirements. Whether you choose NodePort or opt for the convenience of LoadBalancer services, Kubernetes provides flexible options to expose and manage your services effectively.

We hope this article has provided valuable insights into selecting the appropriate service type for your Kubernetes deployments, enabling you to enhance the accessibility and reliability of your applications.

Github

You can find all the diagrams used in this article in the following GitHub repository:

Feedback

If you have any feedback or suggestions for improving my code, please leave a comment on this post or send me a message on my LinkedIn. I would greatly appreciate your contributions to help make this article better. If you enjoyed this post, be sure to follow me to stay updated on my latest articles.

buy me a coffee at https://buymeacoffee.com/mlkmhd

--

--