--- title: Configuration weight: 4 --- MetalLB remains idle until configured. This is accomplished by creating and deploying various resources into **the same namespace** (metallb-system) MetalLB is deployed into. There are various examples of the configuration CRs in [`configsamples`](https://github.com/metallb/metallb/tree/main/configsamples). Also, the API is [fully documented here](../apis/). {{% notice note %}} If you installed MetalLB with Helm, you will need to change the namespace of the CRs to match the namespace in which MetalLB was deployed. {{% /notice %}} ## Defining the IPs to assign to the Load Balancer services In order to assign an IP to the services, MetalLB must be instructed to do so via the `IPAddressPool` CR. All the IPs allocated via `IPAddressPool`s contribute to the pool of IPs that MetalLB uses to assign IPs to services. ```yaml apiVersion: metallb.io/v1beta1 kind: IPAddressPool metadata: name: first-pool namespace: metallb-system spec: addresses: - 192.168.10.0/24 - 192.168.9.1-192.168.9.5 - fc00:f853:0ccd:e799::/124 ``` Multiple instances of `IPAddressPool`s can co-exist and addresses can be defined by CIDR, by range, and both IPV4 and IPV6 addresses can be assigned. ## Announce the service IPs Once the IPs are assigned to a service, they must be announced. The specific configuration depends on the protocol(s) you want to use to announce service IPs. Jump to: - [Layer 2 configuration](#layer-2-configuration) - [BGP configuration](#bgp-configuration) - [Advanced BGP configuration](./_advanced_bgp_configuration) - [Advanced L2 configuration](./_advanced_l2_configuration) - [Advanced IPAddressPool configuration](./_advanced_ipaddresspool_configuration) Note: it is possible to announce the same service both via L2 and via BGP (see the relative [FAQ](../faq/_index.md)). ## Layer 2 configuration Layer 2 mode is the simplest to configure: in many cases, you don't need any protocol-specific configuration, only IP addresses. Layer 2 mode does not require the IPs to be bound to the network interfaces of your worker nodes. It works by responding to ARP requests on your local network directly, to give the machine's MAC address to clients. In order to advertise the IP coming from an `IPAddressPool`, an `L2Advertisement` instance must be associated to the `IPAddressPool`. For example, the following configuration gives MetalLB control over IPs from `192.168.1.240` to `192.168.1.250`, and configures Layer 2 mode: ```yaml apiVersion: metallb.io/v1beta1 kind: IPAddressPool metadata: name: first-pool namespace: metallb-system spec: addresses: - 192.168.1.240-192.168.1.250 ``` ```yaml apiVersion: metallb.io/v1beta1 kind: L2Advertisement metadata: name: example namespace: metallb-system ``` Setting no `IPAddressPool` selector in an `L2Advertisement` instance is interpreted as that instance being associated to all the `IPAddressPool`s available. So in case there are specialized `IPAddressPool`s, and only some of them must be advertised via L2, the list of `IPAddressPool`s we want to advertise the IPs from must be declared (alternative, a label selector can be used). ```yaml apiVersion: metallb.io/v1beta1 kind: L2Advertisement metadata: name: example namespace: metallb-system spec: ipAddressPools: - first-pool ``` ## BGP configuration MetalLB needs to be instructed on how to establish a session with one or more external BGP routers. In order to do so, an instance of `BGPPeer` must be created for each router we want metallb to connect to. {{% notice note %}} The BGPPeer v1beta1 version is deprecated. Please consider using v1beta2. {{% /notice %}} For a basic configuration featuring one BGP router and one IP address range, you need 4 pieces of information: - The router IP address that MetalLB should connect to, - The router's AS number, - The AS number MetalLB should use, - An IP address range expressed as a CIDR prefix. As an example if you want to give MetalLB AS number 64500, and connect it to a router at 10.0.0.1 with AS number 64501, your configuration will look like: ```yaml apiVersion: metallb.io/v1beta2 kind: BGPPeer metadata: name: sample namespace: metallb-system spec: myASN: 64500 peerASN: 64501 peerAddress: 10.0.0.1 ``` Given an `IPAddressPool` like: ```yaml apiVersion: metallb.io/v1beta1 kind: IPAddressPool metadata: name: first-pool namespace: metallb-system spec: addresses: - 192.168.1.240-192.168.1.250 ``` MetalLB must be configured to advertise the IPs coming from it via BGP. This is done via the `BGPAdvertisement` CR. ```yaml apiVersion: metallb.io/v1beta1 kind: BGPAdvertisement metadata: name: example namespace: metallb-system ``` Setting no `IPAddressPool` selector in a `BGPAdvertisement` instance is interpreted as that instance being associated to all the `IPAddressPool`s available. So in case there are specialized `AddressPool`s, and only some of them must be advertised via BGP, the list of `ipAddressPool`s we want to advertise the IPs from must be declared (alternative, a label selector can be used). ```yaml apiVersion: metallb.io/v1beta1 kind: BGPAdvertisement metadata: name: example namespace: metallb-system spec: ipAddressPools: - first-pool ``` ### Enabling BFD support for BGP sessions With the FRR-based modes (FRR-K8s or FRR), BGP sessions can be backed up by BFD sessions in order to provide a quicker path failure detection than BGP alone provides. In order to enable BFD, a BFD profile must be added and referenced by a given peer: ```yaml apiVersion: metallb.io/v1beta1 kind: BFDProfile metadata: name: testbfdprofile namespace: metallb-system spec: receiveInterval: 380 transmitInterval: 270 ``` ```yaml apiVersion: metallb.io/v1beta2 kind: BGPPeer metadata: name: peersample namespace: metallb-system spec: myASN: 64512 peerASN: 64512 peerAddress: 172.30.0.3 bfdProfile: testbfdprofile ``` ## Configuration validation MetalLB ships validation webhooks that check the validity of the CRs applied. However, due to the fact that the global MetalLB configuration is composed by different pieces, not all of the invalid configurations are blocked by those webhooks. Because of that, if a non valid MetalLB configuration is applied, MetalLB discards it and keeps using the last valid configuration. In future releases MetalLB will expose misconfigurations as part of Kubernetes resources, but currently the only way to understand why the configuration was not loaded is by checking the controller's logs.