Sistemd ve süreç yumurtlama


14

Normalde buraya göndermeyin ama saçımı bu saçın üzerinden söküyorum. Ben başlatıldığında çatal ve diğer işlemler bir grup başlatmak için sorumlu bir Python komut dosyası var. Bu komut dosyası başlangıçta sysvinit aracılığıyla başlatıldı, ancak son zamanlarda Debian Jessie'ye geçtim, bu yüzden bunu systemd üzerinden başlatmak için uyarladım.

Ne yazık ki, çalışamayacağım bir sorunla karşılaşıyorum. Komut dosyasını doğrudan bir kullanıcı kabuğunda başlattığınızda, alt süreçlerini doğru bir şekilde başlatır ve komut dosyası çıkışlarında alt süreçler yetim kalır ve çalışmaya devam eder.

Systemd ile başlatıldığında, ana süreç çıkarsa, çocukların hepsi de çıkar (Evet, Ekranın başlattığı ve Ölü olarak göründüğü ???)

İdeal olarak ben tüm alt süreçleri öldürmeden ana komut dosyası yeniden başlatmak gerekir, eksik bir şey var mı?

Teşekkürler!

[Unit]
Description=Server commander
After=network.target

[Service]
User=serveruser
Type=forking
PIDFile=/var/Server/Server.pid

ExecStart=/var/Server/Server.py
ExecStop=/bin/kill -s TERM $MAINPID

[Install]
WantedBy=multi-user.target

Düzenleme: Muhtemelen benim için Python betiği temelde onun alt süreçleri için bir 'denetleyici' olduğunu işaret etmek önemlidir. Merkezi bir sunucudan istendiği gibi gnu ekranlarındaki sunucuları başlatır ve durdurur. Normalde her zaman çalışır, hizmet üretmez ve çıkmaz. Ancak süreçleri pid 1'e yetim kalsa bile, alt süreçleri öldürmeden komut dosyasını yeniden yükleyebileceğim durumlar var. Aslında, Python komut dosyasının işlemleri şu şekilde başlatması bile fark etmez hatta bir ebeveyn süreci.

Nasıl çalıştığına dair daha iyi bir açıklama:

  • Systemd ortaya çıkar / Server.py
  • Server.py, Systemd için pid dosyasını çatallar ve yazar
  • Server.py daha sonra talimatlarını temel alarak gnu ekranında sunucu işlemlerini başlatır
  • Server.py, sunucudan istenen tüm yeniden başlatmaları gerçekleştirmek için çalışmaya devam eder

Systemd olmadan başlatılırken, Server.py yeniden başlatılabilir ve başlattığı gnu ekranları etkilenmez. Systemd ile başlatılırken, Server.py kapatıldığında, bu ekran işlemleri pid 1'e yetim olmak yerine öldürülür.


1
Server.pyBaşlatılan hizmetler çatalı (çatalsa) nasıl kodu ve açıklaması olmadan bir çözüm sağlamak zordur . Ancak, genel olarak konuşursak, bu bir hazır olma protokolü uyumsuzluk problemidir.
intelfx

BTW, ExecStop=gerekli değildir. systemd'nin varsayılan durdurma eylemi işlemleri öldürmektir. KillMode=Yönerge ile ilgili belgelere göz atmak isteyebilirsiniz .
intelfx

1
Uygun bir hazırlık protokolü (biri varsa Ve son olarak ... simpleya forkingaslında), son çare olacağını Type=oneshot, RemainAfterExit=yesve KillMode=control-group.
intelfx

@intelfx Temel olarak Python betiği Subprocess.call kullanarak bir sunucuya bir ekran başlatır. Bundan daha karmaşık çünkü komut dosyası başka bir yerden hangi ekranların başlayıp hangilerinin başlamayacağını söyleyen komutlar alıyor. Hangi ekranların mevcut olduğu da dinamiktir, bu yüzden neden kendi başlarına sistemli hizmetler olamazlar. İdeal olarak ben bu ekranları hizmetin bir parçası olarak ele almak için systemd istemiyorum, ama şu anda aynı işlem grubuna dökülür ve yeniden başlatılırsa master ile ölürler.
Bottswana

Benim önsez systemd böyle bir kontrol süreci "işlemez" (sadece başlangıç ​​zamanında PID's bakar, sonraki olanları tanımıyor ...): |
rogerdpack

Yanıtlar:


9

Ben sadece kontrol grubu yerine varsayılan KillMode ayarlayarak düzeltmeyi başardı (varsayılan). Hepinize teşekkürler


Bu bir düzeltme daha bir şey gibi görünüyor gibi görünüyor, diğer cevaplar bakın ... bunu yaparsanız ve bir "systemctl durdurma" yaparsanız o zaman hala çalışacakları çocuk süreçleri öldürmez [?] systemctl gözetim dışında?
rogerdpack

5

Ben başlatıldığında çatal ve diğer işlemler bir grup başlatmak için sorumlu bir Python komut dosyası var.

Bu da yanlış yaptığınızı gösterir. Bir dakika içinde daha fazlası.

komut dosyası çıktığında alt işlemler artık kalmaz ve çalışmaya devam eder.

Bu doğru davranış değildir. "Ana" işlem - bu durumda, belirttiğinizden beri çatalladığınız çocuk Type=forkingçıkarsa, systemd hizmetin devre dışı bırakıldığını düşünür ve düzenli hale getirmek için devam eden diğer işlemleri (kontrol grubunda) sonlandırır .

Bazen System 5 rckomut dosyalarından systemd'ye dönüştürme basit değildir, çünkü systemd altında işleri yapmanın doğru yolu oldukça farklıdır. Systemd'de OpenVPN veya OpenStack veya OSSEC HIDS yapmanın (diyelim) doğru yolu, bir rckomut dosyasıyla aynı değildir . Çatallayan bir senaryoya sahip olmanız, daha sonra bir sürü torun sürecini ortaya çıkarmanız ve daha sonra bu torunların çalışmaya devam etmesini beklemekten çıkmanız, ossec-controldaha az iki çatal seviyesi ile de olsa aynı türden bir korkuyu sürdürdüğünüzü gösterir. Kendinizi "enable" işaretlerini kontrol eden ve sisteminizin "etkin" bölümleri için alt işlemleri çalıştıran bir "master" komut dosyası yazıyorsanız, o zaman korkunç olanla aynı hatayı yapıyorsunuz demektir ossec-control.

Sistemde böyle bir evde yetiştirilen mekanizmaya gerek yoktur. O zaten bir servis yöneticisi. Https://unix.stackexchange.com/a/200365/5132 uyarınca , systemd'de bunu yapmanın doğru yolu, "alt hizmetlere" sahip olmak için bazı tuhaf ve karışık girişimleri ortaya çıkaran bir hizmete sahip olmak değildir. Her çocuğun kendi başına tam teşekküllü bir sistem hizmeti olarak işlemesi gerekir. Daha sonra normal systemd kontrollerini kullanarak sistemin çeşitli kısımlarını etkinleştirir ve devre dışı bırakır ve başlatır ve durdurur. OSSEC HIDS durumunda görebileceğiniz gibi, basit bir şablon hizmet birimi neredeyse tüm seçenekleri kapsar (bir istisna /ubuntu//a/624871/43344 adresindedir ), systemctl enable ossec@agentlessd.serviceisteğe bağlı olarak etkinleştirmek gibi şeylerin yapılmasına izin veriragentlessdSistem 5 ile ihtiyaç duyulan korkunç "ana komut dosyası" mekanizmasına hiç ihtiyaç duymadan hizmet verebiliriz rc.

Belki de yeniden düşünmenin gerekli olduğu OSSEC HIDS kadar aşırı olmayan birçok durum vardır. Exim ve sendmail gibi MTS'ler böyledir. rcTam olarak çalıştırılmak üzere bir yapılandırma dosyasında bir grup ad hoc kabuk değişkeni bulunan bir kuyruk koşucusu, bir SMTP Gönderme dæmonu ve bir SMTP Geçiş dæmon'u oluşturan tek bir komut dosyası olabilir . Ancak bunu systemd ile yapmanın doğru yolu, üç uygun servis birimine (ikisi ilişkili soket birimlerine sahip ) ve hiç özel bir şeye sahip olmamaktır , sadece servis yöneticisinin düzenli mekanizmalarına sahip olmaktır.


Bu konudaki geribildirimi takdir ediyorum. Alt küme hizmetlerine sahip olmanın mantıklı olduğunu kabul etsem de, Python'da içeri giremediğim bir nedenden dolayı yapıldı. Tek çözümüm, bu yöntemi çalıştırmanın bir yolunu bulmak. Yine de teşekkürler. Bunu düzgün yapmak isterdim.
Bottswana

Komut dosyasının başlattığı alt hizmetler yalnızca gnu ekranında belirli bir kullanıcı olarak çalışan sunuculardır. Bu sunucular çok değişir, bazıları eklenir, bazıları kaldırılır ve bu başka bir yerde kontrol edilir, bu yüzden sistemd'de gerçek hizmetler olamazlar, çünkü bu çok karmaşıklık yaratır ve merkezi olarak yönetilemez. Aynı komut, sistemd olmayan sunucularda da kullanılır.
Bottswana

systemd, kök erişimine gerek kalmadan hizmetlerin eklenmesine ve kaldırılmasına izin veren açık olanaklara sahiptir. "Systemd olmayan servislerde de kullanılır", daha fazla systemd eklenerek düzeltilemeyen yukarıdaki argümanlardan sadece biridir ... iyi, tartışmasız, hatta biri de olabilir. :)
Charles Duffy

0

Ebeveynini sadece uyuyabilir ve systemd'nin durma zamanında öldürmesini bekleyebilirsiniz.

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.