Skip to main content
In this lesson we demonstrate how to use Cilium’s LoadBalancer IPAM to assign EXTERNAL-IP addresses to Kubernetes Services of type LoadBalancer in an on-premises cluster (where cloud-managed load balancers are not available).
A presentation slide showing the word "Demo" on the left and a teal curved panel on the right labeled "LoadBalancer IPAM." The slide also has a small "© Copyright KodeKloud" notice in the corner.

Scenario

  • Cluster runs on-premises (not on AWS/EKS/AKS).
  • No external load-balancer controller (e.g., MetalLB) is installed.
  • We have two sample deployments and corresponding Services; one Service is LoadBalancer type and will initially show EXTERNAL-IP as <pending>.

Verify current Services

Check Services before deploying the sample apps:
user1@control-plane:~$ kubectl get svc
NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE
kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP    4h18m

Apply the sample Deployment and Services

Apply the manifest that creates two applications (myapp and myapp2) and their Services:
user1@control-plane:~$ kubectl apply -f deployment.yaml
deployment.apps/myapp-deployment created
service/myapp-service created
deployment.apps/myapp2-deployment created
service/myapp2-service created
List Services again. Notice myapp-service is LoadBalancer type but its EXTERNAL-IP remains <pending> because no external IP provider exists in this on-prem cluster:
user1@control-plane:~$ kubectl get svc
NAME           TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)           AGE
kubernetes     ClusterIP      10.96.0.1       <none>        443/TCP           4h19m
myapp-service  LoadBalancer   10.100.44.117   <pending>     80:32109/TCP      7s
myapp2-service ClusterIP      10.97.231.39    <none>        80/TCP            7s

Provide external IPs with CiliumLoadBalancerIPPool

Instead of installing a separate external load balancer solution (for example, MetalLB), Cilium can allocate external IP addresses for LoadBalancer Services using a CiliumLoadBalancerIPPool resource. Create a file named lb-ipam.yaml with the IP block you want Cilium to manage. Example:
apiVersion: "cilium.io/v2alpha1"
kind: CiliumLoadBalancerIPPool
metadata:
  name: "my-pool"
spec:
  blocks:
    - start: "172.19.255.1"
      stop:  "172.19.255.45"
  # Optional: restrict IP assignment to services matching these labels
  # serviceSelector:
  #   matchLabels:
  #     color: red
  • The blocks range specifies the pool of external IPs that Cilium can allocate.
  • Optionally use serviceSelector to limit assignments to Services with specific labels.
Apply the pool:
user1@control-plane:~$ kubectl apply -f lb-ipam.yaml
ciliumloadbalancerippool.cilium.io/my-pool created
Now re-check Services:
user1@control-plane:~$ kubectl get svc
NAME           TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)          AGE
kubernetes     ClusterIP      10.96.0.1       <none>          443/TCP          4h22m
myapp-service  LoadBalancer   10.100.44.117   172.19.255.1    80:32109/TCP     2m25s
myapp2-service ClusterIP      10.97.231.39    <none>          80/TCP           2m25s
The myapp-service now has EXTERNAL-IP assigned (172.19.255.1), taken from the configured pool. Subsequent LoadBalancer Services will receive .2, .3, etc., up to the stop address.
Cilium will allocate the EXTERNAL-IP from the pool, but you must ensure the cluster network and upstream routers/switches can route or reach those addresses. Typical methods include L2 advertisement (ARP/NDP) or BGP announcements so external clients can reach the assigned IPs.
If the assigned IPs are not reachable from your network, traffic to the external IP will fail—even though Kubernetes and Cilium show the IP as assigned. Configure ARP/NDP or BGP on your network infrastructure or use an appropriate routing/advertisement mechanism.

Quick reference

ResourcePurposeExample / Notes
CiliumLoadBalancerIPPoolDefines a pool of external IP addresses for Cilium to allocate to Services of type LoadBalancerYAML example shown above
Service (LoadBalancer)Requests an external IP to expose the Service outside the clusterkubectl get svc shows EXTERNAL-IP populated by Cilium
MetalLBAlternative open-source load balancer for on-prem clustershttps://metallb.universe.tf/
That’s the LoadBalancer IPAM workflow with Cilium: create a pool, apply it, and Cilium allocates external IPs for LoadBalancer Services (optionally scoped by label selectors).

Watch Video