Birkaç örneği birlikte durdurmak / başlatmak için bir sanal systemd hizmeti nasıl oluşturulur?


12

Kullanan müşteriler için aynı web uygulamasının birkaç örneğini barındırmayı planlıyorum systemd. Ben edebilmek istiyorum stopve starther bir müşteri örneği kullanılarak systemd, hem de bir araya durdurulup başlatılabilir tek hizmet olarak müşteri örneklerinin koleksiyonun tamamını tedavi.

systemdkullanmam gereken yapı taşlarını PartOfve şablon birimi dosyalarını sağlıyor gibi görünüyor , ancak ana hizmeti durdurdum, çocuk müşteri hizmetleri durdurulmadı. Bunu systemd ile nasıl çalıştırabilirim? İşte şimdiye kadar sahip olduğum şey.

Üst birim dosyası app.service:

[Unit]
Description=App Web Service

[Service]
# Don't run as a deamon (because we've got nothing to do directly)
Type=oneshot
# Just print something, because ExecStart is required
ExecStart=/bin/echo "App Service exists only to collectively start and stop App instances"
# Keep running after Exit start finished, because we want the instances that depend on this to keep running
RemainAfterExit=yes
StandardOutput=journal

app@.serviceMüşteri örnekleri oluşturmak için kullanılan, adlandırılmış bir birim şablonu dosyası :

[Unit]
Description=%I Instance of App Web Service

[Service]
PartOf=app.service
ExecStart=/home/mark/bin/app-poc.sh %i
StandardOutput=journal

Benim app-poc.shsenaryom (sadece bir döngüdeki günlük dosyasına yazdırmak için kavram kanıtı):

#!/bin/bash
# Just a temporary code to fake a full daemon.
while :
do
  echo "The App PoC loop for $@"
  sleep 2;
done

Kavramın kanıtı için, systemd birim dosyalarını içeri aldım ~/.config/systemd/user.

Daha sonra üst ve şablon (sonra systemctl --user daemon-reload) dayalı bir örnek başlatmak :

systemctl --user start app
systemctl --user start app@customer.service

Kullanarak journalctl -fhem başlatıldığını hem de müşteri örneğinin çalışmaya devam ettiğini görebiliyorum. Şimdi ben ebeveynin kapatılmasını bekliyorum çocuğu durduracak (çünkü kullandım PartOf), ama durmuyor. Ayrıca, ebeveynin başlatılması da çocuğu beklendiği gibi başlatmaz.

systemctl --user stop app

Teşekkürler!

(Sistemd 229 ile Ubuntu 16.04 kullanıyorum).


1
"PartOf = Require = 'a benzer bağımlılıkları yapılandırır, ancak birimlerin durdurulması ve yeniden başlatılmasıyla sınırlıdır." Çalışmaya başlamak istiyorsanız, Requires=bunun yerine kullanmanıza gerek yok mu?
sourcejedi

Yanıtlar:


10

Çizgiyi hareket ettirmelisin

PartOf=app.service

dışına [Service]ve içine [Unit]etmek bölümünde ve ekleme [Unit]ait app.servicemüşterilerinin listesine başlamak için, örneğin

Wants=app@customer1.service app@customer2.service

veya sourcejedi'nin yorumlarda söylediği gibi Requires=, aynı şey. PartOfYukarıdaki listede yer almayan el ile başlattığınız hizmetleri durdurmak gibi tutabilirsiniz systemctl --user start app@customer3.service.


Haklı olduğunu doğruladım PartOf. Teşekkürler. Ben sistemd ile yeni bir müşteri etkinleştirmek için gereken tek eylem haline bir symlink aracılığıyla "İstiyor" başa çıkacağım. Test durumum için: `ln -s /home/mark/.config/systemd/user/app@.service / home / mark / .config / systemd / user / app.service.wants / unity @ foo.service`
Mark Stosberg

14

Bunun için "Hedef Birimler" sisteminin ne olduğunu öğrendim. Bir Hedef Birim kullanarak [Service], yukarıda sahip olduğum sahte bölümü oluşturmaya gerek kalmadan istediğim faydaları elde ederim . Çalışan bir örnek "Hedef Birim" dosyası şöyle görünür:

# named like app.target
[Unit]
Description=App Web Service

# This collection of apps should be started at boot time.
[Install]
WantedBy=multi-user.target

Daha sonra her müşteri örneği içermelidir PartOfiçinde [Unit](@meuh tarafından sivri out gibi) bölümünde ve ayrıca bir olması gereken [Install]böylece bölüm enableve disableözel güvenlik elemanları üzerinde çalışacak:

# In a file name like app@.service
[Unit]
Description=%I Instance of App Web Service
PartOf=app.target

[Service]
ExecStart=/home/mark/bin/app-poc.sh %i
Restart=on-failure
StandardOutput=journal

# When the service runs globally, make it run as a particular user for added security
#User=myapp
#Group=myapp

# When systemctl enable is used, make this start when the App service starts
[Install]
WantedBy=app.target

Müşteri örneğini getirmek ve hedef başlatıldığında başlatılmasını sağlamak için bu tek seferlik etkinleştirme komutu kullanılır:

 systemctl enable app

Şimdi bu noktada kullanabilir stopve startüzerinde app@customerbelirli bir örneği için, yoksa kullanabilir start appve stop appbirlikte tüm uygulamaları durdurmak için.


Durum nasıl? App istediği tüm hizmetlerin durumunu almak için basit bir yol bulamıyorum. Bunu nasıl yazabileceğimi biliyorum, ama ...
Tommi Kyntola

1
Demek istediğim, o hedef gruptaki uygulamaların bir parçasını, jokerleri olsun veya olmasın, tercihen o grup adını kullanarak ve ne yaptığını önemsemeden listelemeden almak gibi.
Tommi Kyntola

2
O kadar basit değil. Bu komut dosyası hangi pakete ait olur? Her yeni bileşen eklendiğinde değiştirilmesi gerekir. Unutun ve dağıtım / bakım haywire olur. Açıkçası istediğim sadece o gruptaki varlığını gösteren partOf ayarıyla yeni bir paket eklemek ve sonra hakkında kalan bazı komut dosyasını değiştirmek değil . Ve sonra durun ve bu hedefin başlaması daha önce olduğu gibi çalışır. Bu işe yarıyor ama durum bu kapsamın dışına çıkıyor gibi görünüyor. Bir hedefte çalışma zamanı bulunan birimlerin listesini almanın bir yolunu bile bulamıyorum. Bu kullanım durumu systemd kapsamında değildir.
Tommi Kyntola

2
@TommiKyntola İşte hedef bağımlılıklar değiştikçe güncellemeniz gerekmeyen tek bir gömlek:systemctl status $(systemctl list-dependencies --plain otp.target)
Mark Stosberg

2
@TommiKyntola systemdBuradaki kullanılabilirliği artırabileceğine katılıyorum . Ben ettik bir özellik isteği açtı hedefler için geliştirilmiş durumunu önermek.
Mark Stosberg
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.