¿Cómo iniciar y detener una unidad systemd con otra?

20

Estoy usando CoreOS para programar unidades systemd con flota. Tengo dos unidades ( firehose.servicey firehose-announce.service. Estoy tratando de firehose-announce.serviceiniciar y detener junto con el firehose.service. Aquí está el archivo de la unidad para firehose-announce.service:

[Unit]
Description=Firehose etcd announcer
BindsTo=firehose@%i.service
After=firehose@%i.service
Requires=firehose@%i.service

[Service]
EnvironmentFile=/etc/environment
TimeoutStartSec=30s
ExecStartPre=/bin/sh -c 'sleep 1'
ExecStart=/bin/sh -c "port=$(docker inspect -f '{{range $i, $e := .NetworkSettings.Ports }}{{$p := index $e 0}}{{$p.HostPort}}{{end}}' firehose-%i); echo -n \"Adding socket $COREOS_PRIVATE_IPV4:$port/tcp to /firehose/upstream/firehose-%i\"; while netstat -lnt | grep :$port >/dev/null; do etcdctl set /firehose/upstream/firehose-%i $COREOS_PRIVATE_IPV4:$port --ttl 300 >/dev/null; sleep 200; done"
RestartSec=30s
Restart=on-failure

[X-Fleet]
X-ConditionMachineOf=firehose@%i.service

Estoy tratando de usar BindsTocon la idea de que start y stop firehose.servicetambién comenzará o se detendrá firehose-announce.service. Pero esto nunca sucede correctamente. Si firehose.servicese detiene, firehose-announce.servicepasa al estado fallido. Pero cuando comienzo firehose.service, firehose-announce.serviceno se inicia.

¿Qué estoy haciendo mal aquí?

Andy Shinn
fuente
El mismo problema aqui. ¿Has encontrado una solución?
nahime

Respuestas:

24

Parece que finalmente me topé con la combinación correcta para que esto funcionara como lo deseaba.

En mi firehose-announce.serviceunidad solo configuro un BindsTo. Toda la unidad es:

[Unit]
Description=Firehose etcd announcer
BindsTo=firehose@%i.service

[Service]
EnvironmentFile=/etc/environment
TimeoutStartSec=30s
ExecStartPre=/bin/sh -c 'sleep 1'
ExecStart=/bin/sh -c "port=$(docker inspect -f '{{range $i, $e := .NetworkSettings.Ports }}{{$p := index $e 0}}{{$p.HostPort}}{{end}}' firehose-%i); echo -n \"Adding socket $COREOS_PRIVATE_IPV4:$port/tcp to /firehose/upstream/firehose-%i\"; while netstat -lnt | grep :$port >/dev/null; do etcdctl set /firehose/upstream/firehose-%i $COREOS_PRIVATE_IPV4:$port --ttl 300 >/dev/null; sleep 200; done"
RestartSec=30s
Restart=on-failure

[X-Fleet]
X-ConditionMachineOf=firehose@%i.service

Esto hará que la firehose-announce.serviceunidad se detenga cuando lo firehose.servicehaga. Excelente. Pero, ¿cómo lo iniciamos de nuevo?

Invierto la dependencia para estar en mi firehose.serviceunidad así:

[Unit]
Description=Firehose server
Wants=firehose-announce@%i.service
Before=firehose-announce@%i.service

[Service]
ExecStartPre=/usr/bin/docker pull firehose/server
ExecStartPre=-/usr/bin/docker rm -f firehose-%i
ExecStart=/usr/bin/docker run --name firehose-%i -p 7474 --env-file /home/core/firehose.env firehose/server
ExecStop=/usr/bin/docker rm -f firehose-%i
User=core
TimeoutStartSec=5m
TimeoutStopSec=20s
RestartSec=30s
Restart=on-failure

[Install]
WantedBy=multi-user.target

[X-Fleet]
X-Conflicts=firehose@*.service

Esto significa que firehose.servicequiere firehose-announce.serviceiniciarse cuando lo hace (pero no falle si firehose-announce.serviceno puede iniciarse). También se asegura de que firehose.servicecomience antes firehose-announce.service.

Probé esto y las unidades ahora parecen detenerse y comenzar juntas como se desea.

Andy Shinn
fuente
Genial, lo intentaré.
nahime
1
Aparentemente, quiere = significa opcional. Requiere = es un requisito. BindsTo significa que si la dependencia, es decir, el servicio de manguera de incendios se detiene, entonces el servicio de anuncio de manguera de incendios también se considera detenido. Suena como algo bueno para mí.
Matt
¿Es posible obtener este comportamiento sin tocar firehouse.service?
buddy123
Intenté esta solución, pero me encuentro con un problema. Tengo el servicio A con Requiere = B. servicio y el servicio B con BindsTo = A. servicio. Cuando A sale anormalmente, veo que A y B se reinician. Pero cuando A sale con el código 0 / SUCESS, ambos permanecen en estado detenido
Bug Killer el
ExecStartPre = {dash} -no sirve para nada en el último y solo sirve para todo excepto el último ExecStartPre
meffect