GNU/Linux >> Linux Esercitazione >  >> Linux

Inizia a utilizzare systemd come strumento di risoluzione dei problemi

Nessuno considererebbe davvero systemd uno strumento per la risoluzione dei problemi, ma quando ho riscontrato un problema sul mio server web, la mia crescente conoscenza di systemd e di alcune delle sue funzionalità mi ha aiutato a individuare e aggirare il problema.

Il problema era che il mio server, Yorktown, che fornisce servizi di nomi, DHCP, NTP, HTTPD e servizi di posta elettronica SendMail per la rete del mio ufficio domestico, non riusciva ad avviare il demone Apache HTTPD durante il normale avvio. Ho dovuto avviarlo manualmente dopo aver capito che non era in esecuzione. Il problema persisteva da tempo e di recente ho cercato di risolverlo.

Alcuni di voi diranno che lo stesso systemd è la causa di questo problema e, sulla base di ciò che so ora, sono d'accordo con te. Tuttavia, ho avuto tipi simili di problemi con SystemV. (Nel primo articolo di questa serie, ho esaminato la controversia su systemd come sostituto del vecchio programma init SystemV e degli script di avvio. Se sei interessato a saperne di più su systemd, leggi anche il secondo e il terzo articolo.) Nessun software è perfetto e né systemd né SystemV costituiscono un'eccezione, ma systemd fornisce molte più informazioni per la risoluzione dei problemi rispetto a quelle offerte da SystemV.

Determinazione del problema

Il primo passo per trovare l'origine di questo problema è determinare lo stato del servizio 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 ~]#

Queste informazioni sullo stato sono una delle funzionalità di systemd che trovo molto più utili di qualsiasi altra cosa offerta da SystemV. La quantità di informazioni utili qui presenti mi porta facilmente a una conclusione logica che mi porta nella giusta direzione. Tutto quello che ho ottenuto dal vecchio chkconfig comando indica se il servizio è in esecuzione o meno e l'ID del processo (PID) se lo è. Non è molto utile.

La voce chiave in questo rapporto di stato mostra che HTTPD non può collegarsi all'indirizzo IP, il che significa che non può accettare richieste in arrivo. Ciò indica che la rete non si avvia abbastanza velocemente per essere pronta per l'associazione del servizio HTTPD all'indirizzo IP perché l'indirizzo IP non è stato ancora impostato. Ciò non dovrebbe accadere, quindi ho esplorato i file di configurazione di avvio del sistema di servizio di rete; tutto sembrava essere corretto con le affermazioni "dopo" e "richiede". Ecco il /lib/systemd/system/httpd.service file dal mio server:

# 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

Il httpd.service unit file specifica esplicitamente che deve essere caricato dopo network.target e il httpd-init.service (tra gli altri). Ho provato a trovare tutti questi servizi utilizzando systemctl list-units comando e ricercarli nel flusso di dati risultante. Tutti erano presenti e avrebbero dovuto assicurarsi che il servizio httpd non venisse caricato prima dell'impostazione dell'indirizzo IP di rete.

Prima soluzione

Altro sugli amministratori di sistema

  • Abilita blog Sysadmin
  • The Automated Enterprise:una guida alla gestione dell'IT con l'automazione
  • eBook:Ansible Automation per SysAdmins
  • Racconti dal campo:una guida per l'amministratore di sistema all'automazione IT
  • eBook:una guida a Kubernetes per SRE e amministratori di sistema
  • Ultimi articoli sull'amministratore di sistema

Un po' di ricerca su Internet ha confermato che altri avevano riscontrato problemi simili con httpd e altri servizi. Ciò sembra accadere perché uno dei servizi richiesti indica a systemd che ha terminato il suo avvio, ma in realtà genera un processo figlio che non è terminato. Dopo un po' più di ricerca, ho escogitato un'elusione.

Non riuscivo a capire perché l'indirizzo IP impiegasse così tanto tempo per essere assegnato alla scheda di interfaccia di rete. Quindi, ho pensato che se avessi potuto ritardare l'avvio del servizio HTTPD di un ragionevole lasso di tempo, l'indirizzo IP sarebbe stato assegnato entro quel momento.

Fortunatamente, il /lib/systemd/system/httpd.service il file sopra fornisce alcune indicazioni. Anche se dice di non alterarlo, indica come procedere:Usa il comando systemctl edit httpd , che crea automaticamente un nuovo file (/etc/systemd/system/httpd.service.d/override.conf ) e apre l'editor GNU Nano. (Se non hai familiarità con Nano, assicurati di guardare i suggerimenti nella parte inferiore dell'interfaccia di Nano.)

Aggiungi il seguente testo al nuovo file e salvalo:

[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

Il [Servizio] la sezione di questo file di sostituzione contiene una singola riga che ritarda di 30 secondi l'avvio del servizio HTTPD. Il seguente comando di stato mostra lo stato del servizio durante il tempo di attesa:

[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 ~]#

E questo comando mostra lo stato del servizio HTTPD dopo la scadenza del ritardo di 30 secondi. Il servizio è attivo e funzionante correttamente:

[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.

Avrei potuto sperimentare per vedere se avrebbe funzionato anche un ritardo più breve, ma il mio sistema non è così critico, quindi ho deciso di non farlo. Funziona in modo affidabile così com'è, quindi sono felice.

Poiché ho raccolto tutte queste informazioni, le ho segnalate a Red Hat Bugzilla come Bug 1825554. Credo che sia molto più produttivo segnalare i bug che lamentarsene.

La soluzione migliore

Un paio di giorni dopo aver segnalato questo come un bug, ho ricevuto una risposta che indicava che systemd è solo il manager e se httpd deve essere ordinato dopo che alcuni requisiti sono stati soddisfatti, deve essere espresso nel file unit. La risposta mi ha indirizzato a httpd.service pagina man. Vorrei averlo trovato prima perché è una soluzione migliore di quella che ho trovato. Questa soluzione è esplicitamente mirata all'unità target prerequisita piuttosto che a un ritardo alquanto casuale.

Da httpd.service pagina man:

Avvio del servizio all'avvio

Le unità httpd.service e httpd.socket sono disabilitate per impostazione predefinita. Per avviare il servizio httpd all'avvio, eseguire:systemctl enable httpd.service . Nella configurazione predefinita, il demone httpd accetterà connessioni sulla porta 80 (e, se è installato mod_ssl, connessioni TLS sulla porta 443) per qualsiasi indirizzo IPv4 o IPv6 configurato.

Se httpd è configurato per dipendere da qualsiasi indirizzo IP specifico (ad esempio, con una direttiva "Listen") che potrebbe diventare disponibile solo durante l'avvio, o se httpd dipende da altri servizi (come un demone di database), il servizio deve essere configurato per garantire il corretto ordine di avvio.

Ad esempio, per assicurarti che httpd sia in esecuzione solo dopo aver configurato tutte le interfacce di rete configurate, crea un file drop-in (come descritto sopra) con la seguente sezione:

[Unità]

After=network-online.target

Wants=network-online.target

Continuo a pensare che questo sia un bug perché è abbastanza comune, almeno nella mia esperienza, usare un Ascolta direttiva in httpd.conf file di configurazione. Ho sempre usato Ascolta direttive, anche su host con un solo indirizzo IP, ed è chiaramente necessario su host con più schede di interfaccia di rete (NIC) e indirizzi IP (Internet Protocol). Aggiunta delle righe precedenti a /usr/lib/systemd/system/httpd.service predefinito non causerebbe problemi per le configurazioni che non utilizzano un Ascolta direttiva ed eviterebbe questo problema per coloro che lo fanno.

Nel frattempo, utilizzerò la soluzione suggerita.

Passaggi successivi

Questo articolo descrive un problema che ho riscontrato con l'avvio del servizio Apache HTTPD sul mio server. Ti guida attraverso i passaggi per la determinazione del problema che ho intrapreso e mostra come ho usato systemd per assistere. Ho anche trattato l'elusione che ho implementato utilizzando systemd e la soluzione migliore che è seguita dalla mia segnalazione di bug.

Come ho detto all'inizio, è molto probabile che questo sia il risultato di un problema con systemd, in particolare la configurazione per l'avvio di httpd. Tuttavia, systemd mi ha fornito gli strumenti per individuare la probabile fonte del problema e per formulare e implementare un'elusione. Nessuna delle soluzioni risolve davvero il problema con mia soddisfazione. Per ora, la causa principale del problema esiste ancora e deve essere risolta. Se si tratta semplicemente di aggiungere le righe consigliate a /usr/lib/systemd/system/httpd.service file, che funzionerebbe per me.

Una delle cose che ho scoperto durante questo processo è che ho bisogno di saperne di più sulla definizione delle sequenze in cui iniziano le cose. Lo esplorerò nel mio prossimo articolo, il quinto di questa serie.

Risorse

Ci sono molte informazioni su systemd disponibili su Internet, ma molte sono concise, ottuse o addirittura fuorvianti. Oltre alle risorse menzionate in questo articolo, le seguenti pagine Web offrono informazioni più dettagliate e affidabili sull'avvio di systemd.

  • Il progetto Fedora ha una buona guida pratica a systemd. Ha praticamente tutto ciò che devi sapere per configurare, gestire e mantenere un computer Fedora usando systemd.
  • Il progetto Fedora ha anche un buon cheat sheet che incrocia i vecchi comandi SystemV con quelli di systemd comparabili.
  • Per informazioni tecniche dettagliate su systemd e sui motivi della sua creazione, consulta la descrizione di systemd di Freedesktop.org.
  • "Più divertimento di sistema" di Linux.com offre informazioni e suggerimenti più avanzati sul sistema.

C'è anche una serie di articoli profondamente tecnici per gli amministratori di sistema Linux di Lennart Poettering, il designer e sviluppatore principale di systemd. Questi articoli sono stati scritti tra aprile 2010 e settembre 2011, ma sono rilevanti ora come allora. Gran parte di tutto ciò che è stato scritto di buono su systemd e il suo ecosistema si basa su questi documenti.

  • Ripensare il PID 1
  • systemd per amministratori, parte I
  • sistema per amministratori, parte II
  • sistema per amministratori, parte III
  • systemd per amministratori, parte IV
  • sistema per amministratori, parte V
  • sistema per amministratori, parte VI
  • sistema per amministratori, parte VII
  • systemd per amministratori, parte VIII
  • systemd per amministratori, parte IX
  • sistema per amministratori, parte X
  • systemd per amministratori, parte XI

Linux
  1. Utilizzo di diari di sistema per la risoluzione di problemi temporanei

  2. Gestisci l'avvio usando systemd

  3. Utilizzo del comando systemctl per gestire le unità systemd

  4. Utilizzo dello strumento Screenshot di GNOME in Linux come un professionista

  5. MySQL non riesce ad iniziare a usare systemctl su distribuzioni Linux systemd

Esplora i binari usando questo strumento Linux completo

Come avviare il servizio httpd in RHEL Linux

Visualizza l'utilizzo della larghezza di banda della rete utilizzando lo strumento Bandwhich

Visualizza le informazioni di rete in Linux utilizzando quale strumento IP

Utilizzo delle funzionalità di systemd per proteggere i servizi

Utilizzo di SSH Port Forwarding come strumento di sicurezza in Linux