systemd是Linux下的一种init软件,由Lennart Poettering带头开发,其开发目标是提供更优秀的框架以表示系统服务间的依赖关系,并依此实现系统初始化时服务的并行启动,同时达到下降Shell的系统开销的效果,最终代替如今经常使用的System V与BSD风格init程序。传统sysvinit使用inittab来决定运行哪些shell脚本,大量使用shell脚本被认为是效率低下没法并行的缘由。systemd使用了Linux专属技术,再也不顾及POSIX兼容.php
设计理念前端
与多数发行版使用的System V风格init相比,systemd采用了如下新技术:linux
采用Socket激活式与D-Bus激活式服务,以提升相互依赖的各服务的并行运行性能;shell
用cgroups代替PID来追踪进程,以此即便是两次fork以后生成的守护进程也不会脱离systemd的控制。服务器
从设计构思上说,因为systemd使用了cgroup与fanotify等组件以实现其特性,因此只适用于Linux。有鉴于此,考虑到kFreeBSD分支的软件源没法归入systemd,为与其余分支保持一致,Debian开发者尽力避免归入systemd。网络
应用范围session
systemd已归入众多Linux发行版的软件源中,如下简表:框架
默认init程序为systemd的发行版less
Fedora 15及后续版本ssh
Mageia 2[10]
Mandriva 2011[11]
openSUSE 12.1及后续版本[12]
Arch Linux在2012年10月13日将systemd-sysvcompat归入base软件组,自此Arch Linux默认安装完即以systemd为init程序[13],同时也提供了与Arch自带启动脚本兼容用的systemd启动脚本包以方便用户,使用户能“开箱即用”[14]
Chakra GNU/Linux,在2012.10的光盘镜像文件发布后默认使用systemd。[15]
可使用systemd的发行版
Debian GNU/Linux,于“testing”分支源中提供[16],并在2014年的技术委员会的init系统投票中决定在Debian 8 “Jessie”中将以Linux为核心的版本转换到systemd[17] 。
Gentoo,同Openrc一块儿被Gentoo官方支持[18][19][20]
除此之外,systemd已由Lennart Poettering提请归入GNOME 3.2的外部依赖关系列表[21],而这意味着全部使用GNOME的发行版都应该使用systemd,最低限度来讲也必须将其做为配置选项之一。
一些其余的发行版也把它包含进来,做为 upstart 和 sysvinit 的替代品。
systemd 特色
systemd 开启和监督整个系统是基于 unit 的概念。unit 是由一个与配置文件对应的名字和类型组成的(例如:avahi.service unit 有一个具备相同名字的配置文件,是守护进程 Avahi 的一个封装单元)。unit 有如下几种类型:
service :守护进程的启动、中止、重启和重载是此类 unit 中最为明显的几个类型。
socket :此类 unit 封装系统和互联网中的一个 socket 。当下,systemd 支持流式、数据报和连续包的 AF_INET、AF_INET六、AF_UNIX socket 。也支持传统的 FIFOs 传输模式。每个 socket unit 都有一个相应的服务 unit 。相应的服务在第一个“链接”进入 socket 或 FIFO 时就会启动(例如:nscd.socket 在有新链接后便启动 nscd.service)。
device :此类 unit 封装一个存在于 Linux 设备树中的设备。每个使用 udev 规则标记的设备都将会在 systemd 中做为一个设备 unit 出现。udev 的属性设置能够做为配置设备 unit 依赖关系的配置源。
mount :此类 unit 封装系统结构层次中的一个挂载点。
automount :此类 unit 封装系统结构层次中的一个自挂载点。每个自挂载 unit 对应一个已挂载的挂载 unit (须要在自挂载目录能够存取的状况下尽早挂载)。
target :此类 unit 为其余 unit 进行逻辑分组。它们自己实际上并不作什么,只是引用其余 unit 而已。这样即可以对 unit 作一个统一的控制。(例如:multi-user.target 至关于在传统使用 SysV 的系统中运行级别5);bluetooth.target 只有在蓝牙适配器可用的状况下才调用与蓝牙相关的服务,如:bluetooth 守护进程、obex 守护进程等)
snapshot :与 target unit 类似,快照自己不作什么,惟一的目的就是引用其余 unit 。
systemd 的工具
systemd 包含了本身的配置和诊断工具,在使用它处理系统启动问题时用到的技巧不一样于 sysvinit。因为它与 upstart 和 sysvinit 的兼容特性,咱们在使用这两个初始化工具的发行版里面熟悉的命令与技巧也适用于 systemd。
一 systemctl 命令
检视和控制systemd的主要命令是systemctl。该命令可用于查看系统状态和管理系统及服务。详见man 1 systemctl。该工具在改变配置文件或从新启动后台程序时须要 root 权限,但即便是非 root 用户也能下达一些诊断的命令。若是你在启动该命令时不加任何参数,你会看到一个系统启动时执行任务的“单位(unit)”列表,包括挂载及检测磁盘、启动后台服务及配置硬件。
1)输出激活的单元:
$ systemctl
如下命令等效:
$ systemctl list-units
输出运行失败的单元:
$ systemctl --failed
全部可用的单元文件存放在 /usr/lib/systemd/system/ 和 /etc/systemd/system/ 目录(后者优先级更高)。查看全部已安装服务:
$ systemctl list-unit-files
2)使用单元
一个单元配置文件能够描述以下内容之一:系统服务(.service)、挂载点(.mount)、sockets(.sockets 、系统设备、交换分区/文件、启动目标(target)、文件系统路径、由 systemd 管理的计时器。详情参阅 man 5 systemd.unit.
使用 systemctl 控制单元时,一般须要使用单元文件的全名,包括扩展名(例如 sshd.service)。可是有些单元能够在systemctl中使用简写方式。
当即激活单元:
# systemctl start <单元>
当即中止单元:
# systemctl stop <单元>
重启单元:
# systemctl restart <单元>
命令单元从新读取配置:
# systemctl reload <单元>
输出单元运行状态:
$ systemctl status <单元>
检查单元是否配置为自动启动:
$ systemctl is-enabled <单元>
开机自动激活单元:
# systemctl enable <单元>
注意: 若是服务没有Install段落,通常意味着应该经过其它服务自动调用它们。若是真的须要手动安装,能够直接链接服务,以下(将foo替换为真实的服务名):
# ln -s /usr/lib/systemd/system/foo.service /etc/systemd/system/graphical.target.wants/
取消开机自动激活单元:
# systemctl disable <单元>
显示单元的手册页(必须由单元文件提供):
# systemctl help <单元>
从新载入 systemd,扫描新的或有变更的单元:
# systemctl daemon-reload
3)服务
服务(service)单位是最重要的一类单位之一,由于它们管理着后台服务,而在使用 sysvinit 的发行版里面则通常使用初始化脚原本启动这些服务。挂载(mount)与自动挂载(automount)单位用来挂载文件系统。
套接字(socket)单位用来建立套接字,并在访问套接字后,当即利用依赖关系间接地启动另外一单位。你可使用参数让 systemctl 只列出某个类型的单位,如全部的服务单位:systemctl --type=service
systemd 自动将其输出结果递交给 less 显示;你不只可使用箭头键来上下滚动,也能够向右滚动,由于有时更多的信息会偶尔“藏”到那里。
列表中的第一栏是单位的名字,
第二栏则表示该单位的定义是否已由 systemd 正确加载。
第三栏则告诉咱们该单位是否正在运行。若是你使用了 -a 参数,那么该程序将仅显示非正在运行的单位,即已安装但并未在启动时使用的单位,同时也包含引导系统未能正常加载的单位文件(缘由极可能为该单位文件出现错误)。
第四栏则给出了当前状态:“exited”表示该进程已经无任何错误地完成,这种状况适用于一诸如进程在启动后并不在后台继续运行的状况,例如,在系统启动时因为考虑到兼容性因素执行在 sysvinit 里面经常使用的 /etc/rc.d/rc.local 文件的服务单位。“Running”表示正在后台运行的服务,如 cron、dbus、sshd 和 udev。
第五栏是对该单位的描述。标有“LSB”或“SYSV”的单位已由 systemd 自动建立以管理传统启动脚本。
不能启动或启动后崩溃的服务在第四栏中用红色标为“failed”(若是终端能够显示彩色)。你能够以下命令来察看该服务是什么时候崩溃的以及在服务程序结束后提供了什么错误代码:
systemctl status ntpd.service
对于一个新安装的 Linux Deepin 12.06,systemctl 会列出约50个服务型单位,包含文本终端的登录进程(agetty)。由于 systemd 不一样于 sysvinit, 它会像管理普通的后台服务同样以服务单位的形式对这些进程进行管理。
4)单位文件与目标(target)
一单位的处理
建立单位用的系统配置文件位于 /lib/systemd/system/,但 /etc/systemd/system 目录下的同名文件会优先于前者。
单位文件的定义一般比传统的 sysvinit 脚本要短得多。例如,用于经过 NTP 来同步网络时间的服务只有短短几行:
[Unit]
Description=Network Time Service
[Service]
ExecStart=/usr/bin/ntpd -n -u ntp:ntp -g
[Install]
WantedBy=multi-user.target
1) 全部的单位文件都包含由[Unit]开头的一节,其中包含通常设置与简
2) [Service]一节含有针对该服务要进行的任务的指定设置——对于 NTP 来讲,仅须要启动该服务的命令行。若是须要用一个指定的命令来终止程序,你能够用 ExecStop= 来进行设置。这一步对于 NTP 守护进程是不须要的,由于根据 Unix 传统,它能够用一个简单的“SIGTERM”信号来结束。若是没有指定其余命令,这个命令会告诉 systemd 结束任务。
3) [Install]一节包含了 systemd 在(反)安装时要解释的说明;这里的 NTP 一例中,其内容意为在“多用户”目标激活时应当同步时间。
二目标
“目标”单位的概念与 sysvinit 的运行级别类似;实际上,为考虑兼容性,systemd 甚至可以识别与目标对应的运行级别名称。因此,你能够在引导装载程序中的 kernel 一行中加入 single 这个参数;systemd 就会激活 rescue.target,提供一个至关于单用户模式的最小化界面。
在 systemd 中,多用户模式(即不使用图形化登录界面就彻底启动系统的模式)由 multi-user.target 表示,能够经过下面这个连接来将其设为默认启动目标:
ln -sf /lib/systemd/system/multi-user.target /etc/systemd/system/default.target
若是此后你确实须要默认启动图形化登录界面,可用一样的方式来将 graphical.target 设为默认目标。这等同于传统初始化工具的运行级别 5。你也能够在引导装载程序中为 kernel 指定想要启动的目标单位:
systemd.unit=multi-user.target
若是想要在操做过程当中激活一个不一样的目标单位,你可使用 systemctl 的isolate 命令(须要 root 权限):
systemctl isolate rescue.target
切换为 rescue 目标对于管理任务来讲颇有用,systemd 这时会中止全部的用户登录与后台服务,只有系统服务在运行,如监视逻辑卷的服务(lvm2-monitor)。有时,甚至这些服务也须要中止并从新安装,这时你可使用 emergency.target 来进入紧急模式(emergency mode),这时只有命令提示符的进程以及内核线程在运行。
三 systemctl命令取代了rc.d命令
开机模块加载
/etc/modules-load.d/.conf,至关于原rc.conf中的MODULES变量
# Load virtio-net.ko at boot virtio-net
virtio-net
模块黑名单仍在/etc/modprobe.d/下,如blacklist.conf:
blacklist badmod.ko
Locale
/etc/locale.conf,至关于原rc.conf中的LOCALE
LANG=en_US.UTF-8 LC_COLLATE=C
LC_COLLATE=C
日志服务
systemd自带日志服务,参考systemd Journal
sudo journalctl
能够删除syslog-ng了
主机名
/etc/hostname,至关于原来rc.conf中的HOSTNAME变量
myhostname
网络
sudo systemctl enable NetworkManager.service
不象rc.conf有专门的配置简单网络的地方,仍是用NetworkManager、wicd之类的工具吧
若是你坚持使用简单静态配置,能够参考[SOLVED] static ethernet setup under systemd?
运行级别
四systemd用target替代了runlevel的概念,提供了更大的灵活性,如你能够继承一个已有的target,并添加其它服务,来建立本身的target
sudo systemctl list-units --type=target #查询当前target
sudo systemctl isolate graphical.target #改变当前target,重启无效
sudo systemctl enable multi-user.target #改变启动时默认target
sudo systemctl enable kdm.service #graphical是默认target,指定使用的display manager
优化
systemd有本身的”e4rat”
sudo systemctl enable systemd-readahead-collect.service sudo systemctl enable systemd-readahead-replay.service
/etc/fstab,修改/home分区options,检查/home分区时并行启动其它服务
defaults,noauto,x-systemd.automount
其余
sudo systemctl reboot #systemctl还有系统关机、重启、挂起等功能 sudo systemctl suspend
五本身编写 .service 文件
systemd 的单元文件是受 XDG Desktop Entry .desktop 文件启发而产生,而最初起源是 Windows 下的 .ini 文件。
示例参见:Systemd/Services。
处理依赖关系
使用systemd时,可经过正确编写单元配置文件来解决其依赖关系。典型的状况是,单元A要求单元B在A启动以前运行。在此状况下,向单元A配置文件中的 [Unit] 段添加 Requires=B 和 After=B 便可。若此依赖关系是可选的,可添加 Wants=B 和 After=B。请注意 Wants= 和 Requires= 并不意味着 After=,即若是 After= 选项没有制定,这两个单元将被并行启动。
依赖关系一般被用在服务(service)而不是目标(target)上。例如, network.target 通常会被某个配置网络接口的服务引入,因此,将自定义的单元排在该服务以后便可,由于 network.target 已经启动。
启动方式
编写自定义的 service 文件时,能够选择几种不一样的服务启动方式。启动方式可经过配置文件 [Service] 段中的 Type= 参数进行设置。具体的参数说明请参阅 man systemd.service 。
修改现存单元文件
要更改由软件包提供的单元文件,先建立名为 /etc/systemd/system/<单元名>.d/ 的目录(如 /etc/systemd/system/httpd.service.d/),而后放入 *.conf 文件,其中能够添加或重置参数。这里设置的参数优先级高于原来的单元文件。例如,若是想添加一个额外的依赖,建立这么一个文件便可:
/etc/systemd/system/<unit>.d/customdependency.conf
[Unit]
Requires=<新依赖>
After=<新依赖>
而后运行如下命令使更改生效:
# systemctl daemon-reload
# systemctl restart <单元>
此外,把旧的单元文件从 /usr/lib/systemd/system/ 复制到 /etc/systemd/system/,而后进行修改,也能够达到一样效果。在 /etc/systemd/system/ 目录中的单元文件的优先级老是高于 /usr/lib/systemd/system/ 目录中的同名单元文件。注意,当 /usr/lib/ 中的单元文件因软件包升级变动时,/etc/ 中自定义的单元文件不会同步更新。此外,你还得执行 systemctl reenable <unit>,手动从新启用该单元。所以,建议使用前面一种利用 *.conf 的方法。
小贴士: 能够用 systemd-delta 命令来查看哪些单元文件被覆盖、哪些被修改。
eg:slock
Locks the system with the help of slock. Very handy when closing the laptop lid for example.
/etc/systemd/system/screenlock.service
[Unit]
Description=Lock X session using slock
Before=sleep.target
[Service]
User=<username>
Environment=DISPLAY=:0
ExecStart=/usr/bin/slock
[Install]
WantedBy=sleep.target
如何定制或增长一个自定义 unit 文件?
unit 文件在 /etc/systemd/system 下的优先级要高于 /lib/systemd/system 下的。按照我的的需求从后者移动到前者并进行自定义修改。
若是一行以 .include 开始,后接文件名,那么该文件在此时被解析为特殊文件。请确保包含的文件在指令前有适当的章节头信息。
若是可能的话,你应当使用 .include 声明 unit 文件而不是在 /lib/systemd/system 下复制整个 unit 文件到 /etc/systemd/system 目录下。这样你才能够在未来升级软件包时正确地升级未改变的指令。
在使用 .include 和指令时须要当心,由于它能够有屡次定义(像 EnvironmentFile= 同样)。因为咱们只能添加新指令而不能删除已定义的指令,此时,咱们就必须从 /lib/systemd/system复制整个文件到 /etc/systemd/system 中去。
假设咱们有一个 lighttpd 服务,咱们如今想下降它的 niceness 值。咱们须要作的就只是添加 Nice=-5 到 lighttpd.service 文件中。咱们能够经过复制整个文件/lib/systemd/system/lighttpd.service 到 /etc/systemd/system/lighttpd.service 或者在 /etc/systemd/system/lighttpd.service 中建立以下文件作到
.include /lib/systemd/system/lighttpd.service
[Service]
Nice=-5
不要忘记在编辑一个 unit 文件后使用 systemdctl daemon-reload 重载 systemd 守护进程。
检测到 Linux 所使用的虚拟化平台类型。
要检测 Linux 底层的虚拟化类型首选的就是 dmidecode 命令,它最初设计来显示系统 BIOS 和硬件组件的相关信息。使用以下命令即可以检测相关虚拟化信息:
sudo dmidecode -s system-manufacturer
系统极客网站运行在 Microsoft Azure 平台上,因此检测出来是微软的 Hyper-V。若是你的系统运行在物理服务器上,输入的将是硬件制造商的实际名称(如 Dell Inc.)。若是你的 Linux 是运行在虚拟化平台中,则会显示所使用的虚拟化技术相关名称,如 「Microsoft Corporation」「QEMU」「Xen」「VirtualBox」「VMware, Inc」等等。
注意:该方法不适用于基于容器的虚拟化技术。
对于使用 systemd 的 Linux 系统,可使用 systemd-detect-virt 命令来进行检测,该命令目前能够同时检测到基于 hypervisor 的虚拟化技术(例如 KVM、QEMU、VMware、Xen、Oracle VM、VirtualBox、UML)和基于容器的虚拟化技术(例如 LXC、Docker、OpenVZ)。
systemd-detect-virt
注意:在物理服务器上使用该命令会输出「none」。
咱们介绍的最后一种检测 Linux 所使用虚拟化类型的方法是 virt-what 命令,virt-what 其实是一个 Shell 脚本。它经过各类启发式方法来识别虚拟化环境类型,能够检测出 QEMU/KVM、VMware、Hyper-V、VirtualBox、OpenVZ/Virtuozzo、Xen、LXC、IBM PowerVM 以及 Parallels 等平台类型。
在使用以前,你们须要先经过 apt-get 或 yum 安装 virt-what,再执行以下命令进行检测:
sudo virt-what