GNU/Linux >> Znalost Linux >  >> Linux

Začněte používat systemd jako nástroj pro odstraňování problémů

Nikdo by ve skutečnosti nepovažoval systemd za nástroj pro odstraňování problémů, ale když jsem narazil na problém na svém webovém serveru, moje rostoucí znalost systemd a některých jeho funkcí mi pomohla problém najít a obejít.

Problém byl v tom, že mému serveru yorktown, který poskytuje jmenné služby, DHCP, NTP, HTTPD a e-mailové služby SendMail pro síť mé domácí kanceláře, se nepodařilo spustit démona Apache HTTPD během normálního spouštění. Musel jsem to spustit ručně poté, co jsem si uvědomil, že to neběží. Problém už nějakou dobu trvá a nedávno jsem se ho pokusil opravit.

Někteří z vás řeknou, že příčinou tohoto problému je samotný systemd, a na základě toho, co nyní vím, s vámi souhlasím. Měl jsem však podobné typy problémů se SystemV. (V prvním článku této série jsem se zabýval kontroverzí kolem systemd jako náhrady starého init programu SystemV a spouštěcích skriptů. Pokud se chcete dozvědět více o systemd, přečtěte si také druhý a třetí článek.) Žádný software není dokonalý a ani systemd, ani SystemV nejsou výjimkou, ale systemd poskytuje mnohem více informací pro řešení problémů, než kdy SystemV nabízel.

Určení problému

Prvním krokem k nalezení zdroje tohoto problému je určení stavu služby httpd:

[root@yorktown ~]# systemctl status httpd
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
   Active: failed (Result: exit-code) since Thu 2020-04-16 11:54:37 EDT; 15min ago
     Docs: man:httpd.service(8)
  Process: 1101 ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND (code=exited, status=1/FAILURE)
 Main PID: 1101 (code=exited, status=1/FAILURE)
   Status: "Reading configuration..."
      CPU: 60ms

Apr 16 11:54:35 yorktown.both.org systemd[1]: Starting The Apache HTTP Server...
Apr 16 11:54:37 yorktown.both.org httpd[1101]: (99)Cannot assign requested address: AH00072: make_sock: could not bind to address 192.168.0.52:80
Apr 16 11:54:37 yorktown.both.org httpd[1101]: no listening sockets available, shutting down
Apr 16 11:54:37 yorktown.both.org httpd[1101]: AH00015: Unable to open logs
Apr 16 11:54:37 yorktown.both.org systemd[1]: httpd.service: Main process exited, code=exited, status=1/FAILURE
Apr 16 11:54:37 yorktown.both.org systemd[1]: httpd.service: Failed with result 'exit-code'.
Apr 16 11:54:37 yorktown.both.org systemd[1]: Failed to start The Apache HTTP Server.
[root@yorktown ~]#

Tyto informace o stavu jsou jednou z funkcí systemd, kterou považuji za mnohem užitečnější než cokoli, co SystemV nabízí. Množství užitečných informací mě snadno vede k logickému závěru, který mě vede správným směrem. Vše, co jsem kdy získal ze starého chkconfig příkaz je, zda je služba spuštěna nebo ne, a ID procesu (PID), pokud je. To není příliš užitečné.

Klíčová položka v této stavové zprávě ukazuje, že HTTPD se nemůže vázat na IP adresu, což znamená, že nemůže přijímat příchozí požadavky. To znamená, že se síť nespouští dostatečně rychle, aby byla připravena na připojení služby HTTPD k adrese IP, protože adresa IP ještě nebyla nastavena. To by se nemělo stát, a tak jsem prozkoumal konfigurační soubory spouštěcí systémové služby své síťové služby; vše se zdálo být správné se správnými prohlášeními „po“ a „vyžaduje“. Zde je /lib/systemd/system/httpd.service soubor z mého serveru:

# Modifying this file in-place is not recommended, because changes                                                                                    
# will be overwritten during package upgrades.  To customize the                                                                                      
# behaviour, run "systemctl edit httpd" to create an override unit.                                                                                  
                                                                                                                                                     
# For example, to pass additional options (such as -D definitions) to                                                                                
# the httpd binary at startup, create an override unit (as is done by                                                                                
# systemctl edit) and enter the following:                                                                                                            
                                                                                                                                                     
#       [Service]                                                                                                                                    
#       Environment=OPTIONS=-DMY_DEFINE                                                                                                              
                                                                                                                                                     
[Unit]                                                                                                                                                
Description=The Apache HTTP Server                                                                                                                    
Wants=httpd-init.service                                                                                                                              
After=network.target remote-fs.target nss-lookup.target httpd-init.service                                                                            
Documentation=man:httpd.service(8)                                                                                                                    
                                                                                                                                                     
[Service]                                                                                                                                            
Type=notify                                                                                                                                          
Environment=LANG=C                                                                                                                                    
                                                                                                                                                     
ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND                                                                                                      
ExecReload=/usr/sbin/httpd $OPTIONS -k graceful                                                                                                      
# Send SIGWINCH for graceful stop                                                                                                                    
KillSignal=SIGWINCH                                                                                                                                  
KillMode=mixed                                                                                                                                        
PrivateTmp=true                                                                                                                                      
                                                                                                                                                     
[Install]                                                                                                                                            
WantedBy=multi-user.target

httpd.service unit file výslovně uvádí, že se má načíst po network.target a httpd-init.service (mezi ostatními). Snažil jsem se najít všechny tyto služby pomocí systemctl list-units a vyhledávat je ve výsledném datovém toku. Všechny byly přítomny a měly zajistit, že se služba httpd nenačte před nastavením síťové IP adresy.

První řešení

Více o sysadmins

  • Povolit blog Sysadmin
  • Automatizovaný podnik:průvodce řízením IT pomocí automatizace
  • eKniha:Ansible Automation for SysAdmins
  • Příběhy z terénu:Průvodce správcem systému pro automatizaci IT
  • eKniha:Průvodce Kubernetes pro SRE a správce systému
  • Nejnovější články správce systému

Trochu hledání na internetu potvrdilo, že ostatní se setkali s podobnými problémy s httpd a dalšími službami. Zdá se, že k tomu dochází, protože jedna z požadovaných služeb signalizuje systemd, že dokončila své spuštění – ale ve skutečnosti oddělí podřízený proces, který ještě neskončil. Po chvíli pátrání jsem přišel na obcházení.

Nemohl jsem přijít na to, proč přidělení IP adresy ke kartě síťového rozhraní trvalo tak dlouho. Myslel jsem si tedy, že pokud bych mohl zpozdit spuštění služby HTTPD o rozumnou dobu, IP adresa by byla přidělena do té doby.

Naštěstí /lib/systemd/system/httpd.service výše uvedený soubor poskytuje určitý směr. I když je tam uvedeno, že se to nemá měnit, ukazuje to, jak postupovat:Použijte příkaz systemctl edit httpd , který automaticky vytvoří nový soubor (/etc/systemd/system/httpd.service.d/override.conf ) a otevře editor GNU Nano. (Pokud neznáte Nano, nezapomeňte se podívat na rady ve spodní části rozhraní Nano.)

Přidejte do nového souboru následující text a uložte jej:

[root@yorktown ~]# cd /etc/systemd/system/httpd.service.d/
[root@yorktown httpd.service.d]# ll
total 4
-rw-r--r-- 1 root root 243 Apr 16 11:43 override.conf
[root@yorktown httpd.service.d]# cat override.conf
# Trying to delay the startup of httpd so that the network is
# fully up and running so that httpd can bind to the correct
# IP address
#
# By David Both, 2020-04-16

[Service]
ExecStartPre=/bin/sleep 30

[Služba] část tohoto souboru přepsání obsahuje jeden řádek, který zpožďuje spuštění služby HTTPD o 30 sekund. Následující příkaz status zobrazuje stav služby během doby čekání:

[root@yorktown ~]# systemctl status httpd
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
  Drop-In: /etc/systemd/system/httpd.service.d
           └─override.conf
           /usr/lib/systemd/system/httpd.service.d
           └─php-fpm.conf
   Active: activating (start-pre) since Thu 2020-04-16 12:14:29 EDT; 28s ago
     Docs: man:httpd.service(8)
Cntrl PID: 1102 (sleep)
    Tasks: 1 (limit: 38363)
   Memory: 260.0K
      CPU: 2ms
   CGroup: /system.slice/httpd.service
           └─1102 /bin/sleep 30

Apr 16 12:14:29 yorktown.both.org systemd[1]: Starting The Apache HTTP Server...
Apr 16 12:15:01 yorktown.both.org systemd[1]: Started The Apache HTTP Server.
[root@yorktown ~]#

A tento příkaz ukazuje stav služby HTTPD po uplynutí 30sekundové prodlevy. Služba funguje správně:

[root@yorktown ~]# systemctl status httpd
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; enabled; vendor preset: disabled)
  Drop-In: /etc/systemd/system/httpd.service.d
           └─override.conf
           /usr/lib/systemd/system/httpd.service.d
           └─php-fpm.conf
   Active: active (running) since Thu 2020-04-16 12:15:01 EDT; 1min 18s ago
     Docs: man:httpd.service(8)
  Process: 1102 ExecStartPre=/bin/sleep 30 (code=exited, status=0/SUCCESS)
 Main PID: 1567 (httpd)
   Status: "Total requests: 0; Idle/Busy workers 100/0;Requests/sec: 0; Bytes served/sec:   0 B/sec"
    Tasks: 213 (limit: 38363)
   Memory: 21.8M
      CPU: 82ms
   CGroup: /system.slice/httpd.service
           ├─1567 /usr/sbin/httpd -DFOREGROUND
           ├─1569 /usr/sbin/httpd -DFOREGROUND
           ├─1570 /usr/sbin/httpd -DFOREGROUND
           ├─1571 /usr/sbin/httpd -DFOREGROUND
           └─1572 /usr/sbin/httpd -DFOREGROUND

Apr 16 12:14:29 yorktown.both.org systemd[1]: Starting The Apache HTTP Server...
Apr 16 12:15:01 yorktown.both.org systemd[1]: Started The Apache HTTP Server.

Mohl jsem experimentovat, abych zjistil, zda by fungovalo i kratší zpoždění, ale můj systém není tak kritický, takže jsem se rozhodl ne. Funguje to spolehlivě tak, jak to je, takže jsem spokojený.

Protože jsem shromáždil všechny tyto informace, nahlásil jsem to Red Hat Bugzilla jako Bug 1825554. Věřím, že je mnohem produktivnější chyby hlásit, než si na ně stěžovat.

Lepší řešení

Pár dní poté, co jsem to nahlásil jako chybu, jsem obdržel odpověď, že systemd je pouze správce, a pokud je třeba po splnění některých požadavků objednat httpd, je třeba to vyjádřit v souboru jednotky. Odpověď mě nasměrovala na httpd.service manuálová stránka. Přál bych si, abych to našel dříve, protože je to lepší řešení než to, se kterým jsem přišel. Toto řešení je explicitně zaměřeno na požadovanou cílovou jednotku, nikoli na poněkud náhodné zpoždění.

Ze httpd.service manuálová stránka:

Spuštění služby při spuštění

Jednotky httpd.service a httpd.socket jsou vypnuty ve výchozím stavu. Chcete-li spustit službu httpd při spouštění, spusťte:systemctl enable httpd.service . Ve výchozí konfiguraci bude démon httpd přijímat připojení na portu 80 (a pokud je nainstalován mod_ssl, připojení TLS na portu 443) pro jakoukoli nakonfigurovanou adresu IPv4 nebo IPv6.

Pokud je httpd nakonfigurováno tak, aby záviselo na jakékoli konkrétní IP adrese (například pomocí direktivy "Listen"), která může být dostupná pouze během spouštění, nebo pokud httpd závisí na jiných službách (jako je démon databáze), služba musí být nakonfigurován tak, aby bylo zajištěno správné řazení při spuštění.

Chcete-li například zajistit, aby httpd bylo spuštěno pouze po nakonfigurování všech nakonfigurovaných síťových rozhraní, vytvořte soubor typu drop-in (jak je popsáno výše) s následující částí:

[Jednotka]

After=network-online.target

Wants=network-online.target

Stále si myslím, že se jedná o chybu, protože je docela běžné – alespoň podle mých zkušeností – používat Poslouchat direktiva v httpd.conf konfigurační soubor. Vždy jsem používal Poslouchat direktivy, a to i na hostitelích s pouze jednou IP adresou, a je to jednoznačně nutné na hostitelích s více síťovými kartami (NIC) a adresami internetového protokolu (IP). Přidání řádků výše do /usr/lib/systemd/system/httpd.service výchozí soubor by nezpůsobil problémy pro konfigurace, které nepoužívají Listen a předešlo by tomuto problému těm, kteří to dělají.

Mezitím použiji navrhované řešení.

Další kroky

Tento článek popisuje problém, který jsem měl se spuštěním služby Apache HTTPD na mém serveru. Provede vás kroky k určení problému, které jsem podnikl, a ukáže, jak jsem pomocí systemd pomohl. Popsal jsem také obcházení, které jsem implementoval pomocí systemd, a lepší řešení, které vyplynulo z mé zprávy o chybě.

Jak jsem zmínil na začátku, je velmi pravděpodobné, že se jedná o důsledek problému se systemd, konkrétně konfigurace pro spouštění httpd. Nicméně systemd mi poskytl nástroje k nalezení pravděpodobného zdroje problému a k formulaci a implementaci obcházení. Ani jedno řešení neřeší problém k mé spokojenosti. V současnosti hlavní příčina problému stále existuje a musí být opravena. Pokud jde o pouhé přidání doporučených řádků do /usr/lib/systemd/system/httpd.service soubor, to by pro mě fungovalo.

Jednou z věcí, které jsem během tohoto procesu zjistil, je, že se potřebuji dozvědět více o definování sekvencí, ve kterých věci začínají. To prozkoumám ve svém dalším článku, pátém v této sérii.

Zdroje

Na internetu je k dispozici velké množství informací o systemd, ale mnohé jsou stručné, tupé nebo dokonce zavádějící. Kromě zdrojů zmíněných v tomto článku nabízejí následující webové stránky podrobnější a spolehlivější informace o spouštění systemd.

  • Projekt Fedora má dobrého praktického průvodce systemd. Obsahuje téměř vše, co potřebujete vědět, abyste mohli nakonfigurovat, spravovat a udržovat počítač Fedora pomocí systemd.
  • Projekt Fedora má také dobrý cheat sheet, který křížově odkazuje na staré příkazy SystemV se srovnatelnými příkazy systemd.
  • Podrobné technické informace o systemd a důvodech pro jeho vytvoření naleznete v popisu systemd na Freedesktop.org.
  • Pokročilejší systémové informace a tipy nabízí stránka Linux.com „More systemd fun“.

Existuje také řada hluboce technických článků pro správce systému Linux od Lennarta Poetteringa, návrháře a primárního vývojáře systemd. Tyto články byly napsány mezi dubnem 2010 a zářím 2011, ale nyní jsou stejně aktuální jako tehdy. Většina všeho dobrého, co bylo napsáno o systemd a jeho ekosystému, je založeno na těchto dokumentech.

  • Přehodnocení PID 1
  • systemd pro administrátory, část I
  • systemd pro administrátory, část II
  • systemd pro administrátory, část III
  • systemd pro administrátory, část IV
  • systemd pro administrátory, část V
  • systemd pro administrátory, část VI
  • systemd pro administrátory, část VII
  • systemd pro administrátory, část VIII
  • systemd pro administrátory, část IX
  • systemd pro administrátory, část X
  • systemd pro administrátory, část XI

Linux
  1. Použití žurnálů systemd k řešení přechodných problémů

  2. Spravujte spouštění pomocí systemd

  3. Použití příkazu systemctl ke správě jednotek systemd

  1. Používání nástroje GNOME Screenshot Tool v Linuxu jako profesionál

  2. Služba Systemd nespustí Nodejs?

  3. MySQL se nepodařilo začít používat systemctl v distribucích systemd Linux

  1. Systemd:Použití After a Requires

  2. Startovací skript postgresql Systemd

  3. pomocí časovačů systemd místo cronu