Configuring services to use MetalLB

As a cluster administrator, when you add a service of type LoadBalancer, you can control how MetalLB assigns an IP address.

Request a specific IP address

Like some other load-balancer implementations, MetalLB accepts the spec.loadBalancerIP field in the service specification.

If the requested IP address is within a range from any address pool, MetalLB assigns the requested IP address. If the requested IP address is not within any range, MetalLB reports a warning.

Example service YAML for a specific IP address

  1. apiVersion: v1
  2. kind: Service
  3. metadata:
  4. name: <service_name>
  5. annotations:
  6. metallb.universe.tf/address-pool: <address_pool_name>
  7. spec:
  8. selector:
  9. <label_key>: <label_value>
  10. ports:
  11. - port: 8080
  12. targetPort: 8080
  13. protocol: TCP
  14. type: LoadBalancer
  15. loadBalancerIP: <ip_address>

If MetalLB cannot assign the requested IP address, the EXTERNAL-IP for the service reports <pending> and running oc describe service <service_name> includes an event like the following example.

Example event when MetalLB cannot assign a requested IP address

  1. ...
  2. Events:
  3. Type Reason Age From Message
  4. ---- ------ ---- ---- -------
  5. Warning AllocationFailed 3m16s metallb-controller Failed to allocate IP for "default/invalid-request": "4.3.2.1" is not allowed in config

Request an IP address from a specific pool

To assign an IP address from a specific range, but you are not concerned with the specific IP address, then you can use the metallb.universe.tf/address-pool annotation to request an IP address from the specified address pool.

Example service YAML for an IP address from a specific pool

  1. apiVersion: v1
  2. kind: Service
  3. metadata:
  4. name: <service_name>
  5. annotations:
  6. metallb.universe.tf/address-pool: <address_pool_name>
  7. spec:
  8. selector:
  9. <label_key>: <label_value>
  10. ports:
  11. - port: 8080
  12. targetPort: 8080
  13. protocol: TCP
  14. type: LoadBalancer

If the address pool that you specify for <address_pool_name> does not exist, MetalLB attempts to assign an IP address from any pool that permits automatic assignment.

Accept any IP address

By default, address pools are configured to permit automatic assignment. MetalLB assigns an IP address from these address pools.

To accept any IP address from any pool that is configured for automatic assignment, no special annotation or configuration is required.

Example service YAML for accepting any IP address

  1. apiVersion: v1
  2. kind: Service
  3. metadata:
  4. name: <service_name>
  5. spec:
  6. selector:
  7. <label_key>: <label_value>
  8. ports:
  9. - port: 8080
  10. targetPort: 8080
  11. protocol: TCP
  12. type: LoadBalancer

Share a specific IP address

By default, services do not share IP addresses. However, if you need to colocate services on a single IP address, you can enable selective IP sharing by adding the metallb.universe.tf/allow-shared-ip annotation to the services.

  1. apiVersion: v1
  2. kind: Service
  3. metadata:
  4. name: service-http
  5. annotations:
  6. metallb.universe.tf/address-pool: doc-example
  7. metallb.universe.tf/allow-shared-ip: "web-server-svc" (1)
  8. spec:
  9. ports:
  10. - name: http
  11. port: 80 (2)
  12. protocol: TCP
  13. targetPort: 8080
  14. selector:
  15. <label_key>: <label_value> (3)
  16. type: LoadBalancer
  17. loadBalancerIP: 172.31.249.7 (4)
  18. ---
  19. apiVersion: v1
  20. kind: Service
  21. metadata:
  22. name: service-https
  23. annotations:
  24. metallb.universe.tf/address-pool: doc-example
  25. metallb.universe.tf/allow-shared-ip: "web-server-svc" (1)
  26. spec:
  27. ports:
  28. - name: https
  29. port: 443 (2)
  30. protocol: TCP
  31. targetPort: 8080
  32. selector:
  33. <label_key>: <label_value> (3)
  34. type: LoadBalancer
  35. loadBalancerIP: 172.31.249.7 (4)
1Specify the same value for the metallb.universe.tf/allow-shared-ip annotation. This value is referred to as the sharing key.
2Specify different port numbers for the services.
3Specify identical pod selectors if you must specify externalTrafficPolicy: local so the services send traffic to the same set of pods. If you use the cluster external traffic policy, then the pod selectors do not need to be identical.
4Optional: If you specify the three preceding items, MetalLB might colocate the services on the same IP address. To ensure that services share an IP address, specify the IP address to share.

By default, Kubernetes does not allow multiprotocol load balancer services. This limitation would normally make it impossible to run a service like DNS that needs to listen on both TCP and UDP. To work around this limitation of Kubernetes with MetalLB, create two services:

  • For one service, specify TCP and for the second service, specify UDP.

  • In both services, specify the same pod selector.

  • Specify the same sharing key and spec.loadBalancerIP value to colocate the TCP and UDP services on the same IP address.

Configuring a service with MetalLB

You can configure a load-balancing service to use an external IP address from an address pool.

Prerequisites

  • Install the OpenShift CLI (oc).

  • Install the MetalLB Operator and start MetalLB.

  • Configure at least one address pool.

  • Configure your network to route traffic from the clients to the host network for the cluster.

Procedure

  1. Create a <service_name>.yaml file. In the file, ensure that the spec.type field is set to LoadBalancer.

    Refer to the examples for information about how to request the external IP address that MetalLB assigns to the service.

  2. Create the service:

    1. $ oc apply -f <service_name>.yaml

    Example output

    1. service/<service_name> created

Verification

  • Describe the service:

    1. $ oc describe service <service_name>

    Example output

    1. Name: <service_name>
    2. Namespace: default
    3. Labels: <none>
    4. Annotations: metallb.universe.tf/address-pool: doc-example (1)
    5. Selector: app=service_name
    6. Type: LoadBalancer (2)
    7. IP Family Policy: SingleStack
    8. IP Families: IPv4
    9. IP: 10.105.237.254
    10. IPs: 10.105.237.254
    11. LoadBalancer Ingress: 192.168.100.5 (3)
    12. Port: <unset> 80/TCP
    13. TargetPort: 8080/TCP
    14. NodePort: <unset> 30550/TCP
    15. Endpoints: 10.244.0.50:8080
    16. Session Affinity: None
    17. External Traffic Policy: Cluster
    18. Events: (4)
    19. Type Reason Age From Message
    20. ---- ------ ---- ---- -------
    21. Normal nodeAssigned 32m (x2 over 32m) metallb-speaker announcing from node "<node_name>"
    1The annotation is present if you request an IP address from a specific pool.
    2The service type must indicate LoadBalancer.
    3The load-balancer ingress field indicates the external IP address if the service is assigned correctly.
    4The events field indicates the node name that is assigned to announce the external IP address. If you experience an error, the events field indicates the reason for the error.