参考了
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 getty@tty1.service 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 风格的) 参考价值的两个链接