Six tools to Simplify Kubernetes Journey — Day 2 — MetalLB Load Balancer for Bare Metal Kubernetes

For complete blog list please check https://www.101daysofdevops.com/courses/101-days-of-kubernetes/ (You need to register)

What is MetalLB?

As per official documentation

MetalLB is a load-balancer implementation for bare metal Kubernetes clusters, using standard routing protocols.

Now the question is, why do we need it?

How does it work?

Let see this with the help of an example

  • Create a deployment
kubectl create deployment nginx --image=nginx
deployment.apps/nginx created
  • Expose the deployment
kubectl expose deploy nginx --port 80 --type LoadBalancer
service/nginx exposed
  • If you check the deployment the external-ip is in the pending state
kubectl get svc nginx          
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx LoadBalancer 10.96.255.195 <pending> 80:30681/TCP 46s

To fix this issue, we can implement a solution like MetalLB.

  • First step is to apply the manifests, which will create the namespace metallb-system
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.10.3/manifests/namespace.yamlnamespace/metallb-system created
  • To verify it
kubectl get nsNAME                 STATUS   AGEdefault              Active   24hkube-node-lease      Active   24hkube-public          Active   24hkube-system          Active   24hlocal-path-storage   Active   24hmetallb-system       Active   44s
  • We will apply one more manifest in the next step, which will create the deployment, daemonset, role and cluster role binding, service account, and pod security for metallb in metallb-system namespace.
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.10.3/manifests/metallb.yam
Warning: policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+podsecuritypolicy.policy/controller createdpodsecuritypolicy.policy/speaker createdserviceaccount/controller createdserviceaccount/speaker createdclusterrole.rbac.authorization.k8s.io/metallb-system:controller createdclusterrole.rbac.authorization.k8s.io/metallb-system:speaker createdrole.rbac.authorization.k8s.io/config-watcher createdrole.rbac.authorization.k8s.io/pod-lister createdrole.rbac.authorization.k8s.io/controller createdclusterrolebinding.rbac.authorization.k8s.io/metallb-system:controller createdclusterrolebinding.rbac.authorization.k8s.io/metallb-system:speaker createdrolebinding.rbac.authorization.k8s.io/config-watcher createdrolebinding.rbac.authorization.k8s.io/pod-lister createdrolebinding.rbac.authorization.k8s.io/controller createddaemonset.apps/speaker createddeployment.apps/controller createdl
  • To verify it
kubectl get all -n metallb-systeNAME                             READY   STATUS    RESTARTS   AGEpod/controller-77c44876d-b8gsw   1/1     Running   0          42spod/speaker-wqxlq                1/1     Running   0          42s
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGEdaemonset.apps/speaker 1 1 1 1 1 kubernetes.io/os=linux 42s
NAME READY UP-TO-DATE AVAILABLE AGEdeployment.apps/controller 1/1 1 1 42s
NAME DESIRED CURRENT READY AGEreplicaset.apps/controller-77c44876d 1 1 1 42sm
  • If you look at the pod, you have two types of pod created after applying the manifests, controller and speaker. The controller is the cluster-wide MetalLB controller and is responsible for IP assignment. The speaker is a deamonset that will be installed on each node in your cluster and advertises services with assigned IPs using various advertising strategies.
  • As the last step, you need to define the configmap. Depending on your environment, you can set the operation mode to either Layer 2 or BGP and the external IP range. For this demo, I will use the protocol as layer2 and addresses as 172.18.0.200–172.18.0.250 as my Kubernetes node is running in the subnet range(check the output of kubectl get nodes -o wide command).
kubectl get nodes -o widNAME                 STATUS   ROLES                  AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE       KERNEL-VERSION     CONTAINER-RUNTIMEkind-control-plane   Ready    control-plane,master   24h   v1.21.1   172.18.0.2    <none>        Ubuntu 21.04   5.10.47-linuxkit   containerd://1.5.2e
  • Configmap will look like this
cat cm.yaml                                  
apiVersion: v1
kind: ConfigMap
metadata:
namespace: metallb-system
name: config
data:
config: |
address-pools:
- name: my-ip-space
protocol: layer2
addresses:
- 172.18.0.200-172.18.0.250

GitHub link: https://github.com/100daysofdevops/100daysofdevops/blob/master/metallb/cm.yaml

  • This time if you check the service, you will see that metallb assigned the external ip to it from the pool you defined under configmap.
kubectl get svc nginxNAME  TYPE      CLUSTER-IP   EXTERNAL-IP  PORT(S)    AGEnginx  LoadBalancer  10.96.131.55  172.18.0.200  80:30355/TCP  10m

Wrapping Up

Metallb allows you to create Loadbalancer for your service without deploying your cluster in the cloud environment. So far, I have explored the layer2 mode, which doesn’t need any external hardware. Another mode is BGP, which is production-ready but requires changes on the network end. Please let me know if you have explored BGP mode or any other functionality provided by metallb, which I am missing in this blog.

AWS Community Builder, Ex-Redhat, Author, Blogger, YouTuber, RHCA, RHCDS, RHCE, Docker Certified,4XAWS, CCNA, MCP, Certified Jenkins, Terraform Certified, 1XGCP