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.
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-proxySet strictARP: true in the KubeProxyConfiguration:
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "ipvs"
ipvs:
strictARP: trueApply 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 allCreate 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.200Make 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:v1After 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-testThe 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.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Raymond Ops
Linux ops automation, cloud-native, Kubernetes, SRE, DevOps, Python, Golang and related tech discussions.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
