Monitoring MetalLB configuration status
As an OpenShift Container Platform system administrator, you can gain insights into the operational status of your MetalLB deployments by examining the status of its custom resources (CRs). These status fields provide information about IP address allocations, BGP peer announcements, and session states, which are important for effective monitoring and troubleshooting.
For more information about how to install the MetalLB Operator, see About MetalLB and the MetalLB Operator.
Understanding MetalLB status custom resources
MetalLB provides a scalable framework for monitoring the health of network traffic and IP addresses. Use status fields in MetalLB custom resources to track session status and troubleshoot configuration.
MetalLB exposes status information for several key components, providing a comprehensive view of its configuration and operation.
| Resource | Description | Troubleshooting command |
|---|---|---|
|
Shows the cluster-wide allocation and availability of IP addresses within a defined pool, including the number of assigned and available addresses for both IPv4 and IPv6. |
|
|
Shows which service IP addresses the system announces to specific BGP peers across the network infrastructure. |
|
|
Shows the real-time operational state of the border gateway protocol (BGP) and bidirectional forwarding detection (BFD) sessions between a specific cluster node and a BGP peer, indicating if the channel is |
|
The MetalLB controller, typically deployed as metallb-system/controller, is responsible for managing IP address assignments and updating the IPAddressPool status. When a service requests a LoadBalancer IP, the controller allocates an IP from an appropriate IPAddressPool and updates the status fields to reflect the current number of assigned and available IP addresses.
Viewing the IPAddressPool status
Check IP address allocation from your MetalLB pools by viewing the IPAddressPool status. This status shows the number of addresses assigned to services and the number remaining available for assignment.
As a cluster administrator, you can add address pools to your cluster to control the IP addresses that MetalLB can assign to load-balancer services. This example shows how to create an IPAddressPool custom resource (CR) and view its status. The configuration sets the advertisement mode to Layer 2 (L2).
-
You have an OpenShift Container Platform cluster with the MetalLB Operator installed.
-
You have deployed a MetalLB instance.
-
Create an IP address pool.
-
Create a file, named for example
ipaddresspool.yaml, with content such as the following:apiVersion: metallb.io/v1beta1 kind: IPAddressPool metadata: name: doc-example-l2 namespace: metallb-system spec: addresses: - 192.168.122.200-192.168.122.220 autoAssign: true avoidBuggyIPs: false -
Apply the configuration for the IP address pool:
$ oc apply -f ipaddresspool.yaml
-
-
View the status of the IP address pool by running the following command:
$ oc get ipaddresspool doc-example-l2 -n metallb-system -o yamlThe output is similar to the following:
apiVersion: metallb.io/v1beta1 kind: IPAddressPool metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"metallb.io/v1beta1","kind":"IPAddressPool","metadata":{"annotations":{},"name":"doc-example-l2","namespace":"metallb-system"},"spec":{"addresses":["192.168.122.200-192.168.122.220"],"autoAssign":true,"avoidBuggyIPs":false}} creationTimestamp: "2025-07-17T10:13:37Z" generation: 1 name: doc-example-l2 namespace: metallb-system resourceVersion: "29080" uid: 8df1c303-03ac-4d31-8970-6dacdb173dc2 spec: addresses: - 192.168.122.200-192.168.122.220 autoAssign: true avoidBuggyIPs: false status: assignedIPv4: 0 assignedIPv6: 0 availableIPv4: 21 availableIPv6: 0-
assignedIPv4represents the total number of IPv4 addresses that MetalLB has successfully assigned from this pool toLoadBalancerservices. -
assignedIPv6represents the total number of IPv6 addresses that MetalLB has successfully assigned from this pool toLoadBalancerservices. -
availableIPv4indicates the total number of IPv4 addresses remaining and available for assignment within this pool. MetalLB calculates this value by subtractingassignedIPv4from the total theoretical IPv4 addresses in thespec.addressesranges, potentially accounting foravoidBuggyIPsif enabled. -
availableIPv6indicates the total number of IPv6 addresses remaining and available for assignment within this pool. The system calculates this value similarly toavailableIPv4, using the total theoretical IPv6 addresses in thespec.addressesranges.
-
-
Create an
L2AdvertisementCR for Layer 2 mode with the following sample YAML:apiVersion: metallb.io/v1beta1 kind: L2Advertisement metadata: name: l2advertisement namespace: metallb-system spec: ipAddressPools: - doc-example-l2-
Apply the configuration for the L2 advertisement by running the following command:
$ oc apply -f l2advertisement.yaml
-
-
Deploy an application and expose it with a
LoadBalancerservice.-
Create a file, like
nginx.yaml, with the following content to deploy an Nginx application:apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx spec: replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: quay.io/openshifttest/hello-openshift:multiarch ports: - containerPort: 8080 -
Apply the configuration by running the following command:
$ oc apply -f nginx.yaml -
Expose the deployment as a
LoadBalancerservice by creating a file, such asnginx-service.yaml, with content like the following:apiVersion: v1 kind: Service metadata: name: nginx-service namespace: default annotations: metallb.universe.tf/address-pool: doc-example-l2 spec: selector: app: nginx ports: - protocol: TCP port: 80 targetPort: 8080 type: LoadBalancerImportant
The service must be in the same namespace as your application deployment. The
metallb.universe.tf/address-poolannotation tells MetalLB whichIPAddressPoolto use for IP allocation. -
Apply the service configuration by running the following command:
$ oc apply -f nginx-service.yaml
-
-
View the updated
IPAddressPoolstatus to see the assigned and available IP addresses by running the following command:$ oc get ipaddresspool doc-example-l2 -n metallb-system -o yamlThe output is similar to the following:
apiVersion: metallb.io/v1beta1 kind: IPAddressPool metadata: annotations: kubectl.kubernetes.io/last-applied-configuration: | {"apiVersion":"metallb.io/v1beta1","kind":"IPAddressPool","metadata":{"annotations":{},"name":"doc-example-l2","namespace":"metallb-system"},"spec":{"addresses":["192.168.122.200-192.168.122.220"],"autoAssign":true,"avoidBuggyIPs":false}} creationTimestamp: "2025-07-17T10:13:37Z" generation: 1 name: doc-example-l2 namespace: metallb-system resourceVersion: "30250" uid: 8df1c303-03ac-4d31-8970-6dacdb173dc2 spec: addresses: - 192.168.122.200-192.168.122.220 autoAssign: true avoidBuggyIPs: false status: assignedIPv4: 1 assignedIPv6: 0 availableIPv4: 20 availableIPv6: 0The
assignedIPv4value of1indicates that one IPv4 address from this pool has been successfully assigned by MetalLB to yournginx-serviceLoadBalancer.
Viewing the ServiceBGPStatus custom resource
You can verify border gateway protocol (BGP) advertisement status for your services by viewing the ServiceBGPStatus custom resource, which shows which BGP peers receive advertisements from each node. This is essential for debugging connectivity in telco environments.
The ServiceBGPStatus CR reports the BGP peering status for a service, detailing which neighbors are receiving updates from a specific node.
Note
ServiceBGPStatus resources are created in the metallb-system namespace, not in the namespace where your LoadBalancer service is deployed. Always query these resources with -n metallb-system.
-
You have an OpenShift Container Platform cluster with the MetalLB Operator installed.
-
You have deployed a MetalLB instance.
This example shows how to configure MetalLB for BGP mode, deploy a service, and view the ServiceBGPStatus to verify BGP advertisements.
-
Create an
IPAddressPoolCR for BGP, like the following example, and save it asipaddresspool.yaml:apiVersion: metallb.io/v1beta1 kind: IPAddressPool metadata: name: bgp-pool namespace: metallb-system spec: addresses: - 192.168.122.210-192.168.122.220 autoAssign: true -
Run the following command to create the
IPAddressPoolconfiguration:$ oc apply -f ipaddresspool.yaml -
To configure a BGP peer, create a file named
bgppeer.yamlwith the following content:apiVersion: metallb.io/v1beta2 kind: BGPPeer metadata: name: bgp-peer namespace: metallb-system spec: myASN: 64501 peerASN: 64500 peerAddress: 192.168.1.1-
Set the
spec:peerAddressfield to the IP address of your BGP router.
-
-
Apply the BGPPeer configuration by running the following command:
$ oc apply -f bgppeer.yaml -
To create a BGP advertisement to advertise the pool, create a file named
bgpadvertisement.yamlwith the following content:apiVersion: metallb.io/v1beta1 kind: BGPAdvertisement metadata: name: bgp-advertisement namespace: metallb-system spec: ipAddressPools: - bgp-pool -
Apply the BGPAdvertisement configuration by running the following command:
$ oc apply -f bgpadvertisement.yaml -
Deploy an application and expose it with a
LoadBalancerservice. For this example, create a simple test application named for exampletest-appby creating a file nameddeployment.yamlwith the following content:apiVersion: apps/v1 kind: Deployment metadata: name: test-app namespace: default spec: replicas: 2 selector: matchLabels: app: test-app template: metadata: labels: app: test-app spec: containers: - name: test-app image: quay.io/openshifttest/hello-openshift:multiarch ports: - containerPort: 8080 -
Apply the deployment:
$ oc apply -f deployment.yaml -
Create a
LoadBalancerservice for the application:apiVersion: v1 kind: Service metadata: name: test-service namespace: default spec: selector: app: test-app ports: - protocol: TCP port: 80 targetPort: 8080 type: LoadBalancerImportant
The system creates
ServiceBGPStatusresources automatically only when the service has at least one ready endpoint (running pod). Ensure your application pods are running before checking forServiceBGPStatusresources. -
Apply the service configuration by running the following command:
$ oc apply -f service.yaml -
Verify the service received an external IP by running the following command:
$ oc get svc test-service -n defaultThe output is similar to the following:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE test-service LoadBalancer 172.30.116.108 192.168.122.210 80:32431/TCP 2m -
View the
ServiceBGPStatusresources by running the following command:$ oc get servicebgpstatus -n metallb-systemThe output is similar to the following:
NAME NODE SERVICE NAME SERVICE NAMESPACE bgp-xxxxx worker0 test-service defaultNote
ServiceBGPStatusresources are created with generated names. Use labels to find the status for your service:$ oc get servicebgpstatus -n metallb-system -l metallb.io/service-name=test-service -
View the details of the
ServiceBGPStatusCR for your service:$ oc get servicebgpstatus bgp-xxxxx -n metallb-system -o yamlThe output is similar to the following:
apiVersion: metallb.io/v1beta1 kind: ServiceBGPStatus metadata: name: bgp-xxxxx namespace: metallb-system labels: metallb.io/node: worker0 metallb.io/service-name: test-service metallb.io/service-namespace: default status: node: worker0 peers: - bgp-peer serviceName: test-service serviceNamespace: default-
metadata.labels.metallb.io/nodeindicates the node that is advertising the service via BGP. -
metadata.labels.metallb.io/service-nameidentifies the service being advertised. -
metadata.labels.metallb.io/service-namespaceidentifies the namespace of the service being advertised. -
status.nodeconfirms the name of the node advertising the service. -
status.peerslists the names of the BGPPeer resources to which the service is being advertised. This is useful for confirming that the advertisement is reaching the intended peers. -
status.serviceNameindicates the name of the service being advertised. -
status.serviceNamespaceindicates the namespace of the service being advertised.
-
Verifying BGP session state
Once you configure MetalLB for border gateway protocol (BGP) mode, you can verify that the system has established BGP sessions and is advertising routes. You can examine the BGPSessionStatus custom resource (CR) and the FRRNodeState CR to troubleshoot BGP connectivity and confirm proper route advertisement.
Note
The BGPSessionStatus CR is updated at a regular poll interval of 2 minutes. It can take up to 2 minutes for the CR to reflect the actual BGP state.
-
You have an OpenShift Container Platform cluster with the MetalLB Operator installed.
-
You have configured MetalLB for BGP mode with:
-
An
IPAddressPool -
A
BGPPeerconfiguration -
A
BGPAdvertisement
-
-
You have deployed at least one
LoadBalancerservice.
-
Check BGP session status by running the following command:
$ oc get bgpsessionstatus -o wideThis example output shows the BGP session status between each node and its configured BGP peers. Look for the
Statecolumn to confirm that the session isEstablished.NAMESPACE NAME NODE PEER VRF BGP BFD frr-k8s-system worker-2gjfq worker 10.89.0.64 Active N/A frr-k8s-system worker-9gtnb worker 10.89.0.63 Established N/A frr-k8s-system worker2-rknga worker2 10.89.0.66 Established Up frr-k8s-system worker2-t7bfc worker2 172.30.0.2 Established Down -
Check
FRRNodeStateto see the BGP configuration on each node by running the following command:$ oc get frrnodestate -n metallb-systemThe example output lists the
FRRNodeStateresources for each node where the MetalLB speaker is running.NAME AGE worker0.example.com 5m -
View the detailed BGP configuration and running state by running the following command for a specific node:
$ oc get frrnodestate worker0.example.com -n metallb-system -o yamlThe
status.runningConfigfield shows the FRR BGP configuration including configured BGP neighbors, route advertisements, and prefix lists. -
Verify that the system is advertising routes by checking the
FRRNodeStateresource for the relevant node with this command:$ oc get frrnodestate _<node-name>_ -n metallb-system -o jsonpath='{.status.runningConfig}' | grep "network"The output displays the network prefixes that BGP advertises. For example:
address-family ipv4 unicast network 192.168.122.210/32This confirms that BGP is advertising the service IP.