How to create composite systemd unit

One way is to have all three services depend on the remaining two using Requires=.

  • one.service: Requires=two.service three.service
  • two.service: Requires=one.service three.service
  • three.service: etc.

This won't create a loop – dependencies are independent from startup ordering.

(That said, you should declare some Before= or After=, e.g. if kafka needs to run after zookeeper.)


The other method is to create a .target unit, have it depend on your three services, and the services be PartOf= the unit. (Unfortunately it is not yet possible to have ConsistsOf= in the .target itself.)

  • all.target: Requires=one.service two.service three.service
  • one.service: PartOf=all.target
  • etc.

(Again, you should additionally declare dependencies and ordering between the services; don't rely only on the .target starting everything.)


Yes, there are a few ways to accomplish that.

The simplest one (which does some of what uou describe, but not all) is to create a target unit and add dependencies on your service units (for example, Requires=zookeeper.service kafka.service elassandra.service and also set After= to the same units.) A target unit is helpful in starting all these units together, but it doesn't really help you stop them all together (using systemctl stop on the target unit won't stop its dependencies.) There are ways you can stop units, for example systemctl isolate multi-user.target will stop all units that are not dependencies of that target, which means units started manually will be stopped, but this is much stronger than stopping a small set of units, so probably not a great fit...

A better approach is perhaps using the PartOf= directive, which does exactly as you describe. You can either create a "dummy" service unit to manage all services together, or pick one of your services and make the others PartOf that one service.

You need to configure PartOf= in all the units you want to start and stop together, in your case, zookeeper.service, kafka.service and elassandra.service. But please note you don't necessarily need to modify the service unit files themselves (for example, if they're shipped with the software itself in deb or rpm packages.) You can use override files (which you can create using systemctl edit) to add a small configuration snippet to an existing unit, which should make it easy for you to define PartOf= relationships between units even if they're defined in files you would prefer not to modify.

Tags:

Systemd