Terug naar blog

Hoe u een Linux-service configureert om automatisch te starten na een herstart of systeemcrash: Deel 2 (Theoretische uitleg)

Hoe u een Linux-service configureert om automatisch te starten na een herstart of systeemcrash: Deel 2 (Theoretische uitleg)

In dit tweede deel van de tweedelige handleiding over het configureren van Linux-services om automatisch te starten na een herstart of systeemcrash, zullen we het init-systeem in detail bespreken. Je kunt verwijzen naar Deel 1 van de serie: Hoe configureer je een Linux-service om automatisch te starten na een herstart of systeemcrash: Praktische voorbeelden hier.

Deze handleiding zal sterk theoretisch van aard zijn. Daarom moet je deze gebruiken als referentie om een dieper begrip te krijgen van hoe het init-systeem werkt in Linux. In het eerste deel van deze handleiding hebben we enkele codefragmenten en opstartscripts gedeeld die het init-systeem leest tijdens het opstarten. We hebben ook MySQL gebruikt als voorbeeld om te leren hoe je een Linux-service in- en uitschakelt om automatisch te starten na een crash of herstart. Zoals je in het eerste deel van deze tweedelige handleiding hebt geleerd, zijn er drie init-systemen die in verschillende Linux-distributies worden gebruikt: System V, Upstart en Systemd. Je kunt verwijzen naar het eerste deel van deze handleiding om te begrijpen welke distributie en versie zijn geconfigureerd om een specifiek init-systeem te gebruiken.

In deze handleiding leggen we de code uit die we in het eerste deel van de handleiding hebben gebruikt. We zullen dieper ingaan op de commando's en de configuratiebestanden die het init-systeem gebruikt. Laten we beginnen!

Vereisten

In de conclusie van het eerste deel van deze tweedelige handleiding vermeldden we dat je de drie testservers draaiende moet houden. Als je ze had verwijderd, kun je teruggaan en ze opnieuw aanmaken. Dit zal je helpen om de handleiding te volgen. De drie testservers die je zou moeten hebben zijn:

  • Ubuntu 9.04 en eerder, of Debian 6 x64 (we zullen dit gebruiken om het System V init-systeem te demonstreren)
  • Ubuntu 14.04 x64 (we zullen dit gebruiken om Upstart te demonstreren). Hier is een handleiding over hoe je eenvoudig je Ubuntu-server instelt.
  • CentOS 7 x64 (we zullen dit gebruiken om Systemd te demonstreren).

Je moet op elk van de servers een gebruiker hebben met sudo-privileges die je zult gebruiken om de commando's uit te voeren. Deze handleiding over het configureren van het Linux sudoers-bestand kan je hierbij helpen.

Opmerking:  De commando's in de handleiding zullen interfereren met systeemdiensten. Daarom moet je ze niet toepassen op een live productieserver.

Runlevels

Een runlevel is een operationeel niveau dat de huidige status van een Linux-systeem beschrijft in relatie tot welke services beschikbaar zijn. Het concept vindt zijn oorsprong in System V init. Wanneer het Linux-systeem opstart, initialiseert het de kernel, gaat het naar één runlevel en voert het het opstartscript uit dat aan dat runlevel is gekoppeld. Je kunt bij het opstarten slechts één runlevel uitvoeren.

Andere voorbeelden van runlevels zijn de afsluitstatus, de herstartmodus, een single-user-modus, enz. Elk niveau bepaalt welke services in die status moeten worden uitgevoerd. Sommige services kunnen op meer dan één niveau worden uitgevoerd, terwijl andere dat niet kunnen.

Er zijn zeven runlevels: van 0 tot 6. Hieronder volgt een definitie van de zeven runlevels:

  • Runlevel 0: Systeem uitschakelen
  • Runlevel 1: Single-user- en herstelmodus
  • Runlevels 2, 3, 4: Multi-user- en tekstmodus met netwerk ingeschakeld
  • Runlevel 5: Multi-user, netwerk ingeschakeld en grafische modus
  • Runlevel 6: Systeem herstarten

Runlevels worden niet noodzakelijkerwijs opeenvolgend uitgevoerd. Runlevels 2, 3 en 4 variëren afhankelijk van de Linux-distributie die je gebruikt. Je kunt runlevel 4 in sommige distributies wel implementeren en in andere niet. Toen je een service inschakelde om automatisch te starten, zoals uitgelegd in deel één, heb je deze feitelijk aan een runlevel toegevoegd. In System V start het besturingssysteem met een specifiek runlevel, en tijdens het opstarten probeert het alle services te starten die aan dat runlevel zijn gekoppeld. Runlevels zijn doelen (targets) in Systemd, wat we zullen bespreken in de Systemd-sectie.

Init en PID 1

Het init-systeem is het allereerste proces dat wordt uitgevoerd wanneer een Linux-systeem opstart en de kernel in het geheugen wordt geladen. Het voert verschillende taken uit, waaronder het bepalen hoe een gebruikersproces of systeemservice wordt geladen, in welke volgorde, en of deze automatisch moet starten. In elke Linux-distributie wordt elk proces geïdentificeerd door een proces-ID (PID) en init heeft een PID van 1. Het is de ouder van alle andere processen die achtereenvolgens starten terwijl het systeem opstart.

Geschiedenis van init

Het init-systeem in de recente Linux-distributies is een verbetering ten opzichte van het origineel. De vroegste versies van Linux-distributies maakten gebruik van System V init, wat op vergelijkbare wijze werd gebruikt in Unix-systemen. Naarmate Linux evolueerde, werd de Upstart init-daemon geïmplementeerd – deze is gemaakt door Ubuntu. Nu (op het moment van schrijven van deze handleiding, 2021) hebben we de Systemd init-daemon – die voor het eerst werd geïmplementeerd door Fedora. Omdat Linux-systemen zich blijven ontwikkelen, komt er mogelijk een nieuwer init-systeem. In deze handleiding bespreken we deze drie: System V, Upstart en Systemd.

Recente Linux-versies worden standaard geleverd met het Systemd init-systeem. Ze hebben echter de andere oudere init-systemen behouden voor achterwaartse compatibiliteit. Er zijn verschillende implementaties van System V die u in andere varianten van Linux kunt gebruiken. FreeBSD, een variant van UNIX, gebruikt bijvoorbeeld  BSD init. Oudere versies van Debian gebruiken SysVinit. Beide zijn afkomstig van System V.

De manier waarop elke versie van de init-daemon services beheert, is anders. De verbeteringen die in elke versie zijn toegevoegd, waren gericht op een robuuste tool voor servicebeheer die alles zou afhandelen wat een Linux-systeem nodig heeft op het gebied van services, apparaten, poorten en andere bronnen. Er was behoefte aan een krachtig systeem dat bronnen parallel kon laden en dat elegant kon herstellen van een systeemcrash.

System V Init-volgorde

System V maakt gebruik van een inittab-bestand om initialisatie-instructies te bevatten. Upstart behoudt het inittab-bestand voor achterwaartse compatibiliteit. Hier is de opstartvolgorde van System V:

  • Het init-systeem is afkomstig uit het binaire bestand /sbin/init.
  • Zodra het init-systeem in het geheugen is geladen, leest het zijn eerste bestand op /etc/inittab.
  • Een van de vermeldingen in dit bestand bepaalt het runlevel waarin de machine moet opstarten. Als de waarde voor het runlevel bijvoorbeeld is ingesteld op 5, start Linux op in de grafische modus voor meerdere gebruikers met netwerkondersteuning ingeschakeld (gebruikelijk in distributies die zijn ontworpen voor desktopgebruik). Het hier opgegeven runlevel staat bekend als het standaard runlevel, omdat dit het niveau is dat altijd zal worden gebruikt.
  • Vervolgens kijkt het init-systeem verder in het /etc/inittab-bestand en leest welke init-scripts het moet uitvoeren voor dat runlevel.

Door te zoeken welke scripts moeten worden uitgevoerd voor een bepaald runlevel, ontdekt het init-systeem welke services het moet opstarten. Deze init-scripts zijn de plaatsen waar u doorgaans het opstartgedrag voor afzonderlijke services configureert, op dezelfde manier als we de MySQL-service in het eerste deel van deze handleiding hebben geconfigureerd.

Structuur van System V Init-scripts

In dit gedeelte bekijken we init-scripts in detail. System V-configuratiebestanden of init-scripts zijn de elementen die services beheren. Init-scripts initialiseren een service, vandaar de naam init-script.

Elke service heeft zijn eigen init-script. Het MySQL-init-script bestuurt bijvoorbeeld de MySQL-server. Applicatieleveranciers leveren de init-scripts voor hun specifieke applicatie, terwijl systeemeigen Linux-services worden meegeleverd met de installatie van het besturingssysteem. Wanneer u een aangepaste applicatie maakt, kunt u hier ook uw eigen aangepaste init-scripts voor maken.

Om een service zoals de MySQL-server te starten, wordt het binaire programma eerst in het geheugen geladen. Afhankelijk van de configuratie kan het programma op de achtergrond blijven draaien om clientverbindingen te blijven accepteren. Het init-script van de service regelt het starten, stoppen of herladen van de binaire applicatie. Init-scripts in System V zijn shell-scripts. Een andere naam hiervoor is rc-scripts (run command).

System V-mappenstructuur

De bovenliggende map voor init-scripts is de /etc-map. De /etc/init.d-map is de daadwerkelijke map voor de init-shell-scripts. De scripts zijn via symlinks gekoppeld aan de rc-mappen.

Er zijn verschillende rc-mappen binnen de /etc-map, elk met een nummer in de naam. De nummers vertegenwoordigen verschillende runlevels. Als u de inhoud van de map weergeeft, ziet u namen als /etc/rc0.d, /etc/rc1.d, /etc/rc2.d, enz.

Als u de inhoud van elk van de rc-mappen bekijkt, ziet u bestanden die beginnen met K of S in hun bestandsnaam, gevolgd door twee cijfers. Deze bestanden bevatten symbolische koppelingen die terugverwijzen naar de daadwerkelijke init-shellscripts van het eigenlijke programma. De letters K en S zijn afkortingen: K betekent Kill of Stop, terwijl S staat voor Start. De twee cijfers in de bestandsnamen vertegenwoordigen de volgorde van uitvoering. Als u een bestand ziet met de naam K05script_name, zal dit worden uitgevoerd vóór een bestand met de naam K09script_name.

Opstarten

Nu we verdergaan met de opstartvolgorde, laten we eens kijken hoe de init-scripts worden aangeroepen.

De S- en K-scripts worden niet rechtstreeks door het init-systeem aangeroepen. In plaats daarvan worden ze aangeroepen door een ander script: het /etc/init.d/rc-script. Het /etc/inittab-bestand geeft de init-daemon instructies over in welk runlevel het systeem standaard moet opstarten. Afhankelijk van het opgegeven runlevel roept een regel in het /etc/inittab-bestand het /etc/init.d/rc-script aan, waarbij het standaard runlevel als parameter wordt doorgegeven. Met behulp van deze parameter roept het script de bestanden aan onder de bijbehorende /etc/rcN.d-map, waarbij N het runlevel aangeeft. Als de server bijvoorbeeld opstart met runlevel 5, worden de bijbehorende bestanden onder de /etc/rc5.d-map aangeroepen.

In de rc-map worden alle K-scripts numeriek uitgevoerd met het argument stop, terwijl alle S-scripts op vergelijkbare wijze worden uitgevoerd met het argument start. De bijbehorende daadwerkelijke init-shellscripts voor het programma waarnaar de bestanden onder /etc/rcN.d-symlinks verwijzen, worden respectievelijk aangeroepen met de stop en start -parameters.

In eenvoudige bewoordingen gebeurt er telkens wanneer een Linux-systeem een bepaald runlevel binnengaat of hiernaar overschakelt, dat bepaalde scripts worden uitgevoerd om sommige services te stoppen, terwijl andere worden uitgevoerd om andere services te starten. Dit proces zorgt ervoor dat elk proces dat niet in een bepaalde Linux-status hoort te draaien, wordt gestopt, en elk proces dat wel moet draaien, automatisch wordt gestart.

System V automatisch starten

Wanneer u een service inschakelt om automatisch te starten bij het opstarten, wijzigt u rechtstreeks het init-gedrag. Als u bijvoorbeeld een service configureert om automatisch te starten bij runlevel 2, maakt het init-proces de juiste symbolische koppelingen aan in de /etc/rc2.d-map. Om u te helpen dit te begrijpen, leggen we dit uit aan de hand van een voorbeeld.

System V-voorbeeld

Om u een praktisch voorbeeld te geven, gebruiken we de MySQL-serviceconfiguratie uit deel 1. Log daarom in op de Debian 6 VPS met uw sudo/root-gebruiker via ssh (of putty als u Windows gebruikt), en ga verder met de volgende stappen.

Stap 1: Open en bekijk het inittab-bestand

Voer eerst de volgende opdracht in om de inhoud van het inittab-bestand op de terminal te bekijken:

De inhoud van het bestand zou er ongeveer zo uit moeten zien:

Het getal 2 geeft het runlevel aan waarmee het systeem start. In dit geval is runlevel 2 de standaard, dus dit Debian-systeem start in runlevel 2 als multi-user, tekstmodus. U kunt de volgende opdracht uitvoeren om dit te bevestigen:

Het zal een uitvoer tonen die lijkt op:

Stap 2: De rc-mappen onderzoeken

Voer vervolgens de volgende opdracht uit om de rc-mappen weer te geven:

Hier is een screenshot van de uitvoer:

root screenshot

Zoals we eerder in het inittab-bestand hebben gezien, is het systeem geconfigureerd om op te starten in runlevel 2, daarom zullen de scripts onder /etc/rc2.d worden uitgevoerd bij het opstarten van het systeem. U kunt de inhoud van deze map weergeven met de opdracht:

Zoals u aan de uitvoer kunt zien, zijn de bestanden slechts symbolische koppelingen die verwijzen naar de daadwerkelijke scriptbestanden onder /etc/init.d. Hier is een fragment van de uitvoer:

service crash 1

Er zijn geen K-scripts in deze map, alleen S- (start) scripts. De scripts starten de hier gekoppelde services, zoals rsync. U kunt ook de vermelde mysql-service opmerken, die we in het volgende subonderwerp bespreken.

Stap 3: Het Init-script onderzoeken

Wanneer een service die compatibel is met System V wordt geïnstalleerd, maakt deze een shellscript aan in de map /etc/init.d. U kunt de beschikbaarheid van het MySQL-shellscript controleren door de volgende opdracht in te voeren:

Het toont de onderstaande uitvoer:

screenshot output

Het bestand is vrij groot. U kunt de volgende opdracht invoeren om de inhoud ervan te bekijken:

Stap 4: chkconfig of sysv-rc-conf gebruiken

Chkconfig is een opdracht die u kunt gebruiken in op RHEL gebaseerde distributies zoals CentOS om System V-compatibele services in of uit te schakelen. U kunt het ook gebruiken om geïnstalleerde services en hun respectievelijke runlevels op te sommen. Hier is de opdracht daarvoor (werkt op CentOS):

In Debian-distributies bestaat een dergelijk hulpprogramma niet standaard. De update-rc.d in Debian-systemen installeert en verwijdert alleen services van runlevels. Er is een aangepast hulpprogramma beschikbaar dat u kunt gebruiken om de chkconfig-functionaliteit naar Debian-systemen te brengen. Voer de volgende opdracht in om het te installeren:

Zodra het is geïnstalleerd, kunt u de volgende opdracht uitvoeren om het gedrag van de runlevels voor verschillende services te bekijken:

De uitvoer van deze opdracht is opgemaakt in een tabel die links de servicenaam toont en het runlevel waaronder de service wordt uitgevoerd:

service crash 2

De X geeft het runlevel aan waaronder de service zal draaien. Met dit hulpprogramma kunt u een service voor een runlevel in- of uitschakelen met behulp van de pijltjestoetsen en de spatiebalk. Druk op Q om het hulpprogramma af te sluiten.

Stap 5: Test het opstartgedrag van MySQL tijdens het opstarten van het systeem

In de bovenstaande schermafbeelding kunt u zien dat de mysql-service is ingeschakeld op runlevels 2,3,4,5. U kunt MySQL uitschakelen met de volgende opdracht:

De uitvoer ziet er als volgt uit. Merk op dat de service is gestopt voor alle runlevels:

service crash 3

Voer de onderstaande opdracht uit om de inhoud van de map te bekijken:

Zie de mysql-regel in de onderstaande uitvoer:

De uitvoer toont dat de symlink is veranderd in K, wat Kill (stoppen) betekent. Daarom zal MySQL standaard niet automatisch starten op runlevel 2. Telkens wanneer u een service in- of uitschakelt in System V, is dit wat er gebeurt. Zolang er een S (start)-script in de standaard runlevel-map voor een service staat, zal de init-daemon die service starten tijdens het opstarten van het systeem.

Om de service weer in te schakelen, voert u de volgende opdracht in:

Stap 6: Test het opstartgedrag van MySQL na een systeemcrash

In dit gedeelte bespreken we hoe System V omgaat met crashes van services. U kunt deze kennis gebruiken om het gedrag van uw aangepaste services na een crash te configureren.

In het eerste deel van deze handleiding hadden we een wijziging aangebracht in het bestand /etc/inittab om ervoor te zorgen dat MySQL automatisch start na een crash. We hebben de volgende regel toegevoegd om dit gedrag in te schakelen:

We kunnen dit gedrag controleren door een paar tests uit te voeren. Start eerst uw VPS opnieuw op door de volgende opdracht in te voeren:

Controleer na de herstart met welke proces-ID's mysql_safe en mysqld worden uitgevoerd, voer de volgende opdracht in om de proces-ID's op te vragen:

De uitvoer die we kregen was:

Noteer de proces-ID's. In ons geval waren dat 1836 en 186338. Simuleer nu een crash door het proces te beëindigen met de -9-schakelaar door de volgende opdracht in te voeren. Vergeet niet deze te vervangen door uw eigen proces-ID's:

Controleer na een paar minuten de status van MySQL door de volgende opdracht uit te voeren:

De uitvoer geeft aan dat MySQL actief is, wat betekent dat het opnieuw is opgestart na de gesimuleerde crash. Als u de opdracht ps -ef | grep mysql opnieuw uitvoert, zult u zien dat zowel mysqld_safe als mysqld-processen actief zijn, hoewel met nieuwe ID's.

U kunt proberen de processen meerdere keren te beëindigen en ze zullen na een paar minuten opnieuw opstarten. Dit gedrag is mogelijk door de regel die we hebben toegevoegd aan het /etc/inittab-bestand. Dit is hoe u services configureert om automatisch opnieuw op te starten na een crash in System V. Om de syntaxis nogmaals te bekijken, raadpleegt u deel 1 van deze handleiding.

Sommige aangepaste services kunnen bugs bevatten en na meerdere pogingen niet opnieuw opstarten. De init-daemon zal proberen een service opnieuw op te starten, maar als dit binnen twee minuten meer dan tien keer mislukt, schakelt het Linux-systeem de service maximaal 5 minuten uit. Dit helpt het systeem stabiel te houden en zorgt ervoor dat er geen systeembronnen worden verspild aan crashende services. Het is een goed idee om uw systeemlogboeken te controleren om problemen met uw aangepaste toepassingen te identificeren die moeten worden opgelost.

Inleiding tot Upstart

Het System V init-systeem is lange tijd cruciaal geweest voor Linux-distributies. Maar zoals dat gaat met technologie, blijft het zich ontwikkelen. Het Linux-ecosysteem is enorm gegroeid dankzij de steun van de open-sourcegemeenschap. System V laadt taken en services op een geserialiseerde manier, wat complexiteit met zich meebrengt en tijd kost. Bovendien zorgde de introductie van moderne plugbare opslagmedia, waarvoor System V niet was ontworpen, voor de behoefte aan een ander init-systeem.

De ontwikkelaars van Ubuntu begonnen te werken aan een ander initialisatiesysteem. Dit init-systeem was ontworpen om het besturingssysteem sneller te laden, te zorgen voor een nette opruiming van gecrashte services, de afhankelijkheid tussen systeemservices voorspelbaar te houden en rekening te houden met plugbare opslagmedia. De Upstart-daemon was geboren.

Upstart init heeft op de volgende manieren verschillende voordelen ten opzichte van System V init:

  • Upstart laadt services niet serieel zoals System V, waardoor de opstarttijd van een systeem wordt verkort.
  • Het is ontworpen om gecrashte services beter af te handelen met een nette opruiming en het opnieuw opstarten van de service.
  • Upstart maakt gebruik van een flexibel gebeurtenissysteem om de afhandeling van services in verschillende staten aan te passen.
  • De init vermijdt de complexe shellscripts voor het laden en beheren van services zoals in System V. Upstart maakt gebruik van eenvoudige configuratiebestanden die gemakkelijk te begrijpen en aan te passen zijn.
  • Upstart is gebouwd met achterwaartse compatibiliteit in gedachten. Het script /etc/init.d/rc wordt nog steeds uitgevoerd om systeemeigen System V-services te beheren.
  • Het voorkomt het behouden van overtollige symbolische koppelingen die allemaal naar hetzelfde script verwijzen.

Upstart-gebeurtenissen

Upstart is gebeurtenisgestuurd (event-based), waardoor meerdere gebeurtenissen aan dezelfde service kunnen worden gekoppeld. Deze op gebeurtenissen gebaseerde architectuur zorgt voor flexibel servicebeheer. Elke gebeurtenis kan een shellscript aanroepen dat specifiek is voor de gebeurtenis.

Upstart-gebeurtenissen omvatten:

  • Starting
  • Started
  • Stopping
  • Stopped

Tussen een gebeurtenis door kan een service zich in verschillende staten bevinden, inclusief maar niet beperkt tot:

  • Waiting
  • Pre-start
  • Starting
  • Post-start
  • Running
  • Pre-stop
  • Stopping
  • Post-stop

Upstart init kan worden geconfigureerd om acties te ondernemen voor elk van deze staten, vandaar het flexibele ontwerp.

Upstart Init-opstartvolgorde

De Upstart init voert het /etc/init.d/rc-script uit bij het opstarten, net als System V. Dit script voert alle System V init-scripts normaal uit om achterwaartse compatibiliteit te garanderen.

Upstart-configuratiebestanden bevinden zich in de map /etc/init, dus daar zoekt het standaard en voert het de shell-opdrachten uit die in de configuratiebestanden in deze map staan.

Upstart-configuratiebestanden

De Upstart-init gebruikt serviceconfiguratiebestanden om services te beheren, in tegenstelling tot bash-scripts die in System V worden gebruikt. De naamgevingsstandaard voor deze serviceconfiguratiebestanden is service_name.conf.

De bestanden bevatten platte tekst verdeeld in verschillende secties die stanzas worden genoemd. Elke stanza beschrijft een andere status van een service en het gedrag ervan. Verschillende stanzas beheren verschillende gebeurtenissen van een service. Bijvoorbeeld: waiting, pre-start, start, pre-stop, stopping, etc.

Een stanza bevat shell-commando's, waardoor het mogelijk is om voor elke gebeurtenis van elke service verschillende acties te initiëren. Daarnaast specificeert elk serviceconfiguratiebestand de volgende twee dingen:

  • Op welke runlevels de service moet starten en stoppen.
  • Of de service opnieuw moet opstarten (respawn) als deze crasht.

Upstart-mapstructructuur

De Upstart-serviceconfiguratiebestanden bevinden zich in de map /etc/init. Verwar dit niet met  /etc/init.d.

Upstart-voorbeeld

In dit voorbeeld zien we hoe Upstart een service afhandelt tijdens het opstarten van het systeem en in het geval van een crash. We zullen dieper ingaan op de praktische voorbeelden die in het eerste deel van deze handleiding zijn getoond.

Stap 1: Log in op de Ubuntu 14.0.4-server

Eerst gebruiken we voor het testen van Upstart de tweede VPS, die met Ubuntu 14.0.4. Dat is omdat deze Linux-distributie Upstart standaard implementeert. Gebruik ssh of putty als u Windows gebruikt. U moet inloggen met een gebruiker met root- of sudo-rechten. Ik heb een gebruiker genaamd hackins, dus zo zou ik inloggen:

Vervang dit door uw root/sudo-gebruiker en het openbare IP-adres van uw server. Druk vervolgens op enter en geef een wachtwoord of wachtwoordzin op.

Stap 2: Onderzoek de init- en rc-map

Upstart-configuratiebestanden worden opgeslagen in de map /etc/init. Dit is de map die u gebruikt bij het maken van nieuwe serviceconfiguratiebestanden.

Voer het volgende commando uit om de namen van configuratiebestanden in de map /etc/init weer te geven:

Zoals u zult zien in de uitvoer van het bovenstaande commando, draaien er veel services onder Upstart. Druk op Q om less te sluiten.

Als u het volgende uitvoert om de serviceconfiguratiebestanden voor System V in de rc-map weer te geven, ziet u er slechts een paar:

Stap 3: Onderzoek een Upstart-bestand

In het eerste deel van deze handleiding hadden we een mysql.conf-bestand gebruikt om meer te leren over serverconfiguratie. Om onze kennis uit te breiden, gebruiken we een andere configuratie. Het cron-configuratiebestand is een goede kandidaat. Voer het volgende commando uit om het bestand te openen:

U zou een uitvoer moeten krijgen die lijkt op de onderstaande schermafbeelding:

screenshot 4

Het script is vrij eenvoudig. Let op de volgende belangrijke velden: start on, stop on, fork, en respawn. Laten we definiëren wat deze richtlijnen doen:

  • start on geeft Ubuntu de opdracht om de cron-daemon te starten wanneer het systeem runlevels 2, 3, 4 of 5 binnengaat. Het zal niet draaien op de andere runlevels die hier niet zijn gespecificeerd, d.w.z. 0, 1 of 6.
  • stop on geeft Ubuntu de opdracht om een draaiende daemon te stoppen. In dit geval is er echter een uitroepteken (!) dat een ontkenningsteken is. Het script mag niet worden gestopt op de runlevels na het uitroepteken: 2,3,4,5.
  • fork-richtlijn geeft Upstart de opdracht om het proces los te koppelen van de console en op de achtergrond te laten draaien.
  • respawn-richtlijn geeft het systeem de opdracht om cron automatisch opnieuw te starten als het om welke reden dan ook crasht.

Druk op Ctrl X om de editor te sluiten zonder iets te typen.

Andere Upstart-configuratiebestanden volgen dezelfde structuur, met stanzas voor start, stop en respawn. Sommige configuratiebestanden kunnen aanvullende scriptblokken hebben voor pre-start, pre-stop, post-start en meer. Deze codeblokken vertellen het systeem wat het moet uitvoeren wanneer een proces zich in een van de gedefinieerde statussen bevindt.

Stap 4: Test het opstartgedrag van de MySQL-service nadat het systeem is opgestart

MySQL is standaard ingesteld om automatisch te starten nadat het systeem is opgestart. We zullen proberen dit uit te schakelen en het gedrag te bekijken. In Upstart kan een service worden uitgeschakeld door een bestand te maken genaamd service_name.override onder de /etc/init/ map. De inhoud van het bestand is slechts één woord: manual.

Laten we kijken hoe we deze opdracht kunnen gebruiken om de MySQL-service uit te schakelen. Voer de volgende opdracht in om het bestand te openen met de nano-editor:

Voeg in het geopende bestand de volgende regel toe:

Sla de wijzigingen op door op Ctrl + O te drukken en vervolgens op Enter. Sluit de editor af door op Ctrl + X te drukken. Voer de volgende opdracht uit om de server opnieuw op te starten:

Wacht een paar minuten en log dan opnieuw in. Als u weer bent ingelogd, test u de status van de MySQL-service door de volgende opdracht in te voeren:

De uitvoer zal aangeven dat de service niet actief is:

Dit geeft aan dat MySQL niet automatisch is gestart na het opstarten van het systeem. Open vervolgens het MySQL-configuratiebestand en controleer of de start richtlijn is gewijzigd:

De uitvoer zal aangeven dat er niets is gewijzigd:

Dit betekent dat als uw service niet automatisch start en u alleen het configuratiebestand van de service controleert (service_name.conf), u de fout mogelijk niet vindt. U moet ook controleren of het bestand service_name.override in de map bestaat.

Voer de volgende opdracht in om het override-bestand te verwijderen en de MySQL-service opnieuw in te schakelen. Start vervolgens de server opnieuw op:

Zodra de server is opgestart, test u de status van de MySQL-service opnieuw:

Er zou moeten staan dat de MySQL-service automatisch is gestart.

Step 5: Test the MySQL Service Startup Behavior after a System Crash

Standaard start de MySQL-service automatisch opnieuw op als deze crasht. Om dit gedrag te stoppen, bewerken we het mysql.conf-bestand. Voer de volgende opdracht in om het bestand te openen met de nano-editor:

Zoek de respawn-richtlijnregels en becommentarieer ze zoals hieronder getoond met #:

Voer de volgende opdrachten uit om de service opnieuw te starten:

We hebben de bovenstaande opdrachten gebruikt om de service te stoppen en te starten, omdat het gebruik van initctl restart of initctl reload hier niet zou werken. Wanneer u de opdracht uitvoert om de MySQL-service te starten, geeft de uitvoer een PID voor MySQL weer zoals:

Onze PID was 1439. Noteer vervolgens wat u kreeg toen u de opdracht uitvoerde, we zullen dit in de volgende stap gebruiken. Om een crash te simuleren, beëindigt u het MySQL-proces met de volgende opdracht, vergeet niet uw PID te vervangen zoals hierboven uitgelegd:

Om te controleren of MySQL na de crash opnieuw is opgestart, wacht u een paar minuten en voert u de volgende opdracht in:

De uitvoer zal aangeven dat MySQL is gestopt:

Probeer de status nog een paar keer te controleren om te zien of er verandering is. U zult merken dat MySQL gestopt blijft. Dit komt omdat het configuratiebestand van de service de respawn-richtlijnen niet heeft (degene die we hebben becommentarieerd). Bekijk deel 1 van deze handleiding voor meer uitleg over de respawn-richtlijn.

Waarom hebben we je laten zien hoe je het automatisch herstarten van services na een systeemstart of crash uitschakelt? Dit is voornamelijk voor probleemoplossing. Als je service bijvoorbeeld start en blijft crashen, wil je deze mogelijk uitschakelen zodat je het probleem kunt oplossen en je systeem stabiel kunt houden. Je kunt ook voorkomen dat sommige oude serviceconfiguraties automatisch herstarten als je upgradet naar een nieuwe Linux-distributie die standaard wordt geleverd met systemd, die in de volgende sectie wordt besproken.

Systemd-introductie

Systemd is het nieuwste init-systeem, dat te vinden is in de meest recente Linux-distributies. Het bevat veel componenten die samen een modern Linux-systeem vormen.

Systemd beheert niet alleen de services, maar ook het hele Linux-systeem. In deze sectie richten we ons op hoe systemd het gedrag van services regelt na een systeemstart of crash.

Systemd is achterwaarts compatibel met System V-init-scripts en -commando's. Dus als je services hebt die zijn geconfigureerd voor System V, zullen deze ook onder Systemd draaien. De meeste administratieve commando's van Upstart en System V zijn aangepast om met Systemd to werken. Systemd hernoemt zichzelf naar init tijdens het opstarten. Er bestaat een /sbin/init-bestand dat een symlink is naar /bin/systemd.

Systemd-configuratiebestanden: Unit-bestanden

Systemd-configuratie bestaat uit unit-bestanden. Elk unit-bestand vertegenwoordigt een systeembron. Hoewel de andere twee init-systemen (d.w.z. System V en Upstart) verantwoordelijk waren voor het beheren van services van een Linux-systeem, beheert Systemd niet alleen de service-daemons, maar ook andere soorten systeembronnen zoals apparaatpaden van het besturingssysteem, sockets, koppelpunten, enz. Unit-bestanden slaan informatie over de bron op.

Elk unit-bestand vertegenwoordigt een specifieke systeembron met een naamgevingsstijl van service_name.unit_type. Dit betekent dat je bestanden zult vinden zoals home.mount, dbus.service, sshd.socket, enz. Unit-bestanden zijn eenvoudige tekstbestanden met een declaratieve syntaxis die gemakkelijk te begrijpen en aan te passen is.

Mapstructuur

De hoofdlocatie van systeemeigen unit-bestanden is de /lib/systemd/system/-map. Unit-bestanden die je zelf maakt of die door systeembeheerders op maat zijn gemaakt, en andere gewijzigde systeemeigen unit-bestanden worden opgeslagen in de /etc/systemd/system-map.

Als een unit-bestand met dezelfde naam bestaat in zowel /lib/systemd/system/ als /etc/systemd/system-mappen, zal systemd die onder de /etc-map gebruiken.

Wanneer je een service inschakelt om te starten tijdens het opstarten of een ander target/runlevel, wordt er een symbolische koppeling gemaakt voor dat service-unit-bestand onder de juiste mappen in /etc/systemd/system. Unit-bestanden in de /etc/systemd/system-map zijn slechts symbolische koppelingen naar de bestanden met een vergelijkbare naam in de /lib/systemd/system-map.

Systemd-init-volgorde: Target-units

Target-units zijn unieke typen unit-bestanden die meestal eindigen op .target. Target-units verschillen van andere typen unit-bestanden omdat ze niet één specifieke bron vertegenwoordigen. In plaats daarvan vertegenwoordigen ze de status van het hele systeem op een bepaald moment.

Om dit te bereiken, groeperen en starten target-units meerdere unit-bestanden die deel uitmaken van een specifieke status. Hoewel Systemd-targets en System V-runlevels losjes met elkaar vergeleken kunnen worden, ze zijn niet hetzelfde. Een target-unit-bestand heeft een naam in plaats van een nummer. Je zult bijvoorbeeld iets vinden als multi-user.target in plaats van runlevel 3 of reboot.target in plaats van runlevel 6. Een Linux-systeem kan opstarten met multi-user.target. In dit geval brengt het de server in feite naar runlevel 2, 3 of 4, wat het systeem start in de tekstmodus voor meerdere gebruikers met netwerkfunctionaliteit ingeschakeld.

Het verschil zit in de manier waarop de server naar dat niveau wordt gebracht. System V start services sequentieel op. Aan de andere kant controleert systemd tijdens het opstarten van het systeem of er andere services of bronnen bestaan en bepaalt het de volgorde van laden.

Een ander verschil tussen systemd target-units en System V-runlevels is dat een Linux-distributie die System V gebruikt, in slechts één runlevel zal bestaan. Als je het runlevel wijzigt, zal het simpelweg overschakelen naar en bestaan in dat nieuwe runlevel. Aan de andere kant kunnen target-unitbestanden inclusief zijn. Bovendien zorgt het activeren van een target-unit ervoor dat andere target-units als onderdeel daarvan worden geladen. Als je bijvoorbeeld een Linux-systeem opstart met een grafische gebruikersinterface, zal deze de graphical.target geactiveerd hebben. Dit zorgt er op zijn beurt automatisch voor dat multi-user.target ook wordt geladen en geactiveerd.

Hier is een tabel die runlevels en targets vergelijkt.

Runlevel (System V) Target Units (systemd)
runlevel 0 poweroff.target
runlevel 1 rescue.target
runlevel 2,3,4 multi-user.target
runlevel 5 graphical.target
runlevel 6 reboot.target

Systemd default.target

In systemd is default.target het equivalent van het standaard runlevel in System V. We hebben gezien dat het standaard runlevel in System V werd gedefinieerd in het inittab-bestand. In systemd hebben we het default.target-bestand. Het standaard target-bestand is opgeslagen in de /etc/systemd/system-map. Het verwijst via een symlink naar een van de target-unitbestanden onder /lib/systemd/system. Het wijzigen van het standaard target betekent simpelweg het opnieuw maken van een symbolische koppeling en het wijzigen van het runlevel van het systeem.

In System V specificeerde de inittab in welke map Linux de init-scripts kan vinden. Dit kon elk van de rc-mappen zijn, zoals eerder uitgelegd. Aan de andere kant bepaalt het standaard target van systemd welke resource-units tijdens het opstarten moeten worden geladen. Alle gedefinieerde units worden geladen. Ze worden echter niet allemaal parallel geladen, en ook niet allemaal sequentieel. Het laden van de resource-unit hangt af van de andere resources die het wants of requires.

Systemd-afhankelijkheden: Wants en Requires

In dit gedeelte bespreken we hoe Systemd omgaat met afhankelijkheden. We hebben gezien dat met Upstart het parallel laden van services mogelijk is bij het gebruik van configuratiebestanden. We hebben ook besproken hoe System V runlevels gebruikt om te bepalen welke service automatisch moet worden gestart of moet wachten tot een andere service of resource beschikbaar is. Op vergelijkbare wijze kunnen Systemd-services worden geconfigureerd om in een of meer targets te laden, of te wachten tot een andere service of resource beschikbaar is.

In Systemd zal een unitbestand dat requires een andere unit vereist, niet starten totdat de vereiste unit is geladen en actief is geworden. Als de vereiste unit niet kan worden geladen terwijl de eerste unit actief is, zal de eerste unit stoppen.

Dit gedrag zorgt voor systeemstabiliteit. Een service die requires een specifieke resource (bijvoorbeeld een poort) vereist om beschikbaar en actief te zijn, kan er dus toe worden aangezet te wachten tot de resource beschikbaar is (d.w.z. de poort is geopend).

In tegenstelling hiermee stelt een unit die wants een andere unit wil, dergelijke beperkingen niet. Deze stopt niet als de gewenste unit stopt terwijl de aanroepende unit nog actief is. Bijvoorbeeld sommige niet-essentiële services in de graphical-target-modus.

Systemd-voorbeeld

Laten we kijken hoe we het gedrag van een service onder systemd kunnen configureren.

Stap 1: Log in op je VPS-instantie

We gebruiken MySQL als een praktijkvoorbeeld van een service en CentOS 7 als de server. Om de stappen in de praktijk te doorlopen en de concepten te begrijpen, log je in op je CentOS 7 VPS of maak er een aan op CloudSigma. Een VPS met CentOS 7, Debian 7 of 8, of Ubuntu 15-distributie of nieuwer is geschikt voor dit gedeelte, aangezien ze allemaal met systemd worden geleverd. Log in met het ssh-commando of gebruik PuTTY als je Windows gebruikt:

Stap 2: Onderzoek het default.target-bestand en de afhankelijkheden

De opstartvolgorde van Systemd volgt een lange keten van afhankelijkheden die we in dit gedeelte in detail zullen bespreken.

  • default.target

Het default.target-bestand regelt de services die starten tijdens een normale opstartprocedure. Je kunt het standaard target-unitbestand weergeven met het volgende commando:

De uitvoer toont zoiets als de onderstaande schermafbeelding:

screenshot

De schermafbeelding laat zien dat het standaard target via een symlink verwijst naar het multi-user.target-bestand in de /lib/systemd/system/ map. Dit betekent dat het systeem standaard zal opstarten onder multi-user.target, equivalent aan runlevel 3.

  • multi-user.target.wants

Voer de volgende opdracht in om alle services te zien die het multi-user.target-bestand wil:

De uitvoer bevat veel regels, hier is een fragment:

Zoals de uitvoer laat zien, zijn dit symbolische koppelingen die verwijzen naar de werkelijke unit-bestanden in de /lib/systemd/system/ map. We hebben mysqld.service gemarkeerd om u erop te wijzen dat deze ook deel uitmaakt van multi-user.target. Als u wilt controleren of een bepaalde service is geconfigureerd om op te starten, kunt u de opdracht voor dat bestand aanpassen. We kunnen bijvoorbeeld de uitvoer filteren om de mysql- of cron-daemon te vinden met de volgende opdrachten:

De uitvoer toont:

Voer de volgende opdracht in om het resultaat voor de cron-daemon te filteren:

De uitvoer toont:

Naast de multi-user.target, bestaan er andere typen targets, d.w.z. system-update.target of basic.target.

Voer de volgende opdracht in om te zien van welke targets de multi-user target afhankelijk is:

De uitvoer toont:

Dit betekent dat basic-target eerst moet worden geladen om het systeem te starten in de multi-user.target-modus.

  • basic-target

Voer de volgende opdracht in om te zien welke andere targets de basic.target wil:

De uitvoer toont:

  • sysinit.target

U kunt de volgende opdracht uitvoeren om te zien of er vereiste targets zijn voor sysinit.target. De syntaxis van de opdracht is hetzelfde. U kunt deze blijven aanpassen om te zien welke target-units vereist zijn door een andere target-unit naarmate u vordert. Hier is de opdracht:

De uitvoer zal tonen dat er geen vereiste units zijn voor sysinit.target. We kunnen controleren of er andere services en targets gewenst door sysinit.target met behulp van de volgende opdracht:

De uitvoer toont een lange lijst van services en targets die gewenst worden door sysinit.target. Een deel van de uitvoer ziet u hieronder:

Tijdens de systeeminitialisatie met system4, blijft het systeem niet in slechts één target. In plaats daarvan laadt het services op een afhankelijke manier terwijl het van de ene target naar de andere overgaat.

Stap 3: Een unit-bestand onderzoeken

Laten we eens kijken hoe een unit-bestand eruitziet. We hebben het MySQL-service-unit-bestand in het eerste deel van deze handleiding gebruikt, en dat zullen we opnieuw gebruiken. We kunnen echter ook naar een ander service-unit-bestand kijken – het sshd-unit-bestand. Voer de volgende opdracht in om het sshd-configuratiebestand te openen:

Hieronder ziet u een screenshot met de regels in het bestand:

unit screesnhot

Zoals u kunt zien, maken de omkaderde codeblokken in het bestand het gemakkelijk te begrijpen en indien nodig aan te passen. Hieronder vindt u enkele belangrijke richtlijnen om te begrijpen:

  • After – de After clausule vertelt het systeem om de service pas te laden nadat de opgegeven targets en services zijn geladen. In dit geval wordt de SSHD-service geladen nadat de network-target en de keygen-service zijn geladen.
  • Wants – de Wants clausule toont welke targets deze service willen. In dit geval wil de ssh-keygen.service de sshd.service. Echter, als sshd mislukt of crasht, zal dit niet leiden tot het uitschakelen van de ssh-keygen.service.

Druk op Ctrl + X om de editor te sluiten.

Stap 4: Het opstartgedrag van de MySQL-service testen bij het opstarten van het systeem

In dit gedeelte laten we u zien hoe u het gedrag van de MySQL-service kunt wijzigen en testen bij het opstarten van het systeem. In het vorige gedeelte hebben we gezien dat de mysqld.service gewenst wordt door multi-user.target. Daarom zal deze automatisch starten bij het opstarten.

U kunt de service uitschakelen door de volgende opdracht uit te voeren:

Het uitvoeren van de opdracht toont aan dat de mysql-symlink is verwijderd uit de /etc/systemd/system/multi-user.target.wants/ map. Om dit te testen, voert u de volgende opdracht uit om te controleren of MySQL nog steeds gewenst wordt door multi-user.target:

Het commando retourneert niets. Als u probeert de server opnieuw op te starten en de MySQL-status controleert, zal deze niet actief zijn, wat betekent dat deze niet automatisch is gestart tijdens het opstarten.

Schakel nu de service opnieuw in met het commando:

De uitvoer toont een symlink. Als u uw server opnieuw opstart, zou MySQL automatisch moeten starten. Het inschakelen van een Systemd-service maakt een symbolische koppeling in de wants-map van het standaarddoel. Het uitschakelen van een Systemd-service verwijdert de symbolische koppeling uit de wants-map.

Stap 5: Test het opstartgedrag van de MySQL-service na een servicecrash

Standaard start de MySQL-service automatisch op als deze crasht. We kunnen dit gedrag uitschakelen in het Systemd-configuratiebestand voor MySQL. Laten we eerst naar het bestand kijken. Voer het volgende commando in om het bestand te openen:

De onderstaande schermafbeelding toont de uitvoer:

screen shot 5

De waarde van de Restart-richtlijn is ingesteld op on-failure. Dit betekent dat de MySQL-service opnieuw zal starten na onzuivere exitcodes, time-outs of onzuivere signalen. Hieronder vindt u een tabel met enkele van de herstartparameters uit de man-pagina.

Herstartinstellingen/Exit-oorzaken no always on-success on-failure on-abnormal on-abort on-watchdog
Schone exitcode of signaal X X
Onzuivere exitcode X X
Onzuiver signaal X X X X
Time-out X X X
Watchdog X X X X

De twee belangrijke richtlijnen in een Systemd-unitbestand zijn Restart en RestartSec. Ze regelen het crashgedrag van de service. Restart specificeert wanneer de service opnieuw moet starten, en RestartSec specificeert hoe lang deze moet wachten voordat deze na een crash opnieuw start. Om het herstartgedrag uit te schuiven, markeert u de Restart-richtlijn als commentaar door een # aan het begin van de regel toe te voegen, zoals weergegeven:

Laad nu de systeemdaemon opnieuw en laad vervolgens de mysqld-service opnieuw met de volgende commando's:

Voer vervolgens het volgende commando uit om de Main PID van de MySQL-service te vinden:

screenshot 7

De Main PID voor onze test was 23809. Noteer die van u om in het volgende commando te gebruiken. Simuleer een crash door het proces te beëindigen met het commando kill -9. Vergeet ook niet om dit te vervangen door het procesnummer dat u in uw test hebt gekregen:

Als u het commando uitvoert dat de MySQL-status controleert, zult u zien dat deze niet actief is en niet opnieuw is opgestart:

screesnshot 8

Het blijft in de mislukte status zolang de Restart-richtlijn als commentaar is gemarkeerd in het mysqld.service-configuratiebestand. Dit simuleert een crash waarbij een service stopt en niet meer opstart.

Om de service opnieuw in te schakelen, kunt u het mysqld.service-configuratiebestand bewerken, de Restart-richtlijn uit het commentaar halen, en vervolgens opslaan en sluiten. Laad, net als eerder, de daemon opnieuw en start de service opnieuw. Dit brengt de service terug naar de oorspronkelijke configuratie, en nu kan deze automatisch starten na een crash. Tot slot is dat alles voor het configureren van een service om automatisch te starten na een crash. Als u services wilt configureren om automatisch te starten na een crash, hoeft u alleen maar de Restart-richtlijn toe te voegen (en desgewenst kunt u ook de RestartSec-richtlijn toevoegen) onder de [Service]-sectie van het service-unitbestand.

Conclusie

In deze handleiding hebben we besproken hoe Linux omgaat met services tijdens het opstarten of na een crash. Om het initialisatieproces van het Linux-systeem te begrijpen, hebben we de drie init-systemen besproken die Linux gebruikt: System V, Upstart en Systemd. We hebben hun evolutie besproken en hoe elk init-proces werkt met betrekking tot het automatisch starten van een service na een herstart of crash van het systeem.

Aangezien zowel de init-daemons als de Linux-distributies in de loop der tijd zijn geëvolueerd, moet u niet vergeten de versie van de Linux-distributie die u gebruikt te controleren, zodat u weet welke init-daemon uw systeem systeemeigen ondersteunt.

Systeemeigen Linux-applicaties en de meeste applicaties van derden starten al automatisch op na een systeemstart of crash, dus u hoeft niets te doen. De kennis in deze handleiding is cruciaal wanneer u het opstart- en herstartgedrag van uw eigen aangepaste services configureert, of bij het oplossen van problemen met services die voortdurend crashen.

Veel computerplezier!

author

Manpreet Singh

Auteur · CloudSigma

Preslav Dobrev is een creatief ontwerper bij CloudSigma, met de nadruk op een consistente bedrijfsidentiteit door middel van traditionele en innovatieve marketingkanalen. Hij is bedreven in het samenvoegen van artistieke visie met strategische marketing om impactvolle merkverhalen te creëren.

Reacties

Nog geen reacties. Wees de eerste.