Monitoring MetalLB configuration status {id="monitoring-metallb-status""}
As an OpenShift Container Platform system administrator, you can monitor the operational status of your MetalLB deployment by examining 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.
Understand 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.
MetalLB status resources
| Resource | Description | Troubleshooting command |
|---|---|---|
IPAddressPool** (status field)** | 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. | oc get ipaddresspool _<IPAddressPool-name>_ -n metallb-system -o yaml |
ServiceBGPStatus | Shows which service IP addresses the system announces to specific BGP peers across the network infrastructure. | oc get servicebgpstatus -n metallb-system |
BGPSessionStatus | 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 Established or Up based on routing stack feedback. | oc get bgpsessionstatus -o wide |
ConfigurationState | Shows whether the MetalLB controller and speakers have successfully validated and applied the current configuration. MetalLB creates one resource for the controller and one for each speaker node. Reports errors when custom resources are incompatible. | oc get configurationstates -n metallb-system |
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.
View 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).
Prerequisites
- You have an OpenShift Container Platform cluster with the MetalLB Operator installed.
- You have deployed a MetalLB instance.
Procedure
-
Create an IP address pool.
- Create a file, named for example
ipaddresspool.yaml, with content such as the following:apiVersion: metallb.io/v1beta1kind: IPAddressPoolmetadata:name: doc-example-l2namespace: metallb-systemspec:addresses:- 192.168.122.200-192.168.122.220autoAssign: trueavoidBuggyIPs: false - Apply the configuration for the IP address pool:
$ oc apply -f ipaddresspool.yaml
- Create a file, named for example
-
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/v1beta1kind: IPAddressPoolmetadata: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: 1name: doc-example-l2namespace: metallb-systemresourceVersion: "29080"uid: 8df1c303-03ac-4d31-8970-6dacdb173dc2spec:addresses:- 192.168.122.200-192.168.122.220autoAssign: trueavoidBuggyIPs: falsestatus:assignedIPv4: 0assignedIPv6: 0availableIPv4: 21availableIPv6: 0assignedIPv4represents 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/v1beta1kind: L2Advertisementmetadata:name: l2advertisementnamespace: metallb-systemspec:ipAddressPools:- doc-example-l2- Apply the configuration for the L2 advertisement by running the following command:
$ oc apply -f l2advertisement.yaml
- Apply the configuration for the L2 advertisement by running the following command:
-
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/v1kind: Deploymentmetadata:name: nginx-deploymentlabels:app: nginxspec:replicas: 2selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: quay.io/openshifttest/hello-openshift:multiarchports:- 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: v1kind: Servicemetadata:name: nginx-servicenamespace: defaultannotations:metallb.universe.tf/address-pool: doc-example-l2spec:selector:app: nginxports:- protocol: TCPport: 80targetPort: 8080type: LoadBalancerwarningThe 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/v1beta1kind: IPAddressPoolmetadata: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: 1name: doc-example-l2namespace: metallb-systemresourceVersion: "30250"uid: 8df1c303-03ac-4d31-8970-6dacdb173dc2spec:addresses:- 192.168.122.200-192.168.122.220autoAssign: trueavoidBuggyIPs: falsestatus:assignedIPv4: 1assignedIPv6: 0availableIPv4: 20availableIPv6: 0The
assignedIPv4value of1indicates that one IPv4 address from this pool has been successfully assigned by MetalLB to yournginx-serviceLoadBalancer.
View 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.
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.
Prerequisites
- 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.
Procedure
-
Create an
IPAddressPoolCR for BGP, like the following example, and save it asipaddresspool.yaml:apiVersion: metallb.io/v1beta1kind: IPAddressPoolmetadata:name: bgp-poolnamespace: metallb-systemspec:addresses:- 192.168.122.210-192.168.122.220autoAssign: 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/v1beta2kind: BGPPeermetadata:name: bgp-peernamespace: metallb-systemspec:myASN: 64501peerASN: 64500peerAddress: 192.168.1.1- Set the
spec:peerAddressfield to the IP address of your BGP router.
- Set the
-
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/v1beta1kind: BGPAdvertisementmetadata:name: bgp-advertisementnamespace: metallb-systemspec: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/v1kind: Deploymentmetadata:name: test-appnamespace: defaultspec:replicas: 2selector:matchLabels:app: test-apptemplate:metadata:labels:app: test-appspec:containers:- name: test-appimage: quay.io/openshifttest/hello-openshift:multiarchports:- containerPort: 8080 -
Apply the deployment:
$ oc apply -f deployment.yaml -
Create a
LoadBalancerservice for the application:apiVersion: v1kind: Servicemetadata:name: test-servicenamespace: defaultspec:selector:app: test-appports:- protocol: TCPport: 80targetPort: 8080type: LoadBalancerwarningThe 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) AGEtest-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 NAMESPACEbgp-xxxxx worker0 test-service defaultnoteServiceBGPStatusresources 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/v1beta1kind: ServiceBGPStatusmetadata:name: bgp-xxxxxnamespace: metallb-systemlabels:metallb.io/node: worker0metallb.io/service-name: test-servicemetallb.io/service-namespace: defaultstatus:node: worker0peers:- bgp-peerserviceName: test-serviceserviceNamespace: defaultmetadata.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.
Verify 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 BGPSessionState custom resource (CR) and the FRRNodeState CR to troubleshoot BGP connectivity and confirm proper route advertisement.
The BGPSessionState 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.
Prerequisites
- 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
- An
- You have deployed at least one
LoadBalancerservice.
Procedure
-
Check BGP session status by running the following command:
$ oc get bgpsessionstates.frrk8s.metallb.io -A -o wideThis example output shows the BGP session status between each node and its configured BGP peers. Look for the
BGPcolumn to confirm that the session isEstablished.NAMESPACE NAME NODE PEER VRF BGP BFDopenshift-frr-k8s worker-2gjfq worker 10.89.0.64 Active N/Aopenshift-frr-k8s worker-9gtnb worker 10.89.0.63 Established N/Aopenshift-frr-k8s worker2-rknga worker2 10.89.0.66 Established Upopenshift-frr-k8s 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 AGEworker0.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 unicastnetwork 192.168.122.210/32This confirms that BGP is advertising the service IP.
Check MetalLB configuration status
You can verify that the MetalLB controller and speakers have successfully applied the current configuration by viewing the ConfigurationState custom resource (CR). MetalLB creates a ConfigurationState resource for the controller and one for each speaker node.
These resources report whether the configuration is valid and surface error details when validation fails, such as incompatible custom resources.
Prerequisites
- You have an OpenShift Container Platform cluster with the MetalLB Operator installed.
- You have deployed a MetalLB instance.
- You have configured MetalLB resources such as
IPAddressPool,BGPPeer,BFDProfile,Community, orFRRConfiguration.
Procedure
-
List the
ConfigurationStateresources by running the following command:$ oc get configurationstates -n metallb-systemExample outputNAME RESULT ERRORSUMMARY AGEcontroller Valid 75mspeaker-mysno-sno.demo.lab Valid 28mThe
controllerresource shows the status for the MetalLB controller. Eachspeaker-<node-name>resource shows the status for the speaker on that node. -
Verify that the controller has a valid configuration by inspecting the
ConfigurationStatedetails. Run the following command:$ oc get configurationstates controller -n metallb-system -o yamlExample outputapiVersion: metallb.io/v1beta1kind: ConfigurationStatemetadata:creationTimestamp: "2026-04-21T09:46:47Z"generation: 1labels:metallb.io/component-type: controllername: controllernamespace: metallb-systemresourceVersion: "28268"uid: 23f5c492-4d5c-4893-84ea-77904c006404status:conditions:- lastTransitionTime: "2026-04-21T09:54:00Z"message: ""reason: Reconciledstatus: "True"type: poolReconcilerValidresult: ValidConfirm that the output has the following values:
-
result: Validindicates that all configured resources are compatible and active. If this value isInvalid, check theerrorSummaryfield for aggregated error messages that identify which part of the configuration has failed. -
message: Describes any configuration problem that occurs. Here,""` confirms that no errors were reported. -
reason: Reconciledwithstatus: "True"confirms that the reconciler has successfully processed the configuration. If thereasonisReconciliationFailedandstatusis"False", themessagefield contains details about the failure.noteThe controller does not validate peer-level settings. Errors such as a missing
BFDProfile, undefinedCommunity, or missing authentication secret are reported only by the speakers. AValidcontroller with one or moreInvalidspeakers is expected in these cases. Always check both controller and speakerConfigurationStateresources.If the configuration is invalid, the output is similar to the following example:
apiVersion: metallb.io/v1beta1kind: ConfigurationStatemetadata:creationTimestamp: "2026-04-21T09:51:17Z"generation: 1labels:metallb.io/component-type: speakermetallb.io/node-name: mysno-sno.demo.labname: speaker-mysno-sno.demo.labnamespace: metallb-systemresourceVersion: "31161"uid: 339781bf-ec9a-4ba9-aaba-0a9ac8ebce78status:conditions:- lastTransitionTime: "2026-04-21T10:09:34Z"message: 'configuration error: peer peer1 referencing non existing bfd profilemy-bfd-profile'reason: ConfigurationErrorstatus: "False"type: configReconcilerValiderrorSummary: 'configuration error: peer peer1 referencing non existing bfd profilemy-bfd-profile'result: InvalidConfirm that the output has the following values to identify the problem:
-
result: Invalidindicates that one or more configured resources are incompatible. TheerrorSummaryfield provides an aggregated description of the problem. -
reason: ConfigurationErrorwithstatus: "False"indicates that the reconciler failed to process the configuration. Themessagefield describes the specific error. -
In this example, the
BGPPeerresourcepeer1references aBFDProfilenamedmy-bfd-profilethat does not exist. To resolve this error, either create the missingBFDProfileresource or update theBGPPeerto reference an existingBFDProfile.noteThe
ConfigurationStateresource does not report errors that arise when the configuration applied by the speaker to thefrr-k8sdaemon conflicts with other external configurations within that daemon.
-
-
After correcting the configuration, verify that the status shows a valid configuration by running the following command:
$ oc get configurationstates -n metallb-system -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.result}{"\n"}{end}'A return value of
Validfor all entries confirms that the MetalLB controller and speakers are operating with a valid configuration.
Additional resources