1.1 简介 systemd是linux系统的系统和服务管理器,它兼容之前的SysV init脚本,并提供一系列的其他特色:启动时系统服务的并行启动、按需启动服务、支持系统状态快照、基于服务依赖的控制逻辑。 systemd引入systemd units概念,这些units是通过一些配置文件代表的。以下列出所有的systemd units类型: Unit Type File Extension Description ------------------------------------------------------------------ Service unit .service 系统服务 Target unit .target 一组systemd units Automount unit .automount 文件系统的自动挂载点 ------------------------------------------------------------------- Device unit .device 由内核识别的设备文件 Mount unit .mount 文件系统挂载点 Path unit .path 文件系统中的文件或者目录 ------------------------------------------------------------------- Scope unit .scope 外部创建的进程 Slice unit .slice 一组管理系统进程的分级组织的units Snapshot unit .snapshot 存储的系统管理器状态 Socket unit .socket 进程间通信套接字 ------------------------------------------------------------------- Swap unit .swap 交换设备或者文件 Timer unit .timer systemd定时器 Systemd unit存储位置: 文件夹 描述 /usr/lib/systemd/system/ 利用RPM包安装的软件产生的Systemd unit /run/systemd/system/ 运行时产生的Systemd units,该文件夹优先于directory with installed service units /etc/systemd/system/ 系统管理员创造的systemd units,该文件夹优先于运行时units 1.1.1 主要特点 也就是以上列出的系统支持的unit类型对应的启动特点。 1.1.2 兼容性 systemd对于runlevels的支持是比较局限的。它仅提供一些target units文件,这些文件可以对应runlevels中的运行级别。但是,并不是所有的运行级别都能一一对应,因此尽管可以用runlevel命令,但并不建议这么做。 systemctl工具并不支持定制命令,这在SysV int启动脚本中是可以的。systemctl工具并不能与非systemd启动的服务进行交流,当用systemd启动一个系统服务时,它会存储该服务主要进程的ID并跟踪,systemctl利用这个PID来管理这个服务,而当用户在命令行直接启动一个服务时,systemctl并不能判断该服务的状态也不能停止该服务。 系统服务并不能从标准输入读取信息,当systemd启动一个服务,它会把该服务的标准输入连接到/dev/null来防止与用户直接交流。 系统服务并不能从用户以及他们的对话中继承任何环境(包括HOME、PATH等环境变量),每一个服务都运行在新的执行环境中。 所有针对服务的操作都遵守默认5min的超时,以防服务发生问题导致系统死机。 1.2 管理系统服务
早期版本的RHEL采用SysV init或Upstart,利用/etc/rc.d/init.d/文件夹中的启动脚本,这些启动脚本通常是bash脚本,并且允许管理员控制服务的状态。在systemd控制的系统中,这些启动脚本被service units替代。 以.service后缀的系统units与启动脚本完成相似的功能,为了view、start、stop、restart、enable、disable一项系统服务,可以用systemctl命令。当然之前的service和chkconfig命令也是可用的,但是不建议使用。 为了清晰明了,该部分采用全名(带有.service后缀): systemctl stop bluetooth.service 当处理系统服务时,允许省略文件后缀:systemctl工具当面对一个没有后缀的unit时,会默认其为service unit,因此上一个命令与下面的等价 systemctl stop bluetooth systemctl start name.service 启动服务 systemctl stop name.service 关闭服务 systemctl restart name.service 重启服务 systemctl try-restart name.service 当系统运行状态则重启该服务 systemctl reload name.service 重新加载配置 systemctl status name.service 判断服务状态 systemctl is-active name.servie 判断服务是否在运行 systemctl list-units --type service --all 列出所有服务的状态 systemctl enable name.service 开机自启一项服务 systemctl disable name.service 关闭开机自启一项服务 systemctl is-enabled name.service 判断该服务是否enabled systemctl list-unit-files --type service 列出所有的服务,并判断其是否enabled systemctl list-dependencies --after 列出特定unit启动之前需要启动的服务 systemctl list-dependencies --before 列出特定unit启动之后才启动的服务 1.2.1 列出服务 为了列出目前所有的service units,用以下命令: systemctl list-units --type service 默认情况下,systemctl list-units命令示出活动的units,如果想要列出任何状态的units,用以下命令: systemctl list-units --type service --all 列出所有安装的服务以及它们的enable状态 systemctl list-unit-files --type service 1.2.2 显示服务状态 利用systemctl status name.service 会列出如下字段信息: Loaded 关于该系统服务unit是否已加载、unit文件的绝对路径、该unit是否时enabled状态 Active 显示该服务是否在运行,并在其后有一个时间 Main PID 相应系统服务的名字以及其PID Status 相应系统服务的额外信息 Process 相应进程的额外信息 CGroup 相关控制组(cgroups)的额外信息 1.2.3 启动一项服务 systemctl start name.service | | 1.2.6 自启一项服务 为了是Apache HTTP 服务器在开机时自启,可以用root用户运行如下命令 systemctl enable httpd.service ln -s '/usr/lib/systemd/system/httpd.service' '/etc/systemd/system/multi-user.target.wants/httpd.service' 1.2.7 取消服务开机自启 systemctl disable name.service 该命令会把/usr/lib/systemd/system/name.service在/etc/systemd/system/文件夹以及其子文件夹中的链接删除。此外,你还可以通过mask来掩蔽一项服务,从而使其不能自启或由其它服务启动: systemctl mask name.service 该命令会把/etc/systemd/system/name.service这一文件替换为指向/dev/null的链接,若想取消: systemctl unmask name.service 1.3 Systemd targets systemd targets通过target units代表,其具有.target后缀,target存在的唯一目的就是通过一系列依赖性集合其它的systemd units。例如,graphical.target unit就是用来开启图形会话,启动诸如gdm.service,accounts-daemon.service的服务,且激活multi-user.target unit runlevel0.target,poweroff.target 关机 runlevel1.target,rescue.target 拯救模式,单用户模式 runlevel2.target,multi-user.target 字符界面多用户 runlevel3.target,multi-user.target 字符界面多用户 runlevel4.target,multi-user.target 字符界面多用户 runlevel5.target,graphical.target 图形界面多用户 runlevel6.target,reboot.target 重启 1.3.1 查看默认target systemctl get-default 该命令查看/etc/systemd/system/default.target这一链接指向。 1.3.2 查看目前target 以下命令查看当前系统加载的target units: systemctl list-units --type target 1.3.3 改变默认target systemctl set-default name.target 1.3.4 改变目前target systemctl isolate name.target 这一命令会启动name.target需要的所有服务,并终止所有不需要的服务。 1.3.5 改变到拯救模式 systemctl rescue 这一命令与systemctl isolate rescue.target基本相同,但是它会向目前登陆用户发送信息,要想阻止信息发送,可以用如下命令: systemctl --no-wall rescue 1.3.6 改变到救急模式 systemctl emergency 与拯救模式类似,也会在进入前向登陆用户发送信息,也可以通过以下方式阻止信息发送: systemctl --no-wall emergency 1.4 关机、休眠、睡眠 systemctl halt 关机 systemctl poweroff 关机断电 systemctl reboot 重启 systemctl suspend 挂起 systemctl hibernate 休眠 systemctl hybrid-sleep 休眠并挂起 shutdown命令: 为了在一个特定的时间关机并对机器断电,可以用如下格式的命令: shutdown --poweroff hh:mm (hh:mm为24小时制时间格式) 当然也可以用: shutdown --poweroff +m 在m分钟后关机 如果想要取消关机,可以用: shutdown -c 1.5 在远程设备上操控systemd 除了可以在本机对systemd系统进行控制外,其还允许你通过SSH协议连接到远程电脑上进行操控。但是远程主机必须得运行sshd服务,你可以通过如下命令连接到该主机上: systemctl --host user_name@host_name command 除了前面部分需要加上--host user_name@host_name外,command是相同的 1.6 创建、修改Systemd unit文件 Unit file具有如下形式: unit_name.type_extension 文件结构: [Unit] 描述与unit类型无关的信息、对其它units的依赖 [unit type] 关于该unit类型的指引 [Install] 包含systemctl安装命令(enable/disable) [Unit] Section: Description 针对该unit的描述,该段文字会在systemctl status命令中显示 Documentation 提供关于该unit的帮助文档URIs After 定义unit启动顺序,该unit会在该字段定义的unit启动后才启动 Requires 配置依赖的服务,这里列出的unit会同时启动 Wants 要求比Requires要若 Conflicts 冲突的units [Service] Section: Type simple 默认值; forking 该进程启动后会产生一个子程序并成为服务的主进程,父进程随之退出 oneshot 与simple相似,但是该进程会在后面的unit启动前关闭 dbus notify 随后的units仅会在sd_notify()发送通知信息后启动 idle ExecStart 指定unit启动后执行的命令或脚本 ExecStop 指定unit结束后执行的命令或脚本 ExecReload 指定unit重启后执行的命令或脚本 Restart 当该项enabled,则当进程退出后会重启,当然通过systemctl命令停止并不会重启 RemainAfterExit 如果为True,当它退出后仍会认为是活动的;默认值为false,该字段对Type=oneshot很有用 [Install] Section Alias 提供该unit的别名,不同别名通过空格间隔 RequiredBy 依赖该unit的units WantedBy 弱依赖units Also 指定会随同该unit安装或卸载的units 1.6.2 创建自定义unit文件 (1)准备一个可执行的自定义服务,可以是一个脚本也可以是一个可执行程序。如果必须的话,准备一个包含该服务PID的PID文件。也可能会需要environment文件来储存该服务用到的shell变量。并确认该脚本是可执行的(chmod a+x)并且是非交互的。 (2)在/etc/systemd/system/文件夹下创建一个unit文件,并确认文件权限是正确的: touch /etc/systemd/system/name.service chmod 664 /etc/systemd/system/name.service (3) 打开该name.service文件并加入配置选项。下面是一个网络相关的服务的例子: [Unit] Description=service_description After=network.target [Service] ExecStart=path_to_executable Type=forking PIDFile=path_to_pidfile [Install] WantedBy=default.target (4) 通知systemd有一个新的name.service文件存在,运行如下命令: systemctl daemon-reload systemctl start name.service 1.6.3 把SysV Init脚本转变为unit文件 需要作复杂的变换:找到服务描述、服务依赖、默认target、服务所用到的文件,这些过程比较复杂,需要对启动脚本中的目的明确才行。 1.6.4 修改现有的unit文件 安装的服务的默认unit文件一般储存在/usr/lib/systemd/system/文件夹下,系统管理员不应该直接修改这些文件;任何自定义都要在/etc/systemd/system/文件夹下进行,根据所需要修改的程序,选择以下方法中的一种即可: > 在/etc/systemd/system/unit.d/下建立一个文件夹,这也是对大多数情况建议使用的方法。这种方法允许对默认配置增加额外的功能,而且能够保持原来的unit文件。 > 在/etc/systemd/system下拷贝/usr/lib/systemd/system中初始的unit文件。这一拷贝将会覆盖初始配置,因此软件包更新的配置并不能自动更新进来。这种方法经常用在对配置需要做永久的改动,而不论软件包是否更新。 如果想要复原默认配置,那么只需要删除以上创建的配置文件,而后重启系统或者运行如下命令即可: systemctl daemon-reload daemon-reload选项会重新加载所有的unit文件并重新生成依赖树,你也可以利用如下方法达到同样效果: init q 同样,如果修改的unit文件属于一个正在运行的服务,那么服务必须重启才能接受新的设置: systemctl restart name.service · 拓展默认unit配置: 为了对默认的unit文件增加一些额外的选项,首先需要在/etc/systemd/system/下创建配置文件夹: mkdir /etc/systemd/system/name.service.d 在上面的目录中新建配置文件,记住文件后缀必须为.conf touch /etc/systemd/system/name.service.d/config_name.conf 然后在该文件中在相应的字段中加入配置即可。为了是修改生效,需要执行: systemctl daemon-reload systemctl restart name.service · 重写默认unit配置: 为了要对软件包的配置作持久的更改,需要把unit文件拷贝到/etc/systemd/system/目录下: cp /usr/lib/systemd/system/name.service /etc/systemd/system/name.service 然后对拷贝的文件做出需要的修改。之后运行: systemctl daemon-reload systemctl restart name.service |
|