Zpět na blog

Jak nakonfigurovat službu v Linuxu pro automatické spuštění po restartu nebo pádu systému: Část 2 (Teoretické vysvětlení)

Jak nakonfigurovat službu v Linuxu pro automatické spuštění po restartu nebo pádu systému: Část 2 (Teoretické vysvětlení)

V tomto druhém dílu dvoudílného návodu na konfiguraci Linux služeb tak, aby se automaticky spouštěly po restartu nebo pádu systému, podrobně probereme init systém. Můžete se podívat na 1. část této série: Jak nakonfigurovat službu Linuxu pro automatické spuštění po restartu nebo pádu systému: Praktické příklady zde.

Tento návod bude hodně teoretický. Proto byste jej měli používat jako referenci k hlubšímu pochopení toho, jak init systém v Linuxu funguje. V prvním dílu tohoto návodu jsme sdíleli několik ukázek kódu a spouštěcích skriptů, které init systém čte při spouštění. Použili jsme také MySQL jako příklad, abychom se naučili, jak povolit a zakázat automatické spouštění služby Linuxu po pádu nebo restartu. Jak jste se dozvěděli v prvním dílu tohoto dvoudílného návodu, v různých distribucích Linuxu se používají tři init systémy: System V, Upstart a Systemd. Můžete se podívat na první část tohoto návodu, abyste pochopili, která distribuce a verze je nakonfigurována pro použití konkrétního init systému.

V tomto návodu vysvětlíme kód, který jsme použili v první části návodu. Podrobněji rozebereme příkazy a konfigurační soubory, které init systém používá. Začněme!

Požadavky

V závěru první části tohoto dvoudílného návodu jsme zmínili, že byste měli nechat běžet tři testovací servery. Pokud jste je smazali, můžete se vrátit a znovu je vytvořit. To vám pomůže sledovat tento návod. Tři testovací servery, které byste měli mít, jsou:

  • Ubuntu 9.04 a starší, nebo Debian 6 x64 (použijeme jej k demonstraci init systému System V)
  • Ubuntu 14.04 x64 (použijeme jej k demonstraci Upstartu). Zde je návod, jak snadno nastavit váš Ubuntu server.
  • CentOS 7 x64 (použijeme jej k demonstraci Systemd).

Na každém ze serverů, které budete používat ke spouštění příkazů, byste měli mít uživatele s oprávněními sudo. Tento návod na konfiguraci souboru sudoers v Linuxu vás může provést.

Poznámka:  Příkazy v tomto návodu budou zasahovat do systémových služeb. Proto byste je neměli aplikovat na živém produkčním serveru.

Runlevely

A Runlevel je provozní úroveň, která popisuje aktuální stav systému Linux ve vztahu k tomu, jaké služby jsou k dispozici. Tento koncept pochází ze System V init. Když se systém Linux spouští, inicializuje jádro, vstoupí do jednoho runlevelu a spustí spouštěcí skript spojený s tímto runlevelem. Při spuštění můžete provést pouze jeden runlevel.

Mezi další příklady runlevelů patří stav vypnutí, režim restartu, režim jednoho uživatele atd. Každá úroveň určuje, které služby se mají v daném stavu spustit. Některé služby mohou běžet na více než jedné úrovni, zatímco jiné ne.

Existuje sedm runlevelů: od 0 do 6. Níže je uvedena definice těchto sedmi runlevelů:

  • Runlevel 0: Vypnutí systému
  • Runlevel 1: Režim jednoho uživatele a záchranný režim
  • Runlevely 2, 3, 4: Víceuživatelský a textový režim s povolenou sítí
  • Runlevel 5: Víceuživatelský, síťový a grafický režim
  • Runlevel 6: Restart systému

Runlevely se nemusí nutně spouštět sekvenčně. Runlevely 2, 3 a 4 se liší v závislosti na distribuci Linuxu, kterou používáte. V některých distribucích můžete implementovat runlevel 4 a v jiných ne. Když jste povolili automatické spouštění služby, jak bylo vysvětleno v první části, ve skutečnosti jste ji přidali do runlevelu. V System V operační systém začíná s konkrétním runlevelem a během spouštění se pokouší spustit všechny služby spojené s tímto runlevelem. V Systemd jsou runlevely cíle (targets), o kterých budeme hovořit v sekci Systemd.

Init a PID 1

Init systém je úplně první proces, který se spustí při startu systému Linux a načtení jádra (Kernelu) do paměti. Provádí různé úkoly, včetně určování toho, jak se uživatelský proces nebo systémová služba načte, v jakém pořadí a zda se má spustit automaticky. V každé distribuci Linuxu je každý proces identifikován ID procesu (PID) a init má PID 1. Je rodičem všech ostatních procesů, které se postupně spouštějí při startu systému.

Historie initu

Init systém, který se nachází v nedávných distribucích Linuxu, je vylepšením toho původního. Nejranější verze linuxových distribucí používaly System V init, který se podobně používal v systémech Unix. Jak se Linux vyvíjel, byl implementován init démon Upstart – ten byl vytvořen společností Ubuntu. Nyní (v době psaní tohoto návodu, 2021) máme init démon Systemd – ten byl poprvé implementován distribucí Fedora. Jak se linuxové systémy nadále vyvíjejí, může se objevit novější init systém. V tomto návodu budeme diskutovat o těchto třech: System V, Upstart a Systemd.

Nedávné verze Linuxu se standardně dodávají s init systémem Systemd. Zachovaly si však ostatní starší init systémy kvůli zpětné kompatibilitě. Existují různé implementace System V, které můžete použít v jiných variantách Linuxu. Například FreeBSD, varianta UNIXu, používá BSD init. Starší verze Debianu používají SysVinit. Obě pocházejí ze System V.

Způsob, jakým každá verze init démona spravuje služby, se liší. Vylepšení přidaná do každé verze byla zaměřena na robustní nástroj pro správu služeb, který by zvládl vše, co linuxový systém potřebuje od služeb, zařízení, portů a dalších prostředků. Bylo zapotřebí výkonného systému, který by dokázal načítat prostředky paralelně a dokázal se elegantně zotavit z pádu systému.

Spouštěcí sekvence System V

System V využívá soubor inittab k uchování inicializačních instrukcí. Upstart uchovává soubor inittab kvůli zpětné kompatibilitě. Zde je průběh spouštění System V:

  • Init systém pochází z binárního souboru /sbin/init.
  • Jakmile se init systém načte do paměti, přečte svůj první soubor v /etc/inittab.
  • Jeden ze záznamů v tomto souboru určuje úroveň spuštění (runlevel), do které by měl počítač nabootovat. Pokud je například hodnota úrovně spuštění specifikována jako 5, Linux nabootuje ve víceuživatelském grafickém režimu s povolenou sítí (běžné u distribucí určených pro desktopové použití). Zde specifikovaná úroveň spuštění je známá jako výchozí úroveň spuštění (default runlevel), protože se použije vždy.
  • Poté se init systém podívá dále do /etc/inittab souboru a přečte, které init skripty potřebuje pro tuto úroveň spuštění spustit.

Vyhledáním skriptů, které se mají spustit pro danou úroveň spuštění, init systém zjistí, které služby potřebuje spustit. V těchto init skriptech obvykle konfigurujete chování při spuštění pro jednotlivé služby, stejně jako jsme konfigurovali službu MySQL v první části tohoto návodu.

Struktura init skriptů System V

V této části se podrobně podíváme na init skripty. Konfigurační soubory System V nebo init skripty jsou to, co řídí služby. Init skripty inicializují službu, odtud název init skript.

Každá služba má svůj vlastní init skript. Například init skript MySQL řídí MySQL server. Dodavatelé aplikací poskytují init skripty pro své konkrétní aplikace, zatímco nativní linuxové služby jsou dodávány s instalací operačního systému. Když vytvoříte vlastní aplikaci, můžete pro ni také vytvořit vlastní init skripty.

Chete-li spustit službu, jako je MySQL server, její binární program se nejprve načte do paměti. V závislosti na své konfiguraci může program nadále běžet na pozadí a přijímat připojení klientů. Init skript služby se stará o spuštění, zastavení nebo opětovné načtení binární aplikace. Init skripty v System V jsou shellové skripty. Jiný název pro ně je rc (run command) skripty.

Adresářová struktura System V

Nadřazeným adresářem pro init skripty je adresář /etc. Adresář /etc/init.d je skutečným adresářem pro init shellové skripty. Tyto skripty jsou symbolicky odkazovány do adresářů rc.

V adresáři /etc se nachází několik adresářů rc, z nichž každý má ve svém názvu číslo. Čísla představují různé úrovně spuštění. Pokud vypíšete obsah adresáře, uvidíte názvy jako /etc/rc0.d, /etc/rc1.d, /etc/rc2.d, atd.

Pokud si prohlédnete obsah jednotlivých adresářů rc, uvidíte soubory, které začínají na K nebo S ve svém názvu souboru, následované dvěma číslicemi. Tyto soubory obsahují symbolické odkazy ukazující zpět na skutečné init shellové skripty skutečného programu. Písmena K a S jsou zkratky: K znamená Kill nebo Stop, zatímco S znamená Start. Tyto dvě číslice v názvech souborů představují pořadí spouštění. Pokud vidíte soubor s názvem K05script_name, spustí se před souborem s názvem K09script_name.

Spouštění

Pokročíme-li v sekvenci spouštění, podívejme se, jak se volají init skripty.

Skripty S a K nejsou volány přímo systémem init. Jsou spíše volány jiným skriptem: /etc/init.d/rc skriptem. Soubor /etc/inittab instruuje init démona, v jakém runlevelu se má systém standardně spustit. V závislosti na zadaném runlevelu řádek v souboru /etc/inittab volá skript /etc/init.d/rc a předává výchozí runlevel jako parametr. Pomocí tohoto parametru skript zavolá soubory v odpovídajícím adresáři /etc/rcN.d, kde N označuje runlevel. Pokud se například server spouští s runlevelem 5, budou volány odpovídající soubory v adresáři /etc/rc5.d.

Uvnitř adresáře rc jsou všechny skripty K spouštěny numericky s argumentem stop, zatímco všechny skripty S jsou spouštěny podobně s argumentem start. Odpovídající skutečné init shellové skripty pro program, na které odkazují symbolické odkazy v /etc/rcN.d, budou volány s parametry stop a start v tomto pořadí.

Zjednodušeně řečeno, kdykoli systém Linux vstoupí do určitého runlevelu nebo na něj přepne, spustí se určité skripty, které zastaví některé služby, zatímco jiné se spustí, aby spustily jiné služby. Tento proces zajišťuje, že jakýkoli proces, který by v daném stavu Linuxu neměl běžet, je zastaven, a jakýkoli proces, který by běžet měl, je spuštěn automaticky.

Automatické spouštění System V

Když povolíte automatické spouštění služby při bootování, přímo tím upravujete chování init. Pokud například nakonfigurujete službu tak, aby se automaticky spouštěla v runlevelu 2, proces init vytvoří příslušné symbolické odkazy v adresáři /etc/rc2.d. Pro lepší pochopení si to vysvětlíme na příkladu.

Příklad System V

Abychom vám poskytli praktický příklad, použijeme konfiguraci služby MySQL z 1. části. Přihlaste se tedy k VPS s Debianem 6 jako uživatel sudo/root pomocí ssh (nebo putty, pokud jste ve Windows), a pokračujte následujícími kroky.

Krok 1: Otevření a prozkoumání souboru inittab

Nejprve zadejte následující příkaz pro zobrazení obsahu souboru inittab v terminálu:

Obsah souboru by měl vypadat nějak takto:

Číslo 2 označuje runlevel, se kterým se systém spouští. V tomto případě je výchozí runlevel 2, takže tento systém Debian se spustí v runlevelu 2 jako víceuživatelský, textový režim. Pro potvrzení můžete spustit následující příkaz:

Zobrazí se výstup podobný tomuto:

Krok 2: Prozkoumání adresářů rc

Dále pro výpis adresářů rc spusťte následující příkaz:

Zde je snímek obrazovky s výstupem:

root screenshot

Jak jsme viděli v souboru inittab dříve, systém je nakonfigurován pro spuštění v runlevelu 2, proto se při spuštění systému provedou skripty v /etc/rc2.d. Obsah tohoto adresáře můžete vypsat pomocí příkazu:

Jak můžete vidět z výstupu, soubory jsou pouze symbolické odkazy ukazující na skutečné soubory skriptů v /etc/init.d. Zde je ukázka výstupu:

service crash 1

V tomto adresáři nejsou žádné skripty K, pouze skripty S (start). Skripty spustí služby zde odkazované, jako například rsync. Můžete si také všimnout uvedené služby mysql, o které budeme hovořit v dalším podtématu.

Krok 3: Prozkoumání skriptu Init

Při instalaci služby kompatibilní se System V se v adresáři /etc/init.d vytvoří shell skript. Dostupnost shell skriptu MySQL můžete zkontrolovat zadáním následujícího příkazu:

Zobrazí se následující výstup:

screenshot output

Soubor je poměrně velký. Pro zobrazení jeho obsahu můžete zadat následující příkaz:

Krok 4: Použití chkconfig nebo sysv-rc-conf

Chkconfig je příkaz, který můžete použít v distribucích založených na RHEL, jako je CentOS k povolení nebo zakázání služeb kompatibilních se System V. Můžete jej také použít k výpisu nainstalovaných služeb a jejich příslušných úrovní spuštění. Zde je příkaz pro tento účel (funguje na CentOS):

V distribucích Debian takový nástroj nativně neexistuje. Nástroj update-rc.d v systémech Debian pouze instaluje a odebírá služby z úrovní spuštění. K dispozici je vlastní nástroj, který můžete použít k přenesení funkcionality chkconfig do systémů Debian. Pro jeho instalaci zadejte následující příkaz:

Po instalaci můžete spustit následující příkaz pro zobrazení chování úrovní spuštění pro různé služby:

Výstup tohoto příkazu je formátován do tabulky, která vlevo zobrazuje název služby a úroveň spuštění, pod kterou služba běží:

service crash 2

Písmeno X označuje úroveň spuštění, pod kterou bude služba spuštěna. Tento nástroj vám umožňuje zakázat nebo povolit službu pro danou úroveň spuštění pomocí šipek a mezerníku. Pro ukončení nástroje stiskněte Q.

Krok 5: Otestování chování MySQL při spouštění systému

Na snímku obrazovky výše vidíte, že služba mysql je povolena na úrovních spuštění 2,3,4,5. MySQL můžete zakázat pomocí následujícího příkazu:

Výstup vypadá takto. Všimněte si, že služba byla zastavena pro všechny úrovně spuštění:

service crash 3

Spuštěním níže uvedeného příkazu zobrazíte obsah adresáře:

Podívejte se na řádek mysql v níže uvedeném výstupu:

Výstup ukazuje, že se symbolický odkaz změnil na K, což znamená Kill (zastavit). Proto se MySQL ve výchozím nastavení nespustí automaticky na úrovni spuštění 2. Kdykoli povolíte nebo zakážete službu v System V, stane se toto. Dokud v adresáři výchozí úrovně spuštění pro danou službu existuje skript S (start), démon init tuto službu spustí při bootování systému.

Chcete-li službu znovu povolit, zadejte následující příkaz:

Krok 6: Otestování chování MySQL při spouštění po pádu systému

V této části probereme, jak System V řeší pády služeb. Tyto znalosti můžete využít ke konfiguraci chování vlastních služeb po pádu.

V první části tohoto návodu jsme provedli změnu v souboru /etc/inittab, abychom umožnili automatické spuštění MySQL po pádu. Pro povolení tohoto chování jsme přidali následující řádek:

Toto chování můžeme ověřit provedením několika testů. Nejprve restartujte své VPS zadáním následujícího příkazu:

Po restartu zkontrolujte, s jakými ID procesů běží mysql_safe a mysqld. Pro získání ID procesů zadejte následující příkaz:

Získali jsme následující výstup:

Poznamenejte si ID procesů. V našem případě to bylo 1836 a 186338. Nyní nasimulujte pád ukončením procesu pomocí přepínače -9 zadáním následujícího příkazu. Nezapomeňte je nahradit vašimi ID procesů:

Po několika minutách zkontrolujte stav MySQL spuštěním následujícího příkazu:

Výstup indikuje, že MySQL běží, což znamená, že byl po simulovaném pádu znovu spuštěn. Pokud znovu spustíte příkaz ps -ef | grep mysql, zjistíte, že oba procesy mysqld_safe a mysqld běží, i když s novými ID.

Můžete zkusit procesy ukončit několikrát a po několika minutách se znovu spustí. Toto chování umožňuje řádek, který jsme přidali do souboru /etc/inittab . Takto se v System V konfigurují služby pro automatické restartování po pádu. Chcete-li si znovu prohlédnout syntaxi, podívejte se na 1. část tohoto návodu.

Některé vlastní služby mohou obsahovat chyby a po několika pokusech se je nepodaří znovu spustit. Init démon se pokusí službu restartovat, ale pokud selže více než desetkrát během dvou minut, systém Linux službu až na 5 minut zakáže. To pomáhá udržovat systém stabilní a zajišťuje, že se systémové prostředky neplýtvají na padající služby. Je dobré zkontrolovat systémové protokoly a identifikovat problémy s vašimi vlastními aplikacemi, které je třeba opravit.

Úvod do Upstart

Init systém System V byl pro linuxové distribuce po dlouhou dobu klíčový. Nicméně, jak už to u technologií bývá, vývoj jde kupředu. Linuxový ekosystém se díky podpoře open-source komunity nesmírně rozrostl. System V načítá úlohy a služby sériově, což přináší složitost a časovou náročnost. Navíc zavedení moderních vyměnitelných paměťových médií, pro která nebyl System V navržen, vyvolalo potřebu jiného init systému.

Vývojáři v Ubuntu začali pracovat na jiném inicializačním systému. Tento init systém byl navržen tak, aby zvládal rychlejší načítání operačního systému, zajišťoval korektní vyčištění po pádu služeb, udržoval předvídatelné závislosti mezi systémovými službami a zohledňoval vyměnitelná paměťová média. Tak se zrodil démon Upstart.

Upstart init má oproti System V init několik výhod v následujících oblastech:

  • Upstart nenačítá služby sériově jako System V, čímž zkracuje dobu spouštění systému.
  • Je navržen tak, aby lépe zvládal spadlé služby s korektním vyčištěním a opětovným spuštěním služby.
  • Upstart využívá flexibilní systém událostí pro přizpůsobení správy služeb v různých stavech.
  • Tento init se vyhýbá složitým shellovým skriptům pro načítání a správu služeb, jako tomu bylo v System V. Upstart používá jednoduché konfigurační soubory, které lze snadno pochopit a upravit.
  • Upstart byl vytvořen s ohledem na zpětnou kompatibilitu. Skript /etc/init.d/rc stále běží pro správu nativních služeb System V.
  • Vyhýbá se udržování nadbytečných symbolických odkazů, které všechny ukazují na stejný skript.

Události Upstart

Upstart je založen na událostech, což umožňuje asociovat s jednou službou více událostí. Tato architektura založená na událostech zajišťuje flexibilní správu služeb. Každá událost může volat shellový skript specifický pro danou událost.

Mezi události Upstart patří:

  • Starting
  • Started
  • Stopping
  • Stopped

Mezi událostmi může být služba v různých stavech, mimo jiné:

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

Upstart init lze nakonfigurovat tak, aby prováděl akce pro každý z těchto stavů, což dokládá jeho flexibilní design.

Spouštěcí sekvence Upstart Init

Upstart init spouští při startu skript /etc/init.d/rc, stejně jako System V. Tento skript normálně spouští jakékoli init skripty System V, aby byla zajištěna zpětná kompatibilita.

Konfigurační soubory Upstart se nacházejí v adresáři /etc/init, takže tam ve výchozím nastavení hledá a spouští shellové příkazy nalezené v konfiguračních souborech v tomto adresáři.

Konfigurační soubory Upstart

Upstart init používá k řízení služeb konfigurační soubory služeb, na rozdíl od bash skriptů používaných v System V. Standard pojmenování těchto konfiguračních souborů služeb je service_name.conf.

Soubory obsahují prostý text rozdělený do různých sekcí nazývaných stanzy. Každá stanza popisuje jiný stav služby a její chování. Různé stanzy řídí různé události služby. Například waiting, pre-start, start, pre-stop, stopping atd.

Stanza obsahuje shellové příkazy, což umožňuje iniciovat několik akcí pro každou událost každé služby. Každý konfigurační soubor služby navíc specifikuje následující dvě věci:

  • Na kterých úrovních spuštění (runlevels) by se měla služba spouštět a zastavovat.
  • Zda se má služba automaticky restartovat (respawn), pokud selže.

Adresářová struktura Upstart

Konfigurační soubory služeb Upstart se nacházejí v adresáři /etc/init . Nezaměňujte jej s  /etc/init.d.

Příklad Upstart

V tomto příkladu uvidíme, jak Upstart zpracovává službu během spouštění systému a v případě havárie. Půjdeme do větších podrobností a vysvětlíme si praktické příklady ukázané v první části tohoto návodu.

Krok 1: Přihlaste se k serveru Ubuntu 14.0.4

Nejprve pro testování Upstart použijeme druhý VPS, ten, na kterém běží Ubuntu 14.0.4. Je to proto, že tato distribuce Linuxu implementuje Upstart nativně. Pokud používáte Windows, použijte ssh nebo putty. Musíte se přihlásit jako uživatel s oprávněními root nebo sudo. Mám uživatele s názvem hackins, takže bych se přihlásil takto:

Nahraďte svým root/sudo uživatelem a veřejnou IP adresou serveru. Poté stiskněte enter a zadejte heslo nebo přístupovou frázi.

Krok 2: Prozkoumejte adresáře init a rc

Konfigurační soubory Upstart jsou uloženy v adresáři /etc/init. Je to adresář, který budete používat při vytváření nových konfiguračních souborů služeb.

Chcete-li vypsat názvy konfiguračních souborů v adresáři /etc/init, spusťte následující příkaz:

Jak uvidíte z výstupu výše uvedeného příkazu, pod Upstart běží mnoho služeb. Stisknutím klávesy Q ukončíte program less.

Pokud spustíte následující příkaz pro výpis konfiguračních souborů služeb pro System V v adresáři rc, uvidíte jich pouze několik:

Krok 3: Prozkoumejte soubor Upstart

V první části tohoto návodu jsme použili soubor mysql.conf k seznámení se s konfigurací serveru. Abychom si rozšířili znalosti, použijme jinou konfiguraci. Konfigurační soubor cron je dobrým kandidátem. Pro otevření souboru zadejte následující příkaz:

Měli byste získat výstup podobný níže uvedenému snímku obrazovky:

screenshot 4

Skript je poměrně přímočarý. Všimněte si následujících důležitých polí: start on, stop on, fork, a respawn. Pojďme si definovat, co tyto direktivy dělají:

  • start on instruuje Ubuntu, aby spustilo démona cron, když systém přejde do úrovní spuštění (runlevels) 2, 3, 4 nebo 5. Na ostatních zde neuvedených úrovních spuštění, tj. 0, 1 nebo 6, nepoběží.
  • stop on instruuje Ubuntu, aby zastavilo běžícího démona. V tomto případě je zde však vykřičník (!), což je znak negace. Skript by neměl být zastaven na úrovních spuštění za vykřičníkem: 2,3,4,5.
  • fork instruuje Upstart, aby odpojil proces od konzole a nechal jej běžet na pozadí.
  • respawn instruuje systém, aby automaticky spustil cron, pokud z jakéhokoli důvodu selže.

Stisknutím Ctrl X ukončíte editor bez psaní čehokoli.

Ostatní konfigurační soubory Upstart se řídí stejnou strukturou, se stanzami pro start, stop a respawn. Některé konfigurační soubory mohou mít další bloky skriptů pro pre-start, pre-stop, post-start a další. Tyto bloky kódu říkají systému, co má provést, když je proces v některém z definovaných stavů.

Krok 4: Otestujte chování spouštění služby MySQL po spuštění systému

MySQL je ve výchozím nastavení nastaveno na automatické spuštění po zavedení systému. Pokusíme se jej zakázat a uvidíme, jak se bude chovat. V Upstart lze službu zakázat vytvořením souboru s názvem service_name.override v adresáři /etc/init/. Obsah souboru je pouze jedno slovo: manual.

Podívejme se, jak můžeme tento příkaz použít k zakázání služby MySQL. Zadáním následujícího příkazu otevřete soubor v editoru nano:

Do otevřeného souboru přidejte následující řádek:

Uložte změny stisknutím Ctrl + O, poté stiskněte Enter. Ukončete editor stisknutím Ctrl + X. Spuštěním následujícího příkazu restartujte server:

Počkejte několik minut a poté se znovu přihlaste. Po opětovném přihlášení otestujte stav služby MySQL zadáním následujícího příkazu:

Výstup bude indikovat, že služba neběží:

To znamená, že se MySQL po spuštění systému nespustilo automaticky. Dále otevřete konfigurační soubor MySQL a zkontrolujte, zda se změnila direktiva start:

Výstup bude indikovat, že se nic nezměnilo:

To znamená, že pokud se vaše služba nespouští automaticky a kontrolujete pouze konfigurační soubor služby (service_name.conf), nemusíte chybu najít. Měli byste také zkontrolovat existenci souboru service_name.override v adresáři.

Zadáním následujícího příkazu odstraňte soubor override a znovu povolte službu MySQL. Poté restartujte server:

Jakmile se server spustí, znovu otestujte stav služby MySQL:

Mělo by se zobrazit, že se služba MySQL spustila automaticky.

Krok 5: Otestování chování při spuštění služby MySQL po pádu systému

Ve výchozím nastavení se služba MySQL po pádu automaticky restartuje. Chcete-li toto chování zastavit, upravíme soubor mysql.conf. Zadáním následujícího příkazu otevřete soubor v editoru nano:

Najděte řádky s direktivou respawn a zakomentujte je, jak je znázorněno níže pomocí #:

Spuštěním následujících příkazů restartujte službu:

K zastavení a spuštění služby jsme použili výše uvedené příkazy, protože použití initctl restart nebo initctl reload by zde nefungovalo. Když spustíte příkaz ke spuštění služby MySQL, na výstupu se zobrazí PID pro MySQL jako:

Naše PID bylo 1439. Dále si poznamenejte, co jste získali při spuštění příkazu, použijeme to v dalším kroku. Chcete-li simulovat pád, ukončete proces MySQL pomocí následujícího příkazu, nezapomeňte nahradit své PID, jak je vysvětleno výše:

Chcete-li zkontrolovat, zda se MySQL po pádu restartovalo, počkejte několik minut a poté zadejte následující příkaz:

Výstup bude indikovat, že MySQL je zastaveno:

Zkuste zkontrolovat stav ještě několikrát, abyste zjistili, zda došlo k nějaké změně. Všimnete si, že MySQL zůstane zastaveno. Je to proto, že konfigurační soubor služby neobsahuje direktivy respawn (ty, které jsme zakomentovali). Další vysvětlení direktivy respawn naleznete v 1. části tohoto návodu.

Proč jsme vám ukázali, jak zakázat automatické restartování služeb po spuštění systému nebo po havárii? Je to hlavně pro účely odstraňování problémů. Pokud se například vaše služba spustí a neustále padá, možná ji budete chtít zakázat, abyste mohli problém vyřešit a zároveň udržet systém stabilní. Můžete také zabránit automatickému restartování některých starých konfigurací služeb, pokud přejdete na novou distribuci Linuxu, která nativně obsahuje systemd, o kterém pojednává další část.

Úvod do Systemd

Systemd je nejnovější init systém, který se nachází v nejnovějších distribucích Linuxu. Obsahuje mnoho komponent, které tvoří moderní linuxový systém.

Systemd spravuje nejen služby, ale také celý systém Linux. V této části se zaměříme na to, jak systemd řídí chování služeb po spuštění systému nebo po havárii.

Systemd je zpětně kompatibilní s init skripty a příkazy System V. Pokud tedy máte nějaké služby nakonfigurované pro System V, poběží také pod Systemd. Většina administrativních příkazů Upstart a System V byla upravena tak, aby fungovala se Systemd. Systemd se při spuštění přejmenuje na init. Existuje soubor /sbin/init, který odkazuje symlinkem na /bin/systemd.

Konfigurační soubory Systemd: Unit soubory

Konfigurace Systemd se skládá z unit souborů. Každý unit soubor představuje systémový prostředek. Zatímco ostatní dva init systémy (tj. System V a Upstart) byly zodpovědné za správu služeb linuxového systému, Systemd spravuje nejen démony služeb, ale také další typy systémových prostředků, jako jsou cesty k operačnímu systému zařízení, sockety, přípojné body atd. Unit soubory ukládají informace o daném prostředku.

Každý unit soubor představuje konkrétní systémový prostředek s formátem názvu service_name.unit_type. To znamená, že najdete soubory jako home.mount, dbus.service, sshd.socket atd. Unit soubory jsou jednoduché textové soubory s deklarativní syntaxí, kterou lze snadno pochopit a upravit.

Adresářová struktura

Hlavním umístěním nativních unit souborů je adresář /lib/systemd/system/. Unit soubory, které vytvoříte vy nebo které jsou vytvořeny na zakázku správci systému, a další upravené nativní unit soubory jsou uloženy v adresáři /etc/systemd/system adresář.

Pokud unit soubor se stejným názvem existuje v obou adresářích /lib/systemd/system/ a /etc/systemd/system, systemd použije ten, který se nachází v adresáři /etc.

Když povolíte spuštění služby při startu systému nebo v jakémkoli jiném cíli/úrovni běhu, vytvoří se pro tento unit soubor služby symbolický odkaz v příslušných adresářích v /etc/systemd/system. Unit soubory v adresáři /etc/systemd/system jsou pouze symbolickými odkazy na soubory s podobným názvem v adresáři /lib/systemd/system.

Sekvence spouštění Systemd: Target jednotky

Target jednotky jsou jedinečné typy unit souborů, které mají obvykle příponu .target. Target jednotky se liší od ostatních typů unit souborů tím, že nepředstavují jeden konkrétní prostředek. Místo toho představují stav celého systému v daném okamžiku.

Za tímto účelem target jednotky seskupují a spouštějí více unit souborů, které jsou součástí určitého stavu. Ačkoli lze cíle Systemd a úrovně běhu (runlevely) System V volně porovnávat, nejsou totéž. Target unit soubor má název namísto čísla. Najdete zde například něco jako multi-user.target namísto runlevel 3 nebo reboot.target namísto runlevel 6. Linuxový systém se může spustit s multi-user.target. V tomto případě to v podstatě přivádí server do runlevelu 2, 3 nebo 4, což spustí systém v textovém režimu pro více uživatelů s povolenou sítí.

Rozdíl spočívá v tom, jak server do této úrovně přivádí. System V spouští služby sekvenčně. Na druhou stranu při spouštění systému systemd kontroluje, zda existují další služby nebo prostředky, a určuje pořadí jejich načítání.

Dalším rozdílem mezi target unity v systemd a runlevely v System V je, že distribuce Linuxu používající System V bude existovat pouze v jednom runlevelu. Pokud runlevel upravíte, jednoduše se přepne do tohoto nového runlevelu a bude v něm existovat. Na druhou stranu soubory target unit mohou být inkluzivní. Aktivace target unit navíc zajišťuje, že se jako její součást načtou i další target unity. Pokud například spustíte systém Linux s grafickým uživatelským rozhraním, bude mít aktivovaný graphical.target. To zase automaticky zajišťuje, že multi-user.target je také načten a aktivován.

Zde je tabulka porovnávající runlevely a targety.

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

V systemd je default.target ekvivalentem výchozího runlevelu v System V. Viděli jsme, že výchozí runlevel v System V byl definován v souboru inittab. V systemd máme soubor default.target. Soubor výchozího targetu je uložen v adresáři /etc/systemd/system. Odkazuje symbolickým odkazem (symlink) na jeden ze souborů target unit v /lib/systemd/system. Změna výchozího targetu jednoduše znamená opětovné vytvoření symbolického odkazu a úpravu runlevelu systému.

V System V soubor inittab určoval, ve kterém adresáři Linux najde init skripty. Mohl to být kterýkoli z adresářů rc, jak bylo vysvětleno dříve. Na druhou stranu výchozí target v systemd určuje jednotky prostředků (resource units), které se mají načíst při spuštění. Načtou se všechny definované jednotky. Ne všechny se však načítají paralelně a ne všechny se načítají sekvenčně. Načítání jednotky prostředku závisí na jiných prostředcích, které chce nebo vyžaduje.

Závislosti v Systemd: Wants a Requires

V této části si ukážeme, jak Systemd zpracovává závislosti. Viděli jsme, že u Upstartu je při použití konfiguračních souborů možné paralelní načítání služeb. Diskutovali jsme také o tom, jak System V používá runlevely k určení, která služba se má automaticky spustit nebo zda má počkat, dokud se nespustí jiná služba nebo prostředek. Podobně lze služby Systemd nakonfigurovat tak, aby se načítaly v jednom nebo více targetech, nebo aby počkaly, dokud se nespustí jiná služba nebo prostředek.

V Systemd se unit soubor, který vyžaduje jinou jednotku, nespustí, dokud se vyžadovaná jednotka nenačte a neaktivuje. Pokud se vyžadovanou jednotku nepodaří načíst, zatímco je první jednotka aktivní, první jednotka se zastaví.

Toto chování zajišťuje stabilitu systému. Službu, která vyžaduje konkrétní prostředek (například port), aby byl dostupný a aktivní, lze tak nechat čekat, dokud nebude prostředek k dispozici (tj. port bude otevřen).

Naopak jednotka, která chce jinou jednotku, taková omezení neukládá. Nezastaví se, pokud se chtěná jednotka zastaví, zatímco volající jednotka je stále aktivní. Příkladem jsou některé nepodstatné služby v režimu graphical-target.

Příklad Systemd

Podívejme se, jak můžeme nakonfigurovat chování služby pod systemd.

Krok 1: Přihlaste se ke své instanci VPS

Jako reálnou službu budeme používat MySQL a jako server CentOS 7. Chcete-li si kroky prakticky projít a pochopit koncepty, přihlaste se ke svému VPS s CentOS 7 nebo si jej vytvořte na CloudSigma. Pro tuto část je vhodný VPS se systémem CentOS 7, Debian 7 nebo 8, případně distribucí Ubuntu 15 nebo novější, protože všechny obsahují systemd. Přihlaste se pomocí příkazu ssh, nebo pokud používáte Windows, použijte PuTTY:

Krok 2: Prozkoumejte soubor default.target a závislosti

Spouštěcí sekvence Systemd se řídí dlouhým řetězcem závislostí, o kterých budeme podrobně hovořit v této části.

  • default.target

Soubor default.target řídí služby, které se spouštějí při běžném spuštění systému. Soubor výchozí target jednotky můžete vypsat pomocí následujícího příkazu:

Výstup vypadá podobně jako na snímku obrazovky níže:

screenshot

Snímek obrazovky ukazuje, že výchozí target odkazuje symbolickým odkazem na soubor multi-user.target v /lib/systemd/system/ adresář. To znamená, že systém se ve výchozím nastavení spustí pod multi-user.target, což odpovídá runlevel 3.

  • multi-user.target.wants

Chcete-li zobrazit všechny služby, které soubor multi-user.target vyžaduje, zadejte následující příkaz:

Výstup obsahuje mnoho řádků, zde je ukázka:

Jak ukazuje výstup, jedná se o symbolické odkazy ukazující na skutečné soubory jednotek v adresáři /lib/systemd/system/ . Zvýraznili jsme mysqld.service, abychom vás upozornili, že je také součástí multi-user.target. Pokud si chcete ověřit, zda je určitá služba nakonfigurována pro spuštění, můžete upravit příkaz pro daný soubor. Můžeme například filtrovat výstupy a vyhledat démony mysql nebo cron pomocí následujících příkazů:

Výstup zobrazí:

Chcete-li filtrovat výsledek pro démona cron, zadejte následující příkaz:

Výstup zobrazí:

Kromě multi-user.target existují i jiné různé typy cílů, např. system-update.target nebo basic.target.

Zadejte následující příkaz, abyste zjistili, na kterých cílech závisí multi-user target:

Výstup ukazuje:

To znamená, že basic-target se musí načíst jako první, aby se systém mohl spustit v režimu multi-user.target.

  • basic-target

Zadejte následující příkaz, abyste zjistili, jaké další cíle basic.target vyžaduje:

Výstup zobrazí:

  • sysinit.target

Spuštěním následujícího příkazu můžete zjistit, zda existují nějaké vyžadované cíle pro sysinit.target. Syntaxe příkazu je stejná. Můžete jej dále upravovat, abyste postupně viděli, které cílové jednotky jsou vyžadovány jinou cílovou jednotkou. Zde je tento příkaz:

Výstup ukáže, že pro sysinit.target neexistují žádné vyžadované jednotky. Můžeme zkontrolovat, zda existují další služby a cíle vyžadované cílem sysinit.target pomocí následujícího příkazu:

Výstup ukazuje dlouhý seznam služeb a cílů vyžadovaných sysinit.target. Část výstupu můžete vidět níže:

Během inicializace systému pomocí system4 se systém nezastaví pouze u jednoho cíle. Místo toho načítá služby závislým způsobem, jak přechází z jednoho cíle do druhého.

Krok 3: Prozkoumání souboru jednotky

Podívejme se, jak soubor jednotky vypadá. V první části tohoto návodu jsme použili soubor jednotky služby MySQL a použijeme jej znovu. Můžeme se však podívat i na jiný soubor jednotky služby – soubor jednotky sshd. Zadáním následujícího příkazu otevřete konfigurační soubor sshd:

Níže je snímek obrazovky zobrazující řádky v souboru:

unit screesnhot

Jak vidíte, bloky kódu vyznačené v souboru usnadňují jeho pochopení a případné úpravy. Níže jsou uvedeny některé důležité direktivy, kterým je třeba porozumět:

  • AfterAfter klauzule říká systému, aby službu načetl až po načtení zadaných cílů a služeb. V tomto případě se služba SSHD načte po načtení síťového cíle a služby keygen.
  • WantsWants klauzule ukazuje, které cíle tuto službu vyžadují. V tomto případě ssh-keygen.service vyžaduje sshd.service. Pokud však sshd selže nebo spadne, neukončí to ssh-keygen.service.

Stisknutím Ctrl + X zavřete editor.

Krok 4: Otestování chování spouštění služby MySQL při spuštění systému

V této části vám ukážeme, jak můžete změnit a otestovat chování služby MySQL při spouštění systému. V předchozí části jsme viděli, že mysqld.service je vyžadována cílem multi-user.target. Proto se při spuštění systému automaticky spustí.

Službu můžete zakázat spuštěním následujícího příkazu:

Spuštění příkazu ukáže, že symbolický odkaz mysql byl odstraněn z adresáře /etc/systemd/system/multi-user.target.wants/ directory. Chcete-li to otestovat, spusťte následující příkaz a ověřte, zda je MySQL stále vyžadováno cílem multi-user.target:

Příkaz nevrátí nic. Pokud se pokusíte restartovat server a zkontrolovat stav MySQL, nepoběží, což znamená, že se při spuštění systému automaticky nespustil.

Nyní službu znovu povolte pomocí příkazu:

Výstup zobrazí symbolický odkaz. Pokud restartujete server, MySQL by se mělo spustit automaticky. Povolení služby Systemd vytvoří symbolický odkaz ve složce wants výchozího cíle (target). Zakázání služby Systemd odstraní symbolický odkaz z wants adresáře.

Krok 5: Otestování chování spouštění služby MySQL po pádu služby

Ve výchozím nastavení se služba MySQL v případě pádu automaticky restartuje. Toto chování můžeme zakázat v konfiguračním souboru Systemd pro MySQL. Nejprve se na soubor podívejme. Pro otevření souboru zadejte následující příkaz:

Snímek obrazovky níže ukazuje výstup:

screen shot 5

Hodnota direktivy Restart je nastavena na on-failure. To znamená, že se služba MySQL restartuje po nečistých návratových kódech, vypršení časového limitu nebo nečistých signálech. Níže je tabulka ukazující některé parametry restartu z manuálové stránky.

Nastavení restartu / Příčiny ukončení no always on-success on-failure on-abnormal on-abort on-watchdog
Čistý návratový kód nebo signál X X
Nečistý návratový kód X X
Nečistý signál X X X X
Vypršení časového limitu X X X
Watchdog X X X X

Dvě důležité direktivy v unit souboru Systemd jsou Restart a RestartSec. Řídí chování služby při pádu. Restart určuje, kdy se má služba restartovat, a RestartSec určuje, jak dlouho má po pádu čekat před restartováním. Chcete-li chování restartu zakázat, zakomentujte direktivu Restart přidáním # na začátek řádku, jak je znázorněno:

Nyní znovu načtěte systémového démona a poté znovu načtěte službu mysqld pomocí následujících příkazů:

Dále spusťte následující příkaz, abyste zjistili hlavní PID (Main PID) služby MySQL:

screenshot 7

Hlavní PID pro náš test byl 23809. Poznamenejte si ten svůj, abyste jej mohli použít v dalším příkazu. Pomocí příkazu kill -9 nasimulujte pád ukončením procesu. Nezapomeňte také nahradit číslo procesu číslem, které jste získali ve svém testu:

Pokud spustíte příkaz, který kontroluje stav MySQL, zjistíte, že není aktivní a nepodařilo se jej restartovat:

screesnshot 8

Zůstane ve stavu selhání, dokud bude direktiva Restart zakomentována v konfiguračním souboru mysqld.service. To simuluje pád, kdy se služba zastaví a znovu se nespustí.

Chcete-li službu znovu povolit, můžete upravit konfigurační soubor mysqld.service, odkomentovat direktivu Restart, poté soubor uložit a zavřít. Stejně jako předtím znovu načtěte démona a restartujte službu. Tím se služba vrátí do původní konfigurace a nyní se po pádu může automaticky spustit. To je pro konfiguraci automatického spouštění služby po pádu vše. Pokud chcete nakonfigurovat služby tak, aby se po pádu automaticky spouštěly, stačí jednoduše přidat direktivu Restart (a pokud chcete, můžete také přidat direktivu RestartSec) pod sekci [Service] v unit souboru služby.

Závěr

V tomto návodu jsme probrali, jak Linux nakládá se službami během spouštění nebo po pádu. Abychom pochopili proces inicializace systému Linux, probrali jsme tři init systémy, které Linux používá: System V, Upstart a Systemd. Probrali jsme jejich vývoj a to, jak každý proces init funguje ve vztahu k automatickému spouštění služby po restartu systému nebo pádu.

Vzhledem k tomu, že se démony init i distribuce Linuxu v průběhu času vyvíjely, nezapomeňte zkontrolovat verzi distribuce Linuxu, kterou používáte, abyste věděli, který démon init váš systém nativně podporuje.

Nativní aplikace pro Linux a většina aplikací třetích stran se po spuštění nebo pádu systému spouštějí automaticky, takže nemusíte nic dělat. Znalosti v tomto návodu jsou klíčové, když konfigurujete chování při spouštění a opětovném spouštění (respawn) svých vlastních služeb, nebo při řešení problémů se službami, které neustále padají.

Příjemnou práci s počítačem!

author

Manpreet Singh

Autor · CloudSigma

Preslav Dobrev je kreativní designér ve společnosti CloudSigma, který se zaměřuje na konzistentní firemní identitu prostřednictvím tradičních i inovativních marketingových kanálů. Je zdatný v propojování umělecké vize se strategickým marketingem za účelem vytváření působivých příběhů značky.

Komentáře

Zatím žádné komentáře. Buďte první.