The module lifecycle stageGeneral Availability

Metallb can be used in Static (bare metal) clusters when there is no option to use cloud load balancers. Metallb can work in L2 LoadBalancer or BGP modes LoadBalancer.

Example of metallb usage in L2 LoadBalancer mode

Enable the module:

apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
  name: metallb
spec:
  enabled: true
  version: 2

Prepare the application to publish:

d8 k create deploy nginx --image=nginx

Create the MetalLoadBalancerClass resource:

apiVersion: network.deckhouse.io/v1alpha1
kind: MetalLoadBalancerClass
metadata:
  name: ingress
spec:
  addressPool:
    - 192.168.2.100-192.168.2.150
  isDefault: false
  nodeSelector:
    node-role.kubernetes.io/loadbalancer: "" # node-balancer selector
  type: L2

Create standard resource Service with special annotation and MetalLoadBalancerClass name:

apiVersion: v1
kind: Service
metadata:
  name: nginx-deployment
  annotations:
    network.deckhouse.io/l2-load-balancer-external-ips-count: "3"
spec:
  type: LoadBalancer
  loadBalancerClass: ingress # MetalLoadBalancerClass name
  ports:
  - port: 8000
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx

As a result, the created Service with the type LoadBalancer will be assigned the specified number of addresses:

d8 k get svc

Output example:

NAME                   TYPE           CLUSTER-IP      EXTERNAL-IP                                 PORT(S)        AGE
nginx-deployment       LoadBalancer   10.222.130.11   192.168.2.100,192.168.2.101,192.168.2.102   80:30544/TCP   11s

When creating a service, you can also specify certain IP addresses from the pool that will be assigned to it.

The resulting EXTERNAL-IP are ready to use in application DNS-domain:

$ curl -s -o /dev/null -w "%{http_code}" 192.168.2.100:8000
200
$ curl -s -o /dev/null -w "%{http_code}" 192.168.2.101:8000
200
$ curl -s -o /dev/null -w "%{http_code}" 192.168.2.102:8000
200

Example of metallb usage in BGP LoadBalancer mode

Enable the module and configure all the necessary parameters*:

apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
  name: metallb
spec:
  enabled: true
  settings:
    addressPools:
    - addresses:
      - 192.168.219.100-192.168.219.200
      name: mypool
      protocol: bgp
    bgpPeers:
    - hold-time: 3s
      my-asn: 64600
      peer-address: 172.18.18.10
      peer-asn: 64601
    speaker:
      nodeSelector:
        node-role.deckhouse.io/metallb: ""
  version: 2

* — in future versions, BGP mode settings will be set via the MetalLoadBalancerClass resource.

Configure BGP peering on the network equipment.

Additional configuration examples for Service

Creating a service and assigning it specific IP addresses from the pool

To specify the addresses that should be assigned to the service, use the annotation network.deckhouse.io/load-balancer-ips. If there is more than one desired address, there must also be an annotation network.deckhouse.io/l2-load-balancer-external-ips-count, which must specify the number of addresses allocated from the pool (it must not be less than the number of addresses listed in network.deckhouse.io/load-balancer-ips).

apiVersion: v1
kind: Service
metadata:
  name: nginx-deployment
  annotations:
    # The number of addresses that will be allocated from the pool declared in MetalLoadBalancerClass.
    network.deckhouse.io/l2-load-balancer-external-ips-count: "3"
    # A list of addresses from the pool declared in MetalLoadBalancerClass that will be allocated to the service.
    network.deckhouse.io/load-balancer-ips: "192.168.2.102,192.168.2.103,192.168.2.104"
spec:
  type: LoadBalancer
  loadBalancerClass: ingress # MetalLoadBalancerClass name
  ports:
  - port: 8000
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx

As a result, the created Service with the type LoadBalancer will be assigned the specified number of addresses:

d8 k get svc

Output example:

NAME                   TYPE           CLUSTER-IP      EXTERNAL-IP                                 PORT(S)        AGE
nginx-deployment       LoadBalancer   10.222.130.11   192.168.2.102,192.168.2.103,192.168.2.104   80:30544/TCP   11s

Creating a service with a single, forcibly selected address

To create a Service with a forcibly selected address, you need to add the annotation network.deckhouse.io/load-balancer-ips:

apiVersion: v1
kind: Service
metadata:
  name: nginx
  annotations:
    network.deckhouse.io/load-balancer-ips: 192.168.217.217
spec:
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: nginx
  type: LoadBalancer

Creating services with shared IP addresses

To create a Services with shared IP addresses, you need to add the annotation network.deckhouse.io/load-balancer-shared-ip-key. The value of the annotation is a “sharing key”. Services can share an IP address under the following conditions:

  • They have the same sharing key.
  • They request the use of different ports (e.g. tcp/80 for one and tcp/443 for the other).
  • They use the Cluster external traffic policy, or they both point to the exact same set of pods (i.e. the pod selectors are identical).

If these conditions are satisfied, MetalLB may colocate the two services on the same IP, but does not have to! If you want to ensure that they share a specific address, use the network.deckhouse.io/load-balancer-ips annotation described above.

Here is an example configuration of two services that share the same ip address:

apiVersion: v1
kind: Service
metadata:
  name: dns-service-tcp
  namespace: default
  annotations:
    network.deckhouse.io/load-balancer-shared-ip-key: "key-to-share-1.2.3.4"
spec:
  type: LoadBalancer
  ports:
    - name: dnstcp
      protocol: TCP
      port: 53
      targetPort: 53
  selector:
    app: dns
---
apiVersion: v1
kind: Service
metadata:
  name: dns-service-udp
  namespace: default
  annotations:
    network.deckhouse.io/load-balancer-shared-ip-key: "key-to-share-1.2.3.4"
spec:
  type: LoadBalancer
  ports:
    - name: dnsudp
      protocol: UDP
      port: 53
      targetPort: 53
  selector:
    app: dns

Creating a service and assigning IPAddressPools to it when using mettalb in BGP LoadBalancer mode

Creating a Service and assigning it IPAddressPools is possible in BGP LoadBalancer mode using the annotation metallb.universe.tf. For L2 LoadBalancer mode, you need to use the MetalLoadBalancerClass settings (see above).

apiVersion: v1
kind: Service
metadata:
  name: nginx
  annotations:
    metallb.universe.tf/address-pool: production-public-ips
spec:
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: nginx
  type: LoadBalancer