这篇文章将介绍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模式,即重启。

使用runlevelwho -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目录下,看看里面的详细情况。进入该目录可以看到目录下有以下一些文件:

_MyHomePageState 初始化 执行 初始化运行_自定义

该目录下有以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目录下。

例子:待补充