Kubernetes LoadBalancer service for On-Premises
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.1
IP) 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.