这篇文章将介绍Linux系统启动时用于启动服务的init机制以及init运行级的概念和相关知识。
1、概念
1.1、init系统
Linux系统的启动首先从BIOS开始,接下来Linux的引导程序将内核映像加载到内存,进行内核初始化。在内核初始化的最后一步,就是启动PID为1的init进程,这个进程是系统的第一个进程,负责启动那些开机时需要启动的服务。
大多数的Linux发行版的init系统都是和System V兼容的,所以也被称为sysinit,这是最早也是最流行的init系统。sysinit概念简单清晰,主要依赖于shell脚本。它一次一个串行启动进程,导致了它的致命缺点,启动太慢。当Linux被应用到移动设备上时,这个缺点就成了大问题。
当前已经在使用systemd来替代sysinit。从CentOS 7开始,已经使用systemd代替了sysinit。所以这里所说的init机制及运行级的概念只适用于CentOS 6以及之前的版本。
1.2、运行级
init可以根据使用者定义的执行等级(runlevel)来唤醒不同的服务,进入不同的操作模式,这些执行等级就称为运行级。Linux提供了以下7种运行级:
- init0:关机模式
- init1:单用户援救模式
- init2:字符界面多用户模式,无网络支持
- init3:字符界面多用户模式,运行一个完整的系统
- init4:保留未使用
- init5:图形界面模式
- init6:重启模式
通过在命令行中输入运行级即可进入相应的运行级,如
[root@localhost ~]# init 6
那么系统将会进入init 6模式,即重启。
使用runlevel或who -r命令可以查看当前的运行级:
[root@localhost etc]# runlevel
N 3
[root@localhost etc]# who -r
运行级别 3 2018-10-19 11:14
2、init详解
2.1、init涉及的文件及目录
init本身是一个可执行的二进制文件,位于/sbin目录下,完整路径为:
/sbin/init
以下文件为init运行级的配置文件:
/etc/inittab
打开该文件可以看到以下内容:
# inittab is only used by upstart for the default runlevel.
#
# ADDING OTHER CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM.
#
# System initialization is started by /etc/init/rcS.conf
#
# Individual runlevels are started by /etc/init/rc.conf
#
# Ctrl-Alt-Delete is handled by /etc/init/control-alt-delete.conf
#
# Terminal gettys are handled by /etc/init/tty.conf and /etc/init/serial.conf,
# with configuration in /etc/sysconfig/init.
#
# For information on how to write upstart event handlers, or how
# upstart works, see init(5), init(8), and initctl(8).
#
# Default runlevel. The runlevels used are:
# 0 - halt (Do NOT set initdefault to this)
# 1 - Single user mode
# 2 - Multiuser, without NFS (The same as 3, if you do not have networking)
# 3 - Full multiuser mode
# 4 - unused
# 5 - X11
# 6 - reboot (Do NOT set initdefault to this)
#
id:3:initdefault:
通过修改id后面的数字即可在开机时进入相应的运行级。
init执行的脚本文件全部位于/etc/rc.d目录下,进入该目录,可以看到有以下三个脚本文件及8个目录,分别为:
# 脚本文件
rc
rc.local
rc.sysinit
# 目录
init.d
rc0.d
rc1.d
rc2.d
rc3.d
rc4.d
rc5.d
rc6.d
脚本文件中,通过rc runlevel可执行相应运行级目录中的所以启动脚本;rc.local为系统进入到登录界面之前执行的最后一个脚本;rc.sysinit则用于系统的初始化操作。
目录中,init.d保存了所有系统服务脚本;rc[0-6].d则为每个运行级需要启动的服务,里面的文件均为到init.d目录下脚本的符号链接。
这里我们进入到rc3.d目录下,看看里面的详细情况。进入该目录可以看到目录下有以下一些文件:
该目录下有以K数字开头的和以S数字开头的文件,其中以K数字开头的文件表示在该运行下关闭的服务,而S数字开头的文件表示该运行级下启动的服务。其中数字为顺序。init就是通过这种形式依次启动服务的。
我们来看下S01sysstat这个文件的详细信息:
[root@localhost rc3.d]# ll S01sysstat
lrwxrwxrwx. 1 root root 17 10月 16 15:43 S01sysstat -> ../init.d/sysstat
可以看到,该文件为到init.d下sysstat脚本的符号链接。
如果细心的话,你可以在/etc目录下发现跟/etc/rc.d目录下同名的脚本文件跟目录,其实这些脚本文件跟目录均链接到/etc/rc.d目录下:
[root@localhost etc]# pwd
/etc
[root@localhost etc]# ll init.d rc*
lrwxrwxrwx. 1 root root 11 10月 16 15:36 init.d -> rc.d/init.d
lrwxrwxrwx. 1 root root 7 10月 16 15:40 rc -> rc.d/rc
lrwxrwxrwx. 1 root root 10 10月 16 15:40 rc0.d -> rc.d/rc0.d
lrwxrwxrwx. 1 root root 10 10月 16 15:40 rc1.d -> rc.d/rc1.d
lrwxrwxrwx. 1 root root 10 10月 16 15:40 rc2.d -> rc.d/rc2.d
lrwxrwxrwx. 1 root root 10 10月 16 15:40 rc3.d -> rc.d/rc3.d
lrwxrwxrwx. 1 root root 10 10月 16 15:40 rc4.d -> rc.d/rc4.d
lrwxrwxrwx. 1 root root 10 10月 16 15:40 rc5.d -> rc.d/rc5.d
lrwxrwxrwx. 1 root root 10 10月 16 15:40 rc6.d -> rc.d/rc6.d
lrwxrwxrwx. 1 root root 13 10月 16 15:40 rc.local -> rc.d/rc.local
lrwxrwxrwx. 1 root root 15 10月 16 15:40 rc.sysinit -> rc.d/rc.sysinit
注意:/etc/rc.d/init.d目录下只存放服务的启动脚本,而服务的配置文件则位于/etc/sysconfig目录下。
2.2、init机制下服务的管理
在init机制下可以通过service命令对服务进行管理,可以通过以下命令对服务进行启动|停止|重启|重新载入|查看运行状态:
service daemon start|stop|restart|reload|status
service命令实质上是通过/etc/init.d目录中保存的脚本文件来对服务进行管理的,这些脚本可以接受参数的输入,所以还可以使用下面的方法对服务进行启动|停止|重启|重新载入|查看运行状态:
/etc/init.d/daemon start|stop|restart|reload|status
使用chkconfig命令可以对开机启动的服务进行管理:
# 查看所有服务在各运行级下的开机启动状态
chkconfig --list
# 查看具体的服务在各运行级下的开机启动状态
chkconfig --list daemon
#一个例子,查看sshd服务在各运行级下的开机启动状态
[root@localhost ~]# chkconfig --list sshd
sshd 0:关闭 1:关闭 2:启用 3:启用 4:启用 5:启用 6:关闭
# 设置服务开机启动
chkconfig daemon on
# 取消服务开机启动
chkconfig daemon off
#将自定义的服务加入系统服务(必须将自定义服务的管理脚本拷贝到/etc/init.d目录下)
chkconfig --add daemon
# 从系统服务中删除自定义的服务
chkconfig --del daemon
# 设置服务在指定的运行级开机启动|取消开机启动
chkconfig --level runlevle daemon on|off
3、设置自定义服务的开机启动
当我们要为系统安装额外的服务时,比如安装apache提供http服务,如果通过yum或rpm包的方式安装,则应用一般会自动将自己的服务管理脚本拷贝到/etc/rc.d/init.d目录中,以实现通过chkconfig命令对服务进行开机启动设置;但当我们通过源码包进行安装的时候,则无法实现上面的功能,那么就意味着无法通过chkconfig命令对服务进行设置,自然也无法实现服务的开机自启动功能。所以这里需要通过手动设置实现开机启动的功能。
3.1、通过rc.local文件实现开机启动
上面介绍过rc.local这个脚本文件是系统进入登录界面之前执行的最后一个脚本,所以我们可以把需要在开机后执行的命令添加到该脚本中,通过命令执行服务的管理脚本即可实现服务的开机启动。
例子:待补充
3.2、通过在rc[0-6].d目录下建立符号链接实现在指定运行级下的开机启动
将服务的管理脚本拷贝到/etc/init.d目录下,然后在对应运行级的rcn.d目录中使用ls -n命令建立一个以S数字开头的到/etc/init.d目录下脚本的符号链接即可实现在开机时启动服务。
例子:待补充
3.3、使用chkconfig命令将自定义服务加入系统服务
使用chkconfig --add daemon命令可以将自定义服务加入系统服务,前提是必须将服务的管理脚本拷贝到/etc/init.d目录下。
例子:待补充