Linux的三种自启动系统:
- System V 是一个比较老的自启动系统:
- Debian 6 或者更早版本
- Ubuntu 9.04 或者更早版本
- CentOS 5 或者更早版本
- Upstart:
- Ubuntu 9.10 到 Ubuntu 14.10 的版本
- CentOS 6
- systemd 是比较新的自启动系统:
- Debian 7 和 Debian 8
- Ubuntu 15.04 或者更新的版本
- CentOS 7
System V
原理介绍
- 首先系统执行 /sbin/init
- init进程会先读取 /etc/inittab
- 文件中有一项都决定了系统进入哪个runlevel
- 接下来在文件中查看需要启动哪些脚本
使用
1.想要使用System V 需要在 /etc/init.d
2.使用update-rc.d 命令配置刚写的脚本(例如脚本名称为custom)[1]
sudo update-rc.d custom enable
之后重启系统将会自动执行自定义的脚本
补充:如果为CentOS系统建议使用chkconfig(未验证)[2]
chkconfig custom on
以上的使配置的方式[1][2]都是为custom脚本在对应的 /etc/rc?.d 目录下创建S/K软链接,?代表runlevel,在linux中是运行级别的意思
- Level 0 :系统关闭
- Level 1 :单用户
- Level 2,3,4 : 多用户模式,文本模式,开启网络
- Level 5 :多用户模式,开启网络,图形模式
- Level 6 :系统重启
软链接类似入下图:
其中K(kill) 表示结束进程,S(start)表示开始进程,中间的数字表示启动时的顺序
3.配置进程被异常中断后的操作(例如重启进程)
编辑文件/etc/inittab,能看见如下类似的配置
ms:2345:respawn:/bin/sh /usr/bin/mysqld_safe
- ms代表进程的id
- 2345代表支持的runlevel
- respawn代表重启进程
- /bin/sh /usr/bin/mysqld_safe 代表执行的命令
配置完成后,比我们手动kill掉mysqld_safe的进程,模拟异常中断,等待几分钟后程序会自动恢复启动
Upstart
原理介绍
- Upstart使用配置文件控制服务
- 配置文件目录为 /etc/init ,配置文件是由多个部分组成,每个部分叫做stanzas(节),每一节描述了服务不同方面的行为
- jobs(工作) 是Upstart中的进程,分为任务工作(带有目的)和服务工作(在后台运行)
- events(事件) 用于触发一个任务的行为或另一个事件
- emitting events(发射事件) 由进程广播的信号
使用
配置文件合法性:
- 不能是空文件
- 不能有语法错误
- 必须有至少一个stanzas(节)
例子:
写一段信息和当前时间到日志文件
- 在 /etc/init 目录中创建一个名字为 testjob.conf 的配置文件
- 在文件中写入
description "Upstart的测试job文件"
author "作者的名字"
start on runlevel [2345]
exec echo Test job ran at `date` >> /var/log/testjob.log
- description 代表任务的描述
- author 是任务的作者名字
- start on runlevel 代表执行的系统阶段
- exec 代表执行一段代码
- 保存文件
- 执行命令 init-checkconf /etc/init/testjob.conf 检查语法,如果没有错误会显示
File /etc/init/testjob.conf: syntax ok
- 基础的服务控制命令
sudo service <servicename> <control>
<servicename>代表服务的名称,<control> 代表操作 restart,start,stop,status --分别为重启,启动,停止,状态
- 启动测试任务 sudo service testjob start
- 检查日志文件 /var/log/testjob.log 会有类似如下内容
Test job ran at 2020年 06月 29日 星期一 14:49:32 CST
特殊说明:
在个人目录下 ~/.init/ 的配置文件代表session级别的任务
服务的例子:
安装nodejs,并在系统启动时启动自定义的web服务
- 安装nodejs,sudo apt-get install nodejs
- 在 /etc/init/ 下创建文件 nodetest.conf
- 编辑如下内容
description "Test node.js server"
author "Your Name"
start on filesystem or runlevel [2345]
stop on shutdown
script
export HOME="/srv"
echo $$ > /var/run/nodetest.pid
exec /usr/bin/nodejs /srv/nodetest.js
end script
pre-start script
echo "[`date`] Node Test Starting" >> /var/log/nodetest.log
end script
pre-stop script
rm /var/run/nodetest.pid
echo "[`date`] Node Test Stopping" >> /var/log/nodetest.log
end script
- script 部分代表要执行的一段命令集
- pre-start script 代表启动前执行的命令
- pre-stop script 代表停止前执行的命令
- 编辑 /srv/nodetest.js文件,用于测试
var http = require("http");
http.createServer(function(request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hello World");
response.end();
}).listen(8888);
- 通过 init-checkconf /etc/init/nodetest.conf 检查语法
- 执行 sudo service nodetest start
- 测试 localhost:8888 返回 Hello World 页面,证明启动成功
Systemd
原理介绍
- 服务管理,一个初始化系统的基本功能是在linux内核启动后初始化各个组件,在systemd中,units代表大部分的行为目标用于告诉systemd如何管理服务。
- 服务管理命令systemctl <commands> <application.service> 可以省略 .service 后缀
- systemctl reload application.service 命令使服务重新加载配置,如果不确定服务是否有reload功能,可以使用 reload-or-restart 代替,如果不支持reload功能会执行restart命令
- 使一个服务在系统启动时启动,执行命令systemctl enable application.service。这个命令将会创建一个符号链接 由系统目录下(/lib/systemd/system --> /etc/systemd/system/some_target.target.wants)。systemctl disable application.service 命令将会取消服务跟随系统启动,并删除符合链接
- systemctl status application.service 查看服务的详细状态
- systemctl is-active application.service 查看服务当前是否激活
- systemctl is-enabled application.service 查看服务当前是否被启用(跟随系统启动)
- systemctl is-failed application.service 查看服务启动时是否有错误
- 系统状态概览,执行命令systemctl list-units 显示系统当前的服务,类似如下:
UNIT LOAD ACTIVE SUB DESCRIPTION
atd.service loaded active running ATD daemon
avahi-daemon.service loaded active running Avahi mDNS/DNS-SD Stack
dbus.service loaded active running D-Bus System Message Bus
dcron.service loaded active running Periodic Command Scheduler
UNIT 服务单位的名称,LOAD systemd是否已经加载配置, ACTIVE 服务启动的状态 ,SUB 一个较低级别的状态,指示有关该设备更多详细信息,DESCRIPTION 该服务的简单描述
- 列出所有的单元文件 systemctl list-unit-files
UNIT FILE STATE
proc-sys-fs-binfmt_misc.automount static
dev-hugepages.mount static
dev-mqueue.mount static
proc-fs-nfsd.mount static
proc-sys-fs-binfmt_misc.mount static
sys-fs-fuse-connections.mount static
sys-kernel-config.mount static
sys-kernel-debug.mount static
tmp.mount static
var-lib-nfs-rpc_pipefs.mount static
org.cups.cupsd.path enabled
state 会有 enable disable static masked 几种状态,在这里 static 表示单元文件不包含install 部分(用于service enable),因此 这些static单元不能enabled,通常这些单元表示一次性行为或者用于其他单元的依赖,不能单独运行。
- 单元文件管理
- 使用 systemctl cat xxx.service 查看xxx服务的单元文件
- systemctl list-dependencies sshd.service 将会显示sshd服务的依赖
sshd.service
├─system.slice
└─basic.target
├─microcode.service
├─rhel-autorelabel-mark.service
├─rhel-autorelabel.service
├─rhel-configure.service
├─rhel-dmesg.service
├─rhel-loadmodules.service
├─paths.target
├─slices.target
- systemctl show sshd.service 将会显示sshd服务的属性(key=value格式)
Id=sshd.service
Names=sshd.service
Requires=basic.target
Wants=system.slice
WantedBy=multi-user.target
Conflicts=shutdown.target
Before=shutdown.target multi-user.target
After=syslog.target network.target auditd.service systemd-journald.socket basic.target system.slice
Description=OpenSSH server daemon
. . .
- 显示单个属性 systemctl show sshd.service -p Conflicts
Conflicts=shutdown.target
- 屏蔽一个服务 systemctl mask nginx.service 将会屏蔽nginx服务,无法启动,自启动,手动操作
- 解除屏蔽 systemctl unmask nginx.service
- 编辑单元文件 systemctl edit nginx.service,将会打开一个空白的文件,用来覆盖或者添加指令到nginx服务单元文件。在/etc/systemd/system目录下会创建一个.d后缀文件夹,对于nginx来说为nginx.service.d文件夹。在文件夹中创建override.conf文件。当加载单元文件时会合并源单元文件和override.conf的内容用于内存
- 完全编辑单元文件 systemctl edit --full nginx.service 将会直接编辑当前的单元文件,不会创建片段文件。编辑完成后将会写入/etc/systemd/system中(优先级高于/lib/systemd/system)
- systemctl daemon-reload 用于重新加载单元文件
- systemctl get-default 查看当前系统的默认启动目标
- systemctl set-default graphical.target 用于设置默认启动目标
- systemctl list-unit-files --type=target ,systemctl list-units --type=target 查看可用的目标