systemd

linux启动中内核初始化后,内核启动init程序(/sbin/init),本质上是软连接
(lrwxrwxrwx 1 root root 22 10月 26 10:10 init -> …/lib/systemd/systemd)

pid为1,其他进程都由init进程直接或间接创建和运行

ps -ef|grep systemd
root         1     0  0 11月21 ?      00:01:24 /usr/lib/systemd/systemd --switched-root --system --deserialize 22

unit单元,系统初始化的时候需要做一些事情,比如启动ssh服务、挂载文件系统等,这个过程中的每一步都抽象成一个unit。一个服务就是一个unit,一个挂载点也是一个unit,常见的unit有service、socket、device等。
unit文件按systemd的约定放置在三个地方,存在优先级,上面的优先级高
/etc/systemd/system
/run/systemd/system
/usr/lib/systemd/system

unit文件的三个部分为:

示例:ssh的service
$ systemctl cat sshd.service
[Unit]
Description=OpenSSH server daemon
Documentation=man:sshd(8) man:sshd_config(5)
After=network.target sshd-keygen.service
Wants=sshd-keygen.service

[Service]
EnvironmentFile=/etc/sysconfig/sshd
ExecStart=/usr/sbin/sshd -D $OPTIONS
ExecReload=/bin/kill -HUP $MAINPID
Type=simple
KillMode=process
Restart=on-failure
RestartSec=42s

[Install]
WantedBy=multi-user.target

解释:
[Unit]:记录unit文件的通用信息
After Befter描述启动顺序
Wants Require描述依赖关系,Wants弱依赖 依赖程序退出对当前程序无影响,Require强依赖,依赖程序退出当前程序也需要退出

[Service]:记录Service的信息
启动命令
EnvironmentFile 指定一个配置文件,在unit文件里可以$key的形式获取到
WorkingDirectory 工作目录,在这个目录中可以用相对路径
ExecStart 启动服务执行的命令,Exec命令要用绝对路径
ExecReload 重载服务执行的命令
启动类型
Type simple启动的时候进程为主进程;oneshot只执行一次,service不会长期运行;
重启行为
KillMode control-group默认值,所有子进程一起杀掉;process只停止主进程;
Restart on-failure失败就重启;
RestartSec 重启前等待秒数

所有的启动设置之前,都可以加上一个连词号(-),表示"抑制错误",即发生错误的时候,不影响其他命令的执行。
比如,EnvironmentFile=-/etc/sysconfig/sshd(注意等号后面的那个连词号),就表示即使/etc/sysconfig/sshd文件不存在,也不会抛出错误。

[Install]:安装信息,怎么样做到开机启动
Target表示一组服务,WantedBy=multi-user.target表示此服务在multi-user服务组中
systemcrl默认启动的服务组为multi-user.target,这个组里的服务都将开启自启动

查看 multi-user.target 包含的所有服务
$ systemctl list-dependencies multi-user.target

systemctl命令有下面多种:
systemcrl [command] [unit]

start
stop
kill
restart
reload

enable 系统开机自启动
在/etc/systemd/system里加一个链接到所在服务组的wangts目录中,因为开机时Systemd只执行/etc/systemd/system目录里面的配置文件

disable 开机不自启动

status
systemctl status redis
● redis.service - Redis persistent key-value database
Loaded: loaded (/usr/lib/systemd/system/redis.service; enabled; vendor preset: disabled)
Drop-In: /etc/systemd/system/redis.service.d
└─limit.conf
Active: active (running) since 五 2023-11-24 05:57:26 CST; 4 days ago
Process: 26276 ExecStop=/usr/libexec/redis-shutdown (code=exited, status=0/SUCCESS)
Main PID: 26374 (redis-server)
CGroup: /system.slice/redis.service
└─26374 /usr/bin/redis-server 0.0.0.0:6379

Warning: Journal has been rotated since unit was started. Log output is incomplete or unavailable.
含义:
Loaded 加载位置,是否自启动
Active 正在运行
Main PID 主进程id
CGroup 所有子进程

另外还有
老系统命令 新系统命令 作用
chkconfig foo on;systemctl enable httpd 开机自动启动
chkconfig foo off;systemctl disable httpd 开机不自动启动
chkconfig foo;systemctl is-enabled httpd 查看特定服务是否为开机自启动
chkconfig --list;systemctl list-unit-files --type=httpd 查看各个级别下服务的启动与禁用情况

补充init.d
init.d指的是/etc/rc.d/init.d

[root@ rc.d]# ll
total 4
drwxr-xr-x. 2 root root  222 Nov 30 20:11 init.d
drwxr-xr-x. 2 root root  137 Nov 30 20:11 rc0.d
drwxr-xr-x. 2 root root  137 Nov 30 20:11 rc1.d
drwxr-xr-x. 2 root root  137 Nov 30 20:21 rc2.d
drwxr-xr-x. 2 root root  137 Nov 30 20:21 rc3.d
drwxr-xr-x. 2 root root  137 Nov 30 20:21 rc4.d
drwxr-xr-x. 2 root root  137 Nov 30 20:21 rc5.d
drwxr-xr-x. 2 root root  137 Nov 30 20:11 rc6.d
-rwxrwxrwx. 1 root root 1105 Nov  7 15:29 rc.local

/etc/init.d目录是/etc/rc.d/init.d目录的软链接

[root@ ~]# ll /etc | grep init
lrwxrwxrwx.  1 root root       11 Dec 27  2022 init.d -> rc.d/init.d

init.d目录下是很多shell脚本,在系统启动时执行。在这里的脚本可以用service命令查询状态、开启、关闭

[root@ init.d]# ll
-rwxr-xr-x  1 root root 10576 Nov 30 18:40 mysql
-rwxr-xr-x  1 root root  1698 Nov 30 15:24 nginx
-rwxr-xr-x  1 root root  3885 Nov 30 15:24 postgresql
-rw-r--r--  1 root root  1161 Jan 29  2023 README
-rwxr-xr-x  1 root root  1376 Nov 30 20:11 redis

rc.d下的rc0.d - rc6.d表示的是各运行级别的脚本,linux系统启动时要选择运行级别,就会读取etc/inittab文件得到级别,然后选择一个rcx.d。rcx.d下的文件都是软链接,真实文件在init.d目录下。
启动顺序:
1.加载内核
2.执行init程序
3./etc/rc.d/rc.sysinit # 由init执行的第一个脚本,系统基本设置
4./etc/rc.d/rc $RUNLEVEL # $RUNLEVEL为缺省的运行模式
5./etc/rc.d/rc.local
6./sbin/mingetty # 等待用户登录

然而现在linux已经不再使用etc/inittab文件了,系统启动使用systemd机制。虽然systemctl和service是两种服务管理方式,但是systemcrl兼容了service。
systemctl是systemd的命令,service是SysVinit的命令。systemd是Linux常用的进程管理器,而SysVinit是传统的进程管理器。service实际是去/etc/init.d目录下,去执行相关程序/脚本文件,来管理服务的启停;systemctl则是去/lib/systemd/system目录下,创建和指令同名的service文件