參考了
systemd介紹
1 systemd
systemd是Linux 系統工具,用來啓動守護進程,已成爲大多數發行版的標準配置。目前debian8和centos7均默認使用了systemd工具來管理服務。在此之前,通常使用init的sysv風格的腳本管理本機服務。缺點是不方便處理併發依賴等。systemd相較sysv則更加方便,更加強大,缺點是體系比較龐大,比較複雜。
2 安裝
apt-get install systemd-sysv
3 幫助
man systemd-system.conf
常用命令介紹:
2 systemctl
systemctl是systemd組的一個命令,用於管理系統本身。
常見的有:
# 重啓系統$ sudo systemctl reboot# 關閉系統,切斷電源$ sudo systemctl poweroff# CPU停止工作$ sudo systemctl halt# 暫停系統$ sudo systemctl suspend# 讓系統進入冬眠狀態$ sudo systemctl hibernate# 讓系統進入交互式休眠狀態$ sudo systemctl hybrid-sleep# 啓動進入救援狀態(單用戶狀態)$ sudo systemctl rescue
3 systemd-analyze
# 查看啓動耗時[root@localhost ~]# systemd-analyzeStartup finished in 607ms (kernel) + 3.971s (initrd) + 27.937s (userspace) = 32.517s # 查看每個服務的啓動耗時,blame本義責任,這裏可理解爲追究[root@localhost ~]# systemd-analyze blame 14.290s network.service 5.228s firewalld.service 3.775s tuned.service 1.584s kdump.service 1.415s NetworkManager.service 995ms boot.mount 946ms postfix.service 881ms lvm2-monitor.service 715ms systemd-tmpfiles-setup-dev.service 699ms rhel-readonly.service 519ms systemd-logind.service 409ms polkit.service 382ms lvm2-pvscan@8:2.service 319ms rsyslog.service 223ms auditd.service 223ms kmod-static-nodes.service 208ms systemd-udev-trigger.service 202ms sys-kernel-debug.mount 191ms rhel-import-state.service 158ms rhel-dmesg.service 155ms systemd-sysctl.service 143ms home.mount 132ms systemd-vconsole-setup.service 127ms dev-mapper-centos\x2dswap.swap 122ms systemd-user-sessions.service 112ms dev-mqueue.mount 111ms dev-hugepages.mount 102ms plymouth-read-write.service 85ms systemd-tmpfiles-setup.service 63ms systemd-update-utmp.service 60ms systemd-remount-fs.service 51ms systemd-random-seed.service 44ms plymouth-start.service 39ms systemd-udevd.service 33ms plymouth-quit-wait.service 27ms plymouth-quit.service 22ms systemd-update-utmp-runlevel.service 9ms systemd-journal-flush.service 4ms sys-kernel-config.mount# 顯示瀑布狀的啓動過程流[root@localhost ~]# systemd-analyze critical-chainThe time after the unit is active or started is printed after the "@" character. The time the unit takes to start is printed after the "+" character. multi-user.target @27.914s └─kdump.service @26.327s +1.584s └─network.target @26.327s └─network.service @12.034s +14.290s └─NetworkManager.service @10.617s +1.415s └─firewalld.service @5.388s +5.228s └─basic.target @5.376s └─paths.target @5.376s └─brandbot.path @5.375s └─sysinit.target @5.364s └─systemd-update-utmp.service @5.300s +63ms └─auditd.service @5.074s +223ms └─systemd-tmpfiles-setup.service @4.986s +85ms └─rhel-import-state.service @4.794s +191ms └─local-fs.target @4.793s └─boot.mount @3.798s +995ms └─dev-disk-by\x2duuid-b85ebcc8\x2db3d8\x2d43c0\x2d98ed\x2d7b8842b3aabb.device @3.794s# 顯示指定服務的啓動流$ systemd-analyze critical-chain atd.service
4 hostnamectl
[root@localhost ~]# hostnamectl Static hostname: localhost.localdomain Icon name: computer Chassis: n/a Machine ID: af17eb32eba246d98b89e8ecd838105f Boot ID: 4abee0d67b064429bcff27c145e59bc2 Virtualization: vmware Operating System: CentOS Linux 7 (Core) CPE OS Name: cpe:/o:centos:centos:7 Kernel: Linux 3.10.0-229.el7.x86_64 Architecture: x86_64
5 localectl
[root@localhost ~]# localectlSystem Locale: LANG=en_US.UTF-8 VC Keymap: us X11 Layout: us
6 timedatectl
[root@localhost ~]# timedatectl Local time: Sat 2016-08-06 11:01:06 EDT Universal time: Sat 2016-08-06 15:01:06 UTC RTC time: Sat 2016-08-06 15:01:06 Timezone: America/New_York (EDT, -0400) NTP enabled: n/aNTP synchronized: no RTC in local TZ: no DST active: yes Last DST change: DST began at Sun 2016-03-13 01:59:59 EST Sun 2016-03-13 03:00:00 EDT Next DST change: DST ends (the clock jumps one hour backwards) at Sun 2016-11-06 01:59:59 EDT Sun 2016-11-06 01:00:00 EST[root@localhost ~]# timedatectl set-timezone Asia/Shanghai[root@localhost ~]# timedatectl Local time: Sat 2016-08-06 23:02:32 CST Universal time: Sat 2016-08-06 15:02:32 UTC RTC time: Sat 2016-08-06 15:02:32 Timezone: Asia/Shanghai (CST, +0800) NTP enabled: n/aNTP synchronized: no RTC in local TZ: no DST active: n/a
7 loginctl
[root@localhost ~]# loginctlSESSION UID USER SEAT 1 0 root 2 0 root 2 sessions listed.
systemd的術語介紹
1 Unit單元
Systemd 可以管理所有系統資源。不同的資源統稱爲 Unit(單位)。
Unit類型 一共分成12種。
Service unit:系統服務
Target unit:多個 Unit 構成的一個組
Device Unit:硬件設備
Mount Unit:文件系統的掛載點
Automount Unit:自動掛載點
Path Unit:文件或路徑
Scope Unit:不是由 Systemd 啓動的外部進程
Slice Unit:進程組
Snapshot Unit:Systemd 快照,可以切回某個快照
Socket Unit:進程間通信的 socket
Swap Unit:swap 文件
Timer Unit:定時器
# 通過命令可以查看當前service類型的服務 [root@localhost ~]# systemctl list-units --type=serviceUNIT LOAD ACTIVE SUB DESCRIPTION auditd.service loaded active running Security Auditing Service crond.service loaded active running Command Scheduler dbus.service loaded active running D-Bus System Message Bus firewalld.service loaded active running firewalld - dynamic firewall daemon [email protected] loaded active running Getty on tty1 kdump.service loaded active exited Crash recovery kernel arming ..................LOAD = Reflects whether the unit definition was properly loaded. ACTIVE = The high-level unit activation state, i.e. generalization of SUB. SUB = The low-level unit activation state, values depend on unit type.32 loaded units listed. Pass --all to see loaded but inactive units, too.To show all installed unit files use 'systemctl list-unit-files'. # 查看unit的狀態,說明防火牆已經打開,服務開啓 [root@localhost ~]# systemctl status firewalld.service firewalld.service - firewalld - dynamic firewall daemon Loaded: loaded (/usr/lib/systemd/system/firewalld.service; enabled) Active: active (running) since Sat 2016-08-06 22:51:07 CST; 22min ago Main PID: 854 (firewalld) CGroup: /system.slice/firewalld.service └─854 /usr/bin/python -Es /usr/sbin/firewalld --nofork --nopidAug 06 22:51:07 localhost.localdomain systemd[1]: Started firewalld - dynamic firewall daemon. # 下面的這個命令用於判斷狀態,寫腳本方便使用,只有三種可能unknown,inactive,active [root@localhost ~]# systemctl is-active firewalld.service active # 啓動和停止某個服務systemctl start/stop SERVICE [root@localhost ~]# systemctl start firewalld.service [root@localhost ~]# systemctl stop firewalld.service # systemctl服務reload [root@localhost ~]# systemctl daemon-reload # 查看某個服務的init參數 [root@localhost ~]# systemctl show firewalld.serviceId=firewalld.serviceNames=firewalld.service Requires=dbus.socket basic.target Wants=system.slice WantedBy=basic.target Conflicts=iptables.service ip6tables.service ebtables.service shutdown.targetBefore=network.target libvirtd.service NetworkManager.service shutdown.targetAfter=dbus.socket basic.target system.slice Description=firewalld - dynamic firewall daemon LoadState=loaded ActiveState=inactive SubState=dead FragmentPath=/usr/lib/systemd/system/firewalld.service UnitFileState=enabled ...... CPUAccounting=noCPUShares=1024BlockIOAccounting=noBlockIOWeight=1000MemoryAccounting=noMemoryLimit=18446744073709551615DevicePolicy=autoExecMainStartTimestamp=Sat 2016-08-06 23:18:41 CST ExecMainStartTimestampMonotonic=1669233994ExecMainExitTimestamp=Sat 2016-08-06 23:18:45 CST ExecMainExitTimestampMonotonic=1674104830ExecMainPID=2819ExecMainCode=1ExecMainStatus=0# 查看unit之間的依賴關係 [root@localhost ~]# systemctl list-dependencies firewalld.service
unit文件的配置格式
配置systemctl最重要的就是配置文件了
# 以httpd.service爲例 [root@localhost ~]# cat /usr/lib/systemd/system/httpd.service [Unit] Description=The Apache HTTP Server After=network.target remote-fs.target nss-lookup.target Documentation=man:httpd(8) Documentation=man:apachectl(8) [Service] Type=notify EnvironmentFile=/etc/sysconfig/httpd ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND ExecReload=/usr/sbin/httpd $OPTIONS -k graceful ExecStop=/bin/kill -WINCH ${MAINPID} # We want systemd to give httpd some time to finish gracefully, but still want # it to kill httpd after TimeoutStopSec if something went wrong during the # graceful stop. Normally, Systemd sends SIGTERM signal right after the # ExecStop, which would kill httpd. We are sending useless SIGCONT here to give # httpd time to finish. KillSignal=SIGCONT PrivateTmp=true[Install] WantedBy=multi-user.target 配置文件分爲三個區塊,unit,service,installunit部分: unit通常負責unit元數據和unit間的依賴關係 常見參數如下: Description:簡短描述 Documentation:文檔地址 Requires:當前 Unit 依賴的其他 Unit,如果它們沒有運行,當前 Unit 會啓動失敗 Wants:與當前 Unit 配合的其他 Unit,如果它們沒有運行,當前 Unit 不會啓動失敗 BindsTo:與Requires類似,它指定的 Unit 如果退出,會導致當前 Unit 停止運行 Before:本unit再要執行的unit之前執行 After:本unit在要執行的unit之後執行 Conflicts:有我沒你 Condition...:不滿足指定條件不運行 Assert...:不滿足指定斷言就失敗,拋異常 service部分: 只有service類型的unit纔有,service通常負責描述啓動時候的一些情況 常見參數如下: Type:定義啓動時的進程行爲。它有以下幾種值。 Type=simple:默認值,執行ExecStart指定的命令,啓動主進程 Type=forking:以 fork 方式從父進程創建子進程,創建後父進程會立即退出 Type=oneshot:一次性進程,Systemd 會等當前服務退出,再繼續往下執行 Type=dbus:當前服務通過D-Bus啓動 Type=notify:當前服務啓動完畢,會通知Systemd,再繼續往下執行 Type=idle:若有其他任務執行完畢,當前服務纔會運行 ExecStart:啓動當前服務的命令 ExecStartPre:啓動當前服務之前執行的命令 ExecStartPost:啓動當前服務之後執行的命令 ExecReload:重啓當前服務時執行的命令 ExecStop:停止當前服務時執行的命令 ExecStopPost:停止當其服務之後執行的命令 RestartSec:自動重啓當前服務間隔的秒數 Restart:定義何種情況 Systemd 會自動重啓當前服務,可能的值包括always(總是重啓)、on-success、on-failure、on-abnormal、on-abort、on-watchdog TimeoutSec:定義 Systemd 停止當前服務之前等待的秒數 Environment:指定環境變量 install部分: install一般負責描述如何啓動的問題,是否開機啓動等 常見參數如下: WantedBy:它的值是一個或多個 Target,當前 Unit 激活時(enable)符號鏈接會放入/etc/systemd/system目錄下面以 Target 名 + .wants後綴構成的子目錄中 RequiredBy:它的值是一個或多個 Target,當前 Unit 激活時,符號鏈接會放入/etc/systemd/system目錄下面以 Target 名 + .required後綴構成的子目錄中 Alias:當前 Unit 可用於啓動的別名 Also:當前 Unit 激活(enable)時,會被同時激活的其他 Unit # 此時可以再次看下之前的httpd的配置文件 # 以httpdd.service爲例 [root@localhost ~]# cat /usr/lib/systemd/system/httpd.service [Unit] Description=The Apache HTTP ServerAfter=network.target remote-fs.target nss-lookup.target Documentation=man:httpd(8) Documentation=man:apachectl(8) [Service]Type=notify EnvironmentFile=/etc/sysconfig/httpd ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND ExecReload=/usr/sbin/httpd $OPTIONS -k graceful ExecStop=/bin/kill -WINCH ${MAINPID} # We want systemd to give httpd some time to finish gracefully, but still want # it to kill httpd after TimeoutStopSec if something went wrong during the # graceful stop. Normally, Systemd sends SIGTERM signal right after the # ExecStop, which would kill httpd. We are sending useless SIGCONT here to give # httpd time to finish. KillSignal=SIGCONT PrivateTmp=true[Install] WantedBy=multi-user.target
target
target相當於unit組,通過組的形式管理unit服務,和傳統的sysv的init的runlevel很像
# Target 與 傳統 RunLevel 的對應關係如下。Traditional runlevel New target name Symbolically linked to...Runlevel 0 | runlevel0.target -> poweroff.targetRunlevel 1 | runlevel1.target -> rescue.targetRunlevel 2 | runlevel2.target -> multi-user.targetRunlevel 3 | runlevel3.target -> multi-user.targetRunlevel 4 | runlevel4.target -> multi-user.targetRunlevel 5 | runlevel5.target -> graphical.targetRunlevel 6 | runlevel6.target -> reboot.target 它與init進程的主要差別如下。 (1)默認的 RunLevel(在/etc/inittab文件設置)現在被默認的 Target 取代,位置是/etc/systemd/system/default.target,通常符號鏈接到graphical.target(圖形界面)或者multi-user.target(多用戶命令行)。 (2)啓動腳本的位置,以前是/etc/init.d目錄,符號鏈接到不同的 RunLevel 目錄 (比如/etc/rc3.d、/etc/rc5.d等),現在則存放在/lib/systemd/system和/etc/systemd/system目錄。(3)配置文件的位置,以前init進程的配置文件是/etc/inittab,各種服務的配置文件存放在/etc/sysconfig目錄。現在的配置文件主要存放在/lib/systemd目錄,在/etc/systemd目錄裏面的修改可以覆蓋原始設置。
journal日誌
systemctl可以用journal方式,方便地查看日誌
# 查看所有日誌(默認情況下 ,只保存本次啓動的日誌)$ sudo journalctl# 查看內核日誌(不顯示應用日誌)$ sudo journalctl -k# 查看系統本次啓動的日誌$ sudo journalctl -b$ sudo journalctl -b -0# 查看上一次啓動的日誌(需更改設置)$ sudo journalctl -b -1# 查看指定時間的日誌$ sudo journalctl --since="2012-10-30 18:17:16"$ sudo journalctl --since "20 min ago"$ sudo journalctl --since yesterday$ sudo journalctl --since "2015-01-10" --until "2015-01-11 03:00"$ sudo journalctl --since 09:00 --until "1 hour ago"# 顯示尾部的最新10行日誌$ sudo journalctl -n# 顯示尾部指定行數的日誌$ sudo journalctl -n 20# 實時滾動顯示最新日誌$ sudo journalctl -f# 查看指定服務的日誌$ sudo journalctl /usr/lib/systemd/systemd# 查看指定進程的日誌$ sudo journalctl _PID=1# 查看某個路徑的腳本的日誌$ sudo journalctl /usr/bin/bash# 查看指定用戶的日誌$ sudo journalctl _UID=33 --since today# 查看某個 Unit 的日誌$ sudo journalctl -u nginx.service$ sudo journalctl -u nginx.service --since today# 實時滾動顯示某個 Unit 的最新日誌$ sudo journalctl -u nginx.service -f# 合併顯示多個 Unit 的日誌$ journalctl -u nginx.service -u php-fpm.service --since today# 查看指定優先級(及其以上級別)的日誌,共有8級# 0: emerg# 1: alert# 2: crit# 3: err# 4: warning# 5: notice# 6: info# 7: debug$ sudo journalctl -p err -b# 日誌默認分頁輸出,--no-pager 改爲正常的標準輸出$ sudo journalctl --no-pager# 以 JSON 格式(單行)輸出$ sudo journalctl -b -u nginx.service -o json# 以 JSON 格式(多行)輸出,可讀性更好$ sudo journalctl -b -u nginx.serviceqq -o json-pretty# 顯示日誌佔據的硬盤空間$ sudo journalctl --disk-usage# 指定日誌文件佔據的最大空間$ sudo journalctl --vacuum-size=1G# 指定日誌文件保存多久$ sudo journalctl --vacuum-time=1years
服務開機啓動
# systemctl服務開機啓動其實就是符號鏈接了一個unit配置文件到/etc/systemd/system的*.wants文件夾內[root@localhost ~]# systemctl enable httpd.serviceln -s '/usr/lib/systemd/system/httpd.service' '/etc/systemd/system/multi-user.target.wants/httpd.service'
sysv 和 systemd
如何轉服務,前提你有或者都會寫兩種格式的(sysv && systemd 風格的) 參考價值的兩個鏈接