Virtual Geek

Tales from real IT system administrators world and non-production environment

Using MetalLB as LoadBalancer service to Kubernetes bare metal

The intent of this Load balancer is to spread the workload among different servers or applications. It can be set up on both physical and virtual infrastructures. The load balancer traces the accessibility and availability of pods with the Kubernetes Endpoints API. When it gets an app request for a certain Kubernetes service, the Kubernetes load balancer sorts in order or round robins the application request among appropriate Kubernetes pods for the service.

Here are two kinds of load balancers:

L4 load balancers, or else known as network load balancers
They handle layer 4 data that is present at the network and transport (TCP/UDP) level. These load balancers do not aim on application knowledge, such as content type, cookies, header location, etc. This way they will only transmit traffic built on network layer data.

L7 load balancers, otherwise famously known as application load balancers
Unlike L4 load balancers, this kind of load balancer redirects traffic by utilizing the application layer configuration. These load balancers manage a greater amount of data, and are built on more information. This involves HTTP, HTTPS and SSL protocols, for example.

In earlier article I configured Kubernetes Ingress Controller Setup and deploy Ingress controller for Kubernetes on Bare Metal servers

Kubernetes loadbalancer services metallb configuration bare metal.jpg

At this moment while writing this blog, MetalLB application product is the only Load Balancer supported for Bare Metal Kubernetes Cluster. When you use a Load Balancer type Kubernetes Service on Cloud, Cloud providers deploy their own Load Balancer resource for Kubernetes services in the cloud.

To deploy MetalLB Load Balancer in Kubernetes Cluster you can found instructions from Use below github url to deploy Kubernetes resources and custom resource definition (crds) in the cluster.

ubuntu@k8smaster01:~$ sudo su -
root@k8smaster01:~# kubectl apply -f
namespace/metallb-system created created created created created created created created
serviceaccount/controller created
serviceaccount/speaker created created created created created created created created created
secret/webhook-server-cert created
service/webhook-service created
deployment.apps/controller created
daemonset.apps/speaker created created

Vmware vSPhere kubernetes k8s container loadbalancer kubectl customresourcedefinition crds apiexetions addresspool speaker controller pod-listener metallb baremetal webhook.jpg

Next create IPAddressPool resource. For IP addresses choose and assign the unassigned IP address range in the yaml file configuration. In my LAB environment I am using IP address block. From this block I will carve out and use the to IP range and will make sure it will not get used or assigned to other systems in my network. Apply the configuration.

root@k8smaster01:~# cat ippool.yaml
kind: IPAddressPool
  name: metallb
  namespace: metallb-system
root@k8smaster01:~# kubectl apply -f ippool.yaml created

kubernetes bare metal loadbalancer service kubernetes apply file yaml cat metallb ipaddresspool kind apiversion metadata namespace spec master node worker node networking l2.jpg

Next use the IP address pool name in L2Advertisement resource yaml file to advertise IP address in network infrastructure. Apply this yaml file configuration and create resource with kubectl tool

Below is the Kubernetes cluster configuration setup in my lab: 
Configure Nginx Load Balancer for the Kubernetes API Server - Part 1
Install and configure Kubernetes cluster master nodes using kubeadm - Part 2
Install and configure Kubernetes cluster worker nodes using kubeadm - Part 3

root@k8smaster01:~# cat lbl2adv.yaml
kind: L2Advertisement
  name: l2lbadv
  namespace: metallb-system
  - metallb
root@k8smaster01:~# kubectl apply -f lbl2adv.yaml created

Windows container l2advertisement metallb v1beta1 metallb-system ipaddresspools apiversion metadata namespace spec speaker controller webhook authorization clusterrolebinding rbac loadbalancer service bare metal.jpg

MetalLB Load Balancer is ready in my bare metal Kubernetes cluster environment. Its time to test it. I will deploy few resources such as Namespace, Deployment (Nginx Image with custom static web pages) and Service with LoadBalancer type pointing to deployment. 

Download this project deployment yaml here or it is also available on

root@k8smaster01:~# kubectl apply -f lbtest.yaml
namespace/green-project created
deployment.apps/green created
service/green-svc created

#lbtest.yaml with Kubernetes resources #Namespace, Deployment and Services
#This will create a new Namespace, Deployment and lb Service will be created under this
apiVersion: v1
kind: Namespace
  name: green-project
    app: green
#This will create Deployment with 2 pod replicas of NGINX images - Labels: Green
apiVersion: apps/v1
kind: Deployment
  name: green
    app: green
  namespace: green-project
  replicas: 2
      app: green
        app: green
      - name: websitedata
        emptyDir: {}
      - name: webcontent
        image: busybox
        - name: websitedata
          mountPath: /websitedata
        command: ["/bin/sh"]
        args: ["-c", 'echo "Welcome to Green_Application" > /websitedata/index.html']
      - name: green
        image: nginx
        - containerPort: 80
        - name: websitedata
          mountPath: "/usr/share/nginx/html" #For nginx image path - "/usr/share/nginx/html"
          readOnly: true
#This will create a service with LoadBalancer type with label selector green
apiVersion: v1
kind: Service
  name: green-svc
  namespace: green-project
    app: green
  type: LoadBalancer
  - protocol: TCP
    port: 80
    targetPort: 80

Once you get the information for services using kubectl tool, you can see there is an External-IP assigned to the service and TYPE is LoadBalancer. In absence of LoadBalancer such as MetalLB for Bare Metal, you will see External-IP is pending or none. LoadBalancer assigns the first IP address from the address pool as mentioned above.

root@k8smaster01:~# kubectl get all -n green-project
NAME                         READY   STATUS    RESTARTS   AGE
pod/green-7dd977478c-nrcbp   1/1     Running   0          89s
pod/green-7dd977478c-xpvtz   1/1     Running   0          89s

NAME                TYPE           CLUSTER-IP       EXTERNAL-IP      PORT(S)        AGE
service/green-svc   LoadBalancer   80:32193/TCP   89s

NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/green   2/2     2            2           89s

NAME                               DESIRED   CURRENT   READY   AGE
replicaset.apps/green-7dd977478c   2         2         2       89s

Kubectl kubernetes get all namepsace type loadbalancer service cluster-ip external-ip internal-ip pod restart replicaset metallb load balancer bare metal linux ubuntu kubeadm kubelet kube-proxy overlay.jpg

Test the External-IP in the browser from any other system. You will get the response and Load Balancer is working good.

Vmware vSPhere bare metal deployment pod services load balancer metalLB configuration ipaddresses public ip browser url esxi aks eks aws azure containrization docker rkt cri-o networking resource crds.jpg

Useful Articles
Kubernetes kubeadm join could not find a jws signature in the cluster-info ConfigMap for token ID
Kubernetes kubeadm join couldn't validate the identity of the API server connection refused
How to install kubernetes master control-plane on ubuntu Part 1
How to install kubernetes worker node on ubuntu Part 2
ansible create an array with set_fact
Ansible get information from esxi advanced settings nested dictionary with unique keynames
Install Ansible AWX Tower on Ubuntu Linux
Ansible AWX installation error Cannot have both the docker-py and docker python modules
Ansible AWX installation error docker-compose run --rm --service-ports task awx-manage migrate --no-input

Go Back


Blog Search

Page Views


Follow me on Blogarama