The module lifecycle stage: General 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 annotationnetwork.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 innetwork.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