The instructions here should work for any Kubernetes distro running on bare metal. If you don’t have a cluster yet, start by deploying one.
Running a Kubernetes cluster on bare metal is great, but you need a way to distribute incoming traffic to your applications. This is where a load balancer comes in. A load balancer is a service that distributes incoming network traffic across multiple servers. It ensures that no single server becomes overwhelmed with traffic, and it can help improve the performance and reliability of your applications. In this guide, we’ll show you how to set up a load balancer for your Kubernetes cluster on bare metal. We’ll use Cloudflare for DNS and load balancing, but you can use any load balancer you want, like Nginx or HAProxy.

Requirements

Getting started

To distribute traffic to the applications on your Kubernetes cluster, you first need to expose a service that acts as a load balancer — note that this is different from the load balancer we’ll set up for DNS. For bare metal, MetalLB is a great option. MetalLB is a stable and reliable service for Kubernetes load balancing. Let’s get started.

Install MetalLB

1

Install with Helm

Use Helm to install MetalLB. Refer to MetalLB’s installation guide for up to date instructions.
2

Create an IPAddressPool

An IPAddressPool is a range of IP addresses that MetalLB will use to assign IP addresses to the load balancer services. You can use your own server’s IP addresses or get additional IPs if you prefer.The IPAddressPool requires an IP range, but we can also add the IPs of our worker nodes, which isn’t the best for a production environment but not a different process from doing with additional IPs.So let’s say our Kubernetes worker nodes IPs are 160.202.129.150, 160.202.145.233, and 197.187.133.133. Make note of these IPs and create a file named ipaddresspool.yaml on your local machine.Each Latitude.sh server has its own /31 VLAN, so we need to create an IPAddressPool for each server. Make sure to replace the IP addresses with the IPs of your worker nodes.
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: first-pool
  namespace: metallb-system
spec:
  addresses:
    - 160.202.129.150-160.202.129.150
---
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: second-pool
  namespace: metallb-system
spec:
  addresses:
    - 160.202.145.233-160.202.145.233
---
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: third-pool
  namespace: metallb-system
spec:
  addresses:
    - 197.187.133.133-197.187.133.133
Then apply to your cluster.
kubectl apply -f ipaddresspool.yaml
3

Create L2Advertisements

After creating the IPAddressPool, we need to create an L2Advertisement to announce the IP addresses to the network. Create a file named l2advertisement.yaml with the following content.
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: first-pool-advertisement
  namespace: metallb-system
spec:
  ipAddressPools:
  - first-pool
  nodeSelectors:
  - matchLabels:
      kubernetes.io/hostname: node1

apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: second-pool-advertisement
  namespace: metallb-system
spec:
  ipAddressPools:
  - second-pool
  nodeSelectors:
  - matchLabels:
      kubernetes.io/hostname: node2

apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
  name: third-pool-advertisement
  namespace: metallb-system
spec:
  ipAddressPools:
  - third-pool
  nodeSelectors:
  - matchLabels:
      kubernetes.io/hostname: node3
And apply it
kubectl apply -f l2advertisement.yaml
4

Make sure everything is working

To make sure everything is working, you can create a service and a deployment and see if the load balancer is distributing traffic to the pods. Here’s an example of a service and a deployment for nginx.
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: LoadBalancer
  selector:
    app: MyApp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
If everything is working, you should be able to access the service from outside the cluster by visiting the IP address of the load balancer.

Setup Cloudflare DNS

Now that we have a load balancer, we need to set up Cloudflare DNS to point to the load balancer. We have two options:
  1. Create a DNS record that points to all the IPs of the load balancer.
  2. Create a DNS record through Cloudflare’s load balancer service.
For the purpose of this guide, we’ll go with the second option.
1

Create load balancer service

From your Cloudflare dashboard, go to the Traffic > Load Balancing section and click on “Create Load Balancer”.
2

Set the load balancer settings

  • Hostname: choose a hostname for your service. E.g., k8s-guide.my-domain.com.
  • Endpoints: create and add a pool with the IPs of your Kubernetes worker nodes. You don’t need a fallback pool.
Everything else is optional and can be changed later to your liking.

That’s it!

You should now be able to access services from outside the cluster with MetalLB as the load balancer for application traffic and Cloudflare for DNS.