systemd 常用功能簡介 ==================== :backend: slidy :icons: ++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++ http://www.freedesktop.org/wiki/Software/systemd/[systemd] 是個 Linux 上的 init 實做。 init 是整個作業系統上第一個 process,這類程式的可執行檔通常會放在 /sbin/init,執行時 PID 是 1,也是所有其他 process 的 parent process。 在 Linux 上除了 systemd 以外,還有許多其他的 init 實做,例如: - *SysVinit* (Debian GNU/Linux 和 Debian GNU/Hurd) - *Upstart* (Ubuntu) - *OpenRC* (Gentoo) systemd 不算太新的東西 ---------------------- 現在已經有許多發行版使用 systemd: - Fedora 15 (2011/05) - Arch Linux (2012/10) - Debian 8 (2015/04) - Ubuntu 15.04 (2015/04) systemd 自己做的事情 -------------------- 這些是直接在 systemd 自己 (PID = 1) 裡做的事情: - *+++*+++.service*: 各種服務 (類似 /etc/init.d 或 /etc/rc.d 底下的 script) - *+++*+++.target*: 各種服務的集合 (類似 SysVinit 的 runlevel) - *+++*+++.socket*: 各種不常用服務 (類似 inetd 和 xinetd) - *+++*+++.timer*: 各種定時執行的服務 (類似 cron) - 還有很多其他種類的 systemd unit: *.device、 *.mount、 *.automount、 *.swap、 *.path、 *.snapshot、 *.slice、 *.scope - *systemd-analyze*: 分析開機時間與相依關係 systemd 包含的常用功能 ---------------------- 這些是由其他 process 做的事情: - *systemd-journald*, journalctl: 管理系統紀錄檔 (取代 syslog) - *systemd-logind*, loginctl: 管理使用者 session (取代 ConsoleKit) - *systemd-udevd*: 管理 /dev 下的各種設備 (以前就存在,後來被 systemd 併吞) 一些可能會由 D-Bus API 叫起來執行的小服務: - *systemd-hostnamed*, hostnamectl: 管理主機名稱 - *systemd-localed*, localectl: 管理語言、編碼、鍵盤配置 - *systemd-timedated*, timedatectl: 管理時間、時區和同步時間 systemd 提供但不太常用的功能 ---------------------------- 這些也是其他 process、或是開機時候執行的東西: - *bootctl*: UEFI bootloader - *coredumpctl*: 管理各種服務產生的 core dump - *machinectl*: 管理 container 和 VM - *systemd-networkd*, networkctl: 網路設定 (類似 NetworkManager 的功能) - *systemd-resolved*: 本機 DNS 名稱快取服務 (通常和 systemd-networkd 一起用) 管理系統上執行的各種服務 ------------------------ Linux 提供的 cgroup 功能可以將 process 分群管理並設定資源限制。在 systemd 中,每個服務、每個使用者登入,都會放在不同的 cgroup 裡,因此即使某些服務 產生了許多 child process,或是利用 double fork 的技巧讓親子關係變得混亂, 一樣能輕易找出哪些 process 屬於哪些服務。 - *systemctl status libvirtd.service*: 查看服務狀態,也包含各 process 的指令 - *systemd-cgls*: 像是個以 cgroup 畫成樹的 ps - *systemd-cgtop*: 像是個以 cgroup 為單位的 top 非常基本的指令,相信大家都知道 ------------------------------ [role="incremental"] - 1 * *systemctl status sshd.service* <= service sshd status * *systemctl start sshd.service* <= service sshd start * *systemctl stop sshd.service* <= service sshd stop - 2 * *systemctl enable sshd.service* <= chkconfig sshd on ? * *systemctl disnable sshd.service* <= chkconfig sshd off ? 非常基本的指令,相信大家都知道 ------------------------------ [role="incremental"] - 3 * *systemctl cat sshd.service* <= cat /etc/init.d/sshd ? * *journalctl -u sshd.service* <= grep -r sshd /var/log/ ? * *journalctl _SYSTEMD_UNIT=sshd.service* <= grep -r sshd /var/log/ ? - 4 * *systemctl* <= service --status-all * *systemctl list-unit-files* <= chkconfig ? 非常基本的指令,相信大家都知道 ------------------------------ [role="incremental"] - 5 * *systemctl isolate multi-user.target* <= telinit 3 ? * *systemctl isolate graphical.target* <= telinit 5 ? * *systemctl daemon-reload* <= telinit q * *systemctl daemon-reexec* <= telinit u 為自己的服務寫一個 service 檔 ----------------------------- systemd 設定檔位置: - */usr/lib* 是給 package 用的,這裡的檔案都不該手動修改 - */etc* 是給管理者用的,所有修改都應該放在這裡面 systemd 常用的小規則: - */etc* 裡的東西會取代 */usr/lib* 中同名的檔案 - aaa.service.d 資料夾裡的 *.conf 檔案內容會附加到 aaa.service 檔案 我相信一定比寫給 SysVinit,放在 /etc/init.d 裡的 shell script 簡單、好讀! 一般會留在前景執行的程式 ------------------------ [source,ini] --------------------------------------------------------------------------- [Unit] Description=Xen documentation viewer [Service] Type=simple User=nobody Group=nobody ExecStart=/usr/bin/python3 -m http.server 9980 WorkingDirectory=/usr/share/doc/xen-doc [Install] WantedBy=multi-user.target --------------------------------------------------------------------------- 會自己 fork 去背景執行的程式 ---------------------------- [source,ini] --------------------------------------------------------------------------- [Unit] Description=No-IP DDNS Service After=network.target [Service] Type=forking ExecStart=/usr/local/bin/noip2 [Install] WantedBy=multi-user.target --------------------------------------------------------------------------- 事情做完就結束、不會留在背景的程式 ---------------------------------- [source,ini] --------------------------------------------------------------------------- [Unit] Description=Netfilter Tables ConditionPathExists=/etc/sysconfig/nftables [Service] Type=oneshot RemainAfterExit=yes ExecStart=/usr/sbin/nft -f /etc/sysconfig/nftables ExecStop=/usr/sbin/nft flush ruleset [Install] WantedBy=basic.target --------------------------------------------------------------------------- 其他平常可能比較不會用到的功能 ------------------------------ systemd 不只可以管系統服務,也可以管使用者個人的服務: - *systemctl --user* 用來管理個人服務 - 設定檔放在 *~/.config* ,類似 */etc* systemd 有提供 D-Bus API 給應用程式使用,不用執行 shell script,不用手動 解析指令輸出也能開關服務和查詢服務狀態。 systemd-journald ---------------- - 資料來源 * 本機 syslog socket (/dev/log) * 本機 journald socket (/run/systemd/journal/socket) * 服務印到 stdout 和 stderr 的資料 - Binary log file * /run/log/journal (volatile) 或 /var/log/journal (non-volatile) * 必須用 journalctl 指令或 journal API 來看 * 各個欄位的值可以放 binary data,雖然有這需求的程式應該很少 * 在訊息裡亂加 \n 不會讓管理者上當 systemd-logind -------------- - XDG_RUNTIME_DIR * http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html[ XDG Base Directory Specification] * 通常拿來放僅供個人使用的 fifo、socket、pid 檔,例如 ssh-agent * 第一次登入時產生,所有 session 登出以後消失 - 使用者的登入狀態 * 用 cgroup 管理,不會因為 double fork 或呼叫 setsid 而無法追蹤 * 比 w 或 who 這類用讀寫檔案來管理的程式可靠一些 systemd-logind -------------- - 各種桌面使用者期待要有的功能 * 管理 GPU 的 file descriptor,讓 display server 不用 root 就能執行 * 坐在 console 前面的使用者要有權限燒光碟、用網路攝影機、開 VM * 坐在 console 前面的使用者不用有 root 權限就能關機 * 管理多組鍵盤、滑鼠、螢幕 * 筆電蓋起來是否要睡覺 hostnamed、localed、timedated ----------------------------- - 功能很簡單的小工具 * 以前大家都用 grep 找設定檔,因為這東西很少要改,但每個發行版都放不同地方 * 現在直接用 hostnamectl、localectl、timedatectl 就行了 - 那怎麼不規定一下路徑和設定檔格式就好? * 提供 D-Bus API 給桌面環境使用 * 功能較簡單,也已經有非 Linux 系統的實做: https://uglyman.kremlin.cc/gitweb/gitweb.cgi?p=systembsd.git;a=summary[ systembsd] (Google Summer of Code 2014 - OpenBSD)