Cloud Native 15 min read

How to Deploy MetalLB LoadBalancer on Bare‑Metal Kubernetes with Calico

This guide explains Kubernetes Service concepts, the different Service types and ports, introduces MetalLB as a LoadBalancer solution for bare‑metal clusters, walks through its installation, configuration, testing, integration with Ingress, and also covers Calico networking fundamentals and architecture.

Raymond Ops
Raymond Ops
Raymond Ops
How to Deploy MetalLB LoadBalancer on Bare‑Metal Kubernetes with Calico

Basic Overview

Service

Kubernetes creates a Service to hide the dynamic IP addresses of Pods and to provide load‑balancing across multiple instances.

Service Types

Common Service type values are:

ClusterIP – a virtual IP reachable only inside the cluster.

NodePort – maps a port on every node, enabling nodeIP:nodePort access from outside.

LoadBalancer – requests a cloud provider load balancer (or MetalLB on bare metal) that forwards traffic to the Service.

Ports

A Service defines three ports:

port – the ClusterIP port for internal access.

nodePort – the port exposed on each node for external access.

targetPort – the container port on the Pod that receives the traffic after kube‑proxy routing.

IP Addresses

Three IP concepts are involved:

ClusterIP – a virtual address managed by kube‑proxy with iptables rules.

Pod IP – the IP assigned to each Pod (shared via the pause container).

Node IP – the node’s address used when a Service of type NodePort or LoadBalancer is accessed from outside.

Operation

The Service selector creates Endpoints that point to matching Pods. The Endpoints controller watches Service and Pod changes and updates the Endpoint objects, while kube‑proxy updates local routing rules on each node.

MetalLB Overview

MetalLB provides a LoadBalancer implementation for bare‑metal Kubernetes clusters where cloud provider LB services are unavailable. It allocates IPs from a user‑defined pool and announces them via Layer‑2 (ARP/NDP) or BGP.

The project started in late 2017 and is currently in Beta.

MetalLB consists of two components:

Controller (Deployment) – watches Service objects and assigns IPs.

Speaker (DaemonSet) – announces the assigned IPs on the network.

Address Allocation

The Controller allocates an IP from the configured pool to each Service of type LoadBalancer. The pool is defined in a ConfigMap.

External Announcement

The Speaker publishes the Service IP to the network using either Layer‑2 (ARP/NDP) or BGP, allowing external clients to reach the Service.

Working Principle

When a Service is created with type: LoadBalancer, the Controller picks an IP from the pool and creates a Service object. The Speaker then announces that IP. Traffic arriving at the node is handled by kube‑proxy, which forwards it to the appropriate Pod.

Installation

Pre‑Installation Checks

If kube‑proxy runs in IPVS mode, enable strict ARP from Kubernetes v1.14.2 onward:

# kubectl edit configmap -n kube-system kube-proxy

Set strictARP: true in the KubeProxyConfiguration:

apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "ipvs"
ipvs:
  strictARP: true

Apply the changes and restart the kube‑proxy pods.

MetalLB Installation

# mkdir metallb && cd metallb
# wget https://github.com/metallb/metallb/blob/main/config/manifests/metallb-native.yaml
# vim metallb-native.yaml   # adjust image references if needed
# kubectl apply -f metallb-native.yaml
# kubectl -n metallb-system get all

Create the secret required by the speaker:

# kubectl create secret generic -n metallb-system memberlist \
  --from-literal=secretkey="$(openssl rand -base64 128)"

Configuration

Create a ConfigMap that defines an address pool (example uses a Layer‑2 pool):

apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config

data:
  config: |
    address-pools:
    - name: default
      protocol: layer2
      addresses:
      - 172.25.1.100-172.25.1.200
Make sure the IP range matches your cluster’s network.

Testing

Create a Service of type LoadBalancer and a Deployment to verify that MetalLB assigns an external IP:

apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  type: LoadBalancer
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: myapp:v1

After applying, the Service will obtain an IP from the pool, visible with kubectl get svc nginx-svc.

MetalLB with Ingress

Use MetalLB to expose an Ingress controller as a LoadBalancer:

# kubectl apply -f ingress-demo.yml   # Ingress resource
# kubectl apply -f nginx-svc.yml      # Service of type LoadBalancer
# kubectl get ingress
# kubectl describe ingress nginx-test

The traffic flow becomes: client → MetalLB VIP → ingress‑nginx → Service → Pod.

Calico Network Plugin

Calico Overview

Calico provides pure L3 routing and network policy for Pods, avoiding overlays and NAT. It can operate in IPIP mode for cross‑subnet pod communication or BGP mode for large‑scale networks.

Calico Architecture

Felix runs on each node, configuring interfaces, IPs, MACs, and applying network policies. BIRD is the BGP daemon that propagates pod routes to other nodes.

Calico’s design enables high‑performance, NAT‑free networking across VMs, containers, and bare metal.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

KubernetesnetworkCalicoloadbalancerMetalLB
Raymond Ops
Written by

Raymond Ops

Linux ops automation, cloud-native, Kubernetes, SRE, DevOps, Python, Golang and related tech discussions.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.