Fullmoon System

Een systemd-service maken: unit, beveiliging, logs en herstartverificatie

AI_Manager

Registreer een systemd-service om zelf geïnstalleerde programma’s bij het opstarten te starten, ze opnieuw te laten opstarten bij fouten en de uitvoerende gebruiker en logs consistent te beheren. Dit artikel is gebaseerd op systeemservices voor RHEL en Rocky Linux 8/9. De applicatie moet op de voorgrond blijven draaien zonder naar de achtergrond te splitsen.

Een systemd-service maken: de stroom van starten, status, logs, netwerk en herstel van Linux-containers en systemd-services
Onderdelen, beveiligingsgrenzen, statuscontrole en herstelstroom bij het maken van een systemd-service

1. Bereid eerst het uitvoerbare bestand en de configuratie voor

Pas de /usr/local/bin/myapp en /etc/myapp/config.yml uit het voorbeeld aan aan de werkelijke applicatie. De onderstaande procedure installeert het programma zelf niet en maakt de inhoud van configuratiebestanden niet aan. Controleer eerst het normale startcommando van het programma, de werkmap, de benodigde bestanden/poorten en de methode voor een normale afsluiting. Als u dit toepast op een bestaande service, bewaar dan kopieën van de te wijzigen unit- en configuratiebestanden op een apart pad.

command -v systemctl
systemd --version
sudo test -x /usr/local/bin/myapp
sudo test -f /etc/myapp/config.yml

Ga niet door naar de volgende stap als de controle mislukt. Als er al een service door een pakket wordt geleverd, controleer dit dan met systemctl cat 서비스명 voordat u een nieuwe unit maakt en gebruik bij voorkeur een drop-in voor de meegeleverde unit, wat gunstiger is voor het onderhoud.

2. Maak een toegewezen account en een schrijfmap aan

getent passwd myapp
getent group myapp
# Alleen eenmalig uitvoeren als er geen account bestaat.
sudo useradd --system --user-group --home-dir /var/lib/myapp --shell /sbin/nologin myapp
sudo install -d -o myapp -g myapp -m 0750 /var/lib/myapp
sudo chown root:myapp /etc/myapp/config.yml
sudo chmod 0640 /etc/myapp/config.yml
sudo -u myapp test -x /usr/local/bin/myapp
sudo -u myapp test -r /etc/myapp/config.yml

Als er al een myapp-account bestaat, controleer dan het doel en de basisgroep en sla het commando voor het aanmaken van het account over. Omdat toegangsrechten ook nodig zijn voor de bovenliggende map, controleert u het volledige pad met namei -l /etc/myapp/config.yml. Zorg ervoor dat het serviceaccount het uitvoerbare bestand en de configuratie niet kan wijzigen, en ken alleen de datamap die door de applicatie wordt gebruikt toe aan dat account. Controleer in omgevingen waar SELinux is ingeschakeld zowel de AVC-logs als de bestandscontext.

3. Schrijf de service-unit

Sla de volgende inhoud op met sudoedit /etc/systemd/system/myapp.service.

[Unit]
Description=My application
After=network-online.target
Wants=network-online.target
StartLimitIntervalSec=60
StartLimitBurst=5

[Service]
Type=simple
User=myapp
Group=myapp
WorkingDirectory=/var/lib/myapp
ExecStart=/usr/local/bin/myapp --config /etc/myapp/config.yml
Restart=on-failure
RestartSec=5s
TimeoutStopSec=30s
NoNewPrivileges=yes
PrivateTmp=yes
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
  • Type=simple volgt het gestarte proces als het hoofdproces van de service. Omdat dit niet garandeert dat de applicatie klaar is voor gebruik, is een afzonderlijke functiecontrole vereist.
  • ExecStart is geen shell-opdrachtregel. Gebruik geen &, pipes of redirecties.
  • After bepaalt de volgorde en Wants bepaalt de relatie tussen units die samen moeten starten. De online status van het netwerk garandeert geen normaal antwoord van een externe database of API.
  • Gebruik Restart=on-failure samen met een limiet voor het aantal starts om herhaaldelijk snel falen te stoppen. Bepaal op basis van het type programma of het ook bij een normale afsluiting opnieuw moet opstarten.
  • PrivateTmp creëert een toegewezen tijdelijke ruimte. Controleer de compatibiliteit voor programma’s die /tmp-bestanden moeten delen met andere services.

Plaats wachtwoorden en tokens niet direct in de Environment= van de unit. Gebruik configuratiebestanden met toegangsbeperkingen die door de applicatie worden ondersteund of de functie voor het doorgeven van inloggegevens die door de betreffende systemd-versie wordt ondersteund.

4. Controleer de syntaxis, start de service en test de werkelijke functionaliteit

sudo systemd-analyze verify /etc/systemd/system/myapp.service
# Doorgaan wanneer er geen fouten zijn in de bovenstaande controle.
sudo systemctl daemon-reload
sudo systemctl enable --now myapp.service
systemctl is-enabled myapp.service
systemctl is-active myapp.service
sudo systemctl status myapp.service --no-pager --full
sudo journalctl -u myapp.service -b -n 100 --no-pager

daemon-reload leest de unit opnieuw in, enable maakt de koppeling voor het opstarten bij het booten en --now start de service nu. Als u de configuratie van een reeds draaiende service hebt gewijzigd, is een door het programma ondersteunde ‘reload’ of een geplande ‘restart’ afzonderlijk vereist.

Controleer niet alleen active. Als het een webservice is, stuur dan een verzoek naar de daadwerkelijke statuscontrole-URL van de service; als het een taakverwerker is, controleer dan het resultaat van de testtaak. Test tijdens een onderhoudsvenster ook of de service na een herstart opstart en normaal afsluit. Pas de wachttijd van 30 seconden voor afsluiten in het voorbeeld aan op basis van de tijd die nodig is om af te sluiten zonder gegevensverlies.

5. Onderscheid veelvoorkomende fouten

Symptoom Te controleren inhoud
203/EXEC Pad naar uitvoerbaar bestand, uitvoeringsrechten, script-interpreter en SELinux-weigeringen
200/CHDIR Bestaat de WorkingDirectory en heeft het serviceaccount toegangsrechten tot de map
217/USER Controleer of het User- en Group-account bestaat
Onmiddellijke afsluiting na het starten Fouten in werkelijke argumenten of configuratie, en of het programma splitst naar de daemon-modus
start-limit-hit Na het corrigeren van de oorzaak van herhaaldelijke fouten in de logs, reset de limiet en herstart de service
sudo journalctl -u myapp.service --since '-10 minutes' --no-pager
# Uitvoeren na het verhelpen van de oorzaak.
sudo systemctl reset-failed myapp.service
sudo systemctl restart myapp.service

Bij het terugdraaien van wijzigingen

Als het een nieuw gemaakte service is, stop deze dan en hef de registratie voor opstarten op met sudo systemctl disable --now myapp.service. Als het een wijziging aan een bestaande service betreft, herstel dan de opgeslagen unit en configuratie, en voer na daemon-reload een geplande herstart en functiecontrole uit. Verwijder service-accounts of datamappen niet voordat de afhankelijkheden en de noodzaak voor behoud zijn gecontroleerd.

Officiële documentatie