Binding two SystemD-services to manage Loadbalancer IPVS

We have demonstrated how to makeĀ scalable resilient UDP service behindĀ  IPVS load-balancer.

In this article we will see how we can bind two systemd services (one is the process on a given port and the other is registering it to IPVS)

Requires, Before and After

When you write systemd unit files for two dependent systemd services, let’s say A then B, usually we specify both “Requires and “After” for example, in B.service you specify “Requires=A.service” and “After=A.service” which imply that A.service is “Before=B.service”

The order of “Before” and “After” is reversed when you stop the service.

How “BindsTo” work

Refer to “systemd.unit” manual page for details, in short it’s just like Requires but it if it’s down it would take the other one with it.

So if the process died it will be removed from the load-balancer. If it’s up it’s added. When you stop a process, first it would be removed from load-balanced then stopped.

Our unit file that launch the service on a given port looks like this


Description=Aggron UDP Server on port %I
Before=aggron-udp-lb@%i.service aggron-udp-lb@%i.service

ExecStart=bash -c "cd ~/aggron/ && exec ./ udp_server port=%i"


And the unit file for the service that register it in IPVS load-balancer


Description=LoadBalancer for Aggron UDP Server on port %I aggron-udp@%i.service aggron-udp@%i.service

ExecStart=/bin/bash -c "exec /sbin/ipvsadm -a -u $IP:7000 -r $IP:%i -m"
ExecStop=-/bin/bash -c "exec /sbin/ipvsadm -d -u $IP:7000 -r $IP:%i"


Note that the first service is running as a user while the other is a single shot command (no running daemon) executed as root.