Systemd 入門(mén)教程:命令篇

Systemd 入門(mén)教程:實(shí)戰(zhàn)篇

Systemd 入門(mén)教程:命令篇

作者: 阮一峰

日期: 2016年3月 7日

Systemd 是 Linux 系統(tǒng)工具,用來(lái)啟動(dòng)守護(hù)進(jìn)程,已成為大多數(shù)發(fā)行版的標(biāo)準(zhǔn)配置。

本文介紹它的基本用法,分為上下兩篇。今天介紹它的主要命令,下一篇介紹如何用于實(shí)戰(zhàn)。img

 

一、由來(lái)

歷史上,Linux 的啟動(dòng)一直采用init進(jìn)程。

下面的命令用來(lái)啟動(dòng)服務(wù)。

這種方法有兩個(gè)缺點(diǎn)。

一是啟動(dòng)時(shí)間長(zhǎng)。init進(jìn)程是串行啟動(dòng),只有前一個(gè)進(jìn)程啟動(dòng)完,才會(huì)啟動(dòng)下一個(gè)進(jìn)程。

二是啟動(dòng)腳本復(fù)雜。init進(jìn)程只是執(zhí)行啟動(dòng)腳本,不管其他事情。腳本需要自己處理各種情況,這往往使得腳本變得很長(zhǎng)。

 

二、Systemd 概述

Systemd 就是為了解決這些問(wèn)題而誕生的。它的設(shè)計(jì)目標(biāo)是,為系統(tǒng)的啟動(dòng)和管理提供一套完整的解決方案。

根據(jù) Linux 慣例,字母d是守護(hù)進(jìn)程(daemon)的縮寫(xiě)。 Systemd 這個(gè)名字的含義,就是它要守護(hù)整個(gè)系統(tǒng)。

img

( 上圖為 Systemd 作者 Lennart Poettering

使用了 Systemd,就不需要再用init了。Systemd 取代了initd,成為系統(tǒng)的第一個(gè)進(jìn)程(PID等于 1),其他進(jìn)程都是它的進(jìn)程。

上面的命令查看 Systemd 的版本。

Systemd 的優(yōu)點(diǎn)是功能強(qiáng)大,使用方便,缺點(diǎn)是體系龐大,非常復(fù)雜。事實(shí)上,現(xiàn)在還有很多人反對(duì)使用 Systemd,理由就是它過(guò)于復(fù)雜,與操作系統(tǒng)的其他部分強(qiáng)耦合,違反"keep simple, keep stupid"的Unix 哲學(xué)img

(上圖為 Systemd 架構(gòu)圖)

 

三、系統(tǒng)管理

Systemd 并不是一個(gè)命令,而是一組命令,涉及到系統(tǒng)管理的方方面面。

3.1 systemctl

systemctl是 Systemd 的主命令,用于管理系統(tǒng)。

3.2 systemd-analyze

systemd-analyze 命令用于查看啟動(dòng)耗時(shí)。

3.3 hostnamectl

hostnamectl命令用于查看當(dāng)前主機(jī)的信息。

3.4 localectl

localectl命令用于查看本地化設(shè)置。

3.5 timedatectl

timedatectl命令用于查看當(dāng)前時(shí)區(qū)設(shè)置。

3.6 loginctl

loginctl命令用于查看當(dāng)前登錄的用戶(hù)。

 

四、unit

4.1 含義

Systemd 可以管理所有系統(tǒng)資源。不同的資源統(tǒng)稱(chēng)為 Unit(單位)。

Unit 一共分成12種。

  • Service unit:系統(tǒng)服務(wù)
  • Target unit:多個(gè) Unit 構(gòu)成的一個(gè)組
  • Device Unit:硬件設(shè)備
  • Mount Unit:文件系統(tǒng)的掛載點(diǎn)
  • Automount Unit:自動(dòng)掛載點(diǎn)
  • Path Unit:文件或路徑
  • Scope Unit:不是由 Systemd 啟動(dòng)的外部進(jìn)程
  • Slice Unit:進(jìn)程組
  • Snapshot Unit:Systemd 快照,可以切回某個(gè)快照
  • Socket Unit:進(jìn)程間通信的 socket
  • Swap Unit:swap 文件
  • Timer Unit:定時(shí)器

systemctl list-units命令可以查看當(dāng)前系統(tǒng)的所有 Unit 。

4.2 Unit 的狀態(tài)

systemctl status命令用于查看系統(tǒng)狀態(tài)和單個(gè) Unit 的狀態(tài)。

除了status命令,systemctl還提供了三個(gè)查詢(xún)狀態(tài)的簡(jiǎn)單方法,主要供腳本內(nèi)部的判斷語(yǔ)句使用

4.3 Unit 管理

對(duì)于用戶(hù)來(lái)說(shuō),最常用的是下面這些命令,用于啟動(dòng)和停止 Unit(主要是 service)。

4.4 依賴(lài)關(guān)系

Unit 之間存在依賴(lài)關(guān)系:A 依賴(lài)于 B,就意味著 Systemd 在啟動(dòng) A 的時(shí)候,同時(shí)會(huì)去啟動(dòng) B。

systemctl list-dependencies命令列出一個(gè) Unit 的所有依賴(lài)。

上面命令的輸出結(jié)果之中,有些依賴(lài)是 Target 類(lèi)型(詳見(jiàn)下文),默認(rèn)不會(huì)展開(kāi)顯示。如果要展開(kāi) Target,就需要使用--all參數(shù)。

 

五、Unit 的配置文件

5.1 概述

每一個(gè) Unit 都有一個(gè)配置文件,告訴 Systemd 怎么啟動(dòng)這個(gè) Unit 。

Systemd 默認(rèn)從目錄/etc/systemd/system/讀取配置文件。但是,里面存放的大部分文件都是符號(hào)鏈接,指向目錄/usr/lib/systemd/system/,真正的配置文件存放在那個(gè)目錄。

systemctl enable命令用于在上面兩個(gè)目錄之間,建立符號(hào)鏈接關(guān)系。

如果配置文件里面設(shè)置了開(kāi)機(jī)啟動(dòng),systemctl enable命令相當(dāng)于激活開(kāi)機(jī)啟動(dòng)。

與之對(duì)應(yīng)的,systemctl disable命令用于在兩個(gè)目錄之間,撤銷(xiāo)符號(hào)鏈接關(guān)系,相當(dāng)于撤銷(xiāo)開(kāi)機(jī)啟動(dòng)。

配置文件的后綴名,就是該 Unit 的種類(lèi),比如sshd.socket。如果省略,Systemd 默認(rèn)后綴名為.service,所以sshd會(huì)被理解成sshd.service

5.2 配置文件的狀態(tài)

systemctl list-unit-files命令用于列出所有配置文件。

這個(gè)命令會(huì)輸出一個(gè)列表。

這個(gè)列表顯示每個(gè)配置文件的狀態(tài),一共有四種。

  • enabled:已建立啟動(dòng)鏈接
  • disabled:沒(méi)建立啟動(dòng)鏈接
  • static:該配置文件沒(méi)有[Install]部分(無(wú)法執(zhí)行),只能作為其他配置文件的依賴(lài)
  • masked:該配置文件被禁止建立啟動(dòng)鏈接

注意,從配置文件的狀態(tài)無(wú)法看出,該 Unit 是否正在運(yùn)行。這必須執(zhí)行前面提到的systemctl status命令。

一旦修改配置文件,就要讓 SystemD 重新加載配置文件,然后重新啟動(dòng),否則修改不會(huì)生效。

5.3 配置文件的格式

配置文件就是普通的文本文件,可以用文本編輯器打開(kāi)。

systemctl cat命令可以查看配置文件的內(nèi)容。

從上面的輸出可以看到,配置文件分成幾個(gè)區(qū)塊。每個(gè)區(qū)塊的第一行,是用方括號(hào)表示的區(qū)別名,比如[Unit]。注意,配置文件的區(qū)塊名和字段名,都是大小寫(xiě)敏感的。

每個(gè)區(qū)塊內(nèi)部是一些等號(hào)連接的鍵值對(duì)。

5.4 配置文件的區(qū)塊

[Unit]區(qū)塊通常是配置文件的第一個(gè)區(qū)塊,用來(lái)定義 Unit 的元數(shù)據(jù),以及配置與其他 Unit 的關(guān)系。它的主要字段如下。

  • Dsecription:簡(jiǎn)短描述
  • Documentation:文檔地址
  • Requires:當(dāng)前 Unit 依賴(lài)的其他 Unit,如果它們沒(méi)有運(yùn)行,當(dāng)前 Unit 會(huì)啟動(dòng)失敗
  • Wants:與當(dāng)前 Unit 配合的其他 Unit,如果它們沒(méi)有運(yùn)行,當(dāng)前 Unit 不會(huì)啟動(dòng)失敗
  • BindsTo:與Requires類(lèi)似,它指定的 Unit 如果退出,會(huì)導(dǎo)致當(dāng)前 Unit 停止運(yùn)行
  • Before:如果該字段指定的 Unit 也要啟動(dòng),那么必須在當(dāng)前 Unit 之后啟動(dòng)
  • After:如果該字段指定的 Unit 也要啟動(dòng),那么必須在當(dāng)前 Unit 之前啟動(dòng)
  • Conflicts:這里指定的 Unit 不能與當(dāng)前 Unit 同時(shí)運(yùn)行
  • Condition...:當(dāng)前 Unit 運(yùn)行必須滿(mǎn)足的條件,否則不會(huì)運(yùn)行
  • Assert...:當(dāng)前 Unit 運(yùn)行必須滿(mǎn)足的條件,否則會(huì)報(bào)啟動(dòng)失敗

[Install]通常是配置文件的最后一個(gè)區(qū)塊,用來(lái)定義如何啟動(dòng),以及是否開(kāi)機(jī)啟動(dòng)。它的主要字段如下。

  • WantedBy:它的值是一個(gè)或多個(gè) Target,當(dāng)前 Unit 激活時(shí)(enable)符號(hào)鏈接會(huì)放入/etc/systemd/system目錄下面以 Target 名 + .wants后綴構(gòu)成的子目錄中
  • RequiredBy:它的值是一個(gè)或多個(gè) Target,當(dāng)前 Unit 激活時(shí),符號(hào)鏈接會(huì)放入/etc/systemd/system目錄下面以 Target 名 + .required后綴構(gòu)成的子目錄中
  • Alias:當(dāng)前 Unit 可用于啟動(dòng)的別名
  • Also:當(dāng)前 Unit 激活(enable)時(shí),會(huì)被同時(shí)激活的其他 Unit

[Service]區(qū)塊用來(lái) Service 的配置,只有 Service 類(lèi)型的 Unit 才有這個(gè)區(qū)塊。它的主要字段如下。

  • Type:定義啟動(dòng)時(shí)的進(jìn)程行為。它有以下幾種值。
  • Type=simple:默認(rèn)值,執(zhí)行ExecStart指定的命令,啟動(dòng)主進(jìn)程
  • Type=forking:以 fork 方式從父進(jìn)程創(chuàng)建子進(jìn)程,創(chuàng)建后父進(jìn)程會(huì)立即退出
  • Type=oneshot:一次性進(jìn)程,Systemd 會(huì)等當(dāng)前服務(wù)退出,再繼續(xù)往下執(zhí)行
  • Type=dbus:當(dāng)前服務(wù)通過(guò)D-Bus啟動(dòng)
  • Type=notify:當(dāng)前服務(wù)啟動(dòng)完畢,會(huì)通知Systemd,再繼續(xù)往下執(zhí)行
  • Type=idle:若有其他任務(wù)執(zhí)行完畢,當(dāng)前服務(wù)才會(huì)運(yùn)行
  • ExecStart:?jiǎn)?dòng)當(dāng)前服務(wù)的命令
  • ExecStartPre:?jiǎn)?dòng)當(dāng)前服務(wù)之前執(zhí)行的命令
  • ExecStartPost:?jiǎn)?dòng)當(dāng)前服務(wù)之后執(zhí)行的命令
  • ExecReload:重啟當(dāng)前服務(wù)時(shí)執(zhí)行的命令
  • ExecStop:停止當(dāng)前服務(wù)時(shí)執(zhí)行的命令
  • ExecStopPost:停止當(dāng)其服務(wù)之后執(zhí)行的命令
  • RestartSec:自動(dòng)重啟當(dāng)前服務(wù)間隔的秒數(shù)
  • Restart:定義何種情況 Systemd 會(huì)自動(dòng)重啟當(dāng)前服務(wù),可能的值包括always(總是重啟)、on-success、on-failure、on-abnormal、on-abort、on-watchdog
  • TimeoutSec:定義 Systemd 停止當(dāng)前服務(wù)之前等待的秒數(shù)
  • Environment:指定環(huán)境變量

Unit 配置文件的完整字段清單,請(qǐng)參考官方文檔

 

六、Target

啟動(dòng)計(jì)算機(jī)的時(shí)候,需要啟動(dòng)大量的 Unit。如果每一次啟動(dòng),都要一一寫(xiě)明本次啟動(dòng)需要哪些 Unit,顯然非常不方便。Systemd 的解決方案就是 Target。

簡(jiǎn)單說(shuō),Target 就是一個(gè) Unit 組,包含許多相關(guān)的 Unit 。啟動(dòng)某個(gè) Target 的時(shí)候,Systemd 就會(huì)啟動(dòng)里面所有的 Unit。從這個(gè)意義上說(shuō),Target這個(gè)概念類(lèi)似于"狀態(tài)點(diǎn)",啟動(dòng)某個(gè) Target 就好比啟動(dòng)到某種狀態(tài)。

傳統(tǒng)的init啟動(dòng)模式里面,有 RunLevel 的概念,跟 Target 的作用很類(lèi)似。不同的是,RunLevel 是互斥的,不可能多個(gè) RunLevel同時(shí)啟動(dòng),但是多個(gè) Target 可以同時(shí)啟動(dòng)。

Target 與 傳統(tǒng) RunLevel 的對(duì)應(yīng)關(guān)系如下。

它與init進(jìn)程的主要差別如下。

(1)默認(rèn)的 RunLevel(在/etc/inittab文件設(shè)置)現(xiàn)在被默認(rèn)的 Target取代,位置是/etc/systemd/system/default.target,通常符號(hào)鏈接到graphical.target(圖形界面)或者multi-user.target(多用戶(hù)命令行)。

(2)啟動(dòng)腳本的位置,以前是/etc/init.d目錄,符號(hào)鏈接到不同的 RunLevel 目錄(比如/etc/rc3.d、/etc/rc5.d等),現(xiàn)在則存放在/lib/systemd/system/etc/systemd/system目錄。

(3)配置文件的位置,以前init進(jìn)程的配置文件是/etc/inittab,各種服務(wù)的配置文件存放在/etc/sysconfig目錄?,F(xiàn)在的配置文件主要存放在/lib/systemd目錄,在/etc/systemd目錄里面的修改可以覆蓋原始設(shè)置。

 

七、日志管理

Systemd 統(tǒng)一管理所有 Unit 的啟動(dòng)日志。帶來(lái)的好處就是,可以只用journalctl一個(gè)命令,查看所有日志(內(nèi)核日志和應(yīng)用日志)。日志的配置文件是/etc/systemd/journald.conf。

journalctl功能強(qiáng)大,用法非常多。

(完)

 

文檔信息

您最近使用了:

收藏 菜單 QQ