如何配置Linux的服务设置为⾃动启动或崩溃重新启动后
介绍
在本教程中,⾃动启动 Linux 服务,我们将退后⼀步,更详细地解释 init 进程。你应该很好地了解它们如何控制守护进程的启动⾏为。
在第⼀部分本系列教程我们分享使⽤ MySQL 的如何崩溃或重启后启⽤的 Linux 服务⾃动启动⼀些实际的例⼦。
我们看到了如何从三个不同的初始化⽅式做到这⼀点:System V 的,Upstart,和 systemd。阅读第⼀个教程在其上分布在默认情况下使⽤的 init 系统的复习。
在本教程中,我们将退后⼀步,解释为什么我们运⾏命令并编辑我们所做的配置⽂件。我们将从 System V init 守护进程开始。我们还将看到为什么它随着时间的推移被更新的 init 模式所取代。
先决条件
要学习本教程,你需要你创建的三个 DigitalOceanDroplet 之前。
我们有:
运⾏ MySQL 的 Debian 6 服务器
⼀个运⾏ MySQL 的 Ubuntu 14.04 服务器
运⾏ MySQL 的 CentOS 7 服务器
我们建议您回到本系列的第 1 部分,先创建 Droplets。
此外,您将需要是 root ⽤户或在服务器上具有 sudo 权限。要了解 sudo 的权限是如何⼯作的看到有关这个 Sudo 教程 DigitalOcean 。
您不应在⽣产 Linux 服务器上运⾏本教程中的任何命令,查询或配置。
运⾏级别
运⾏级别代表了 Linux 系统的当前状态。
该概念来⾃ System V init,其中 Linux 系统引导,初始化内核,然后输⼊⼀个(且只有⼀个)运⾏级别。
例如,运⾏级可以是 Linux 服务器的关闭状态,单⽤户模式,重新启动模式等。每个模式将指⽰什么服
务可以在该状态下运⾏。
某些服务可以在⼀个或多个运⾏级别运⾏,但不能在其他运⾏级别运⾏。
运⾏级别由单个数字表⽰,它们可以具有介于 0 和 6 之间的值。以下列表显⽰了这些级别各⾃的含义:
运⾏级别 0:系统关闭
运⾏级别 1:单⽤户,救援模式
运⾏级别 2,3,4:多⽤户,与⽹络⽂本模式下启⽤
运⾏级别 5:多⽤户,启⽤⽹络,图形模式
运⾏级别 6:系统重启
运⾏级别 2,3 和 4 因分布⽽异。例如,⼀些 Linux 发⾏版不实现运⾏级别 4,⽽其他的。⼀些分布在这三个级别之间有明显的区别。通常,运⾏级别 2,3 或 4 意味着Linux 已在多⽤户,启⽤⽹络的⽂本模式下引导的状态。
当我们启⽤⼀个服务⾃动启动,我们实际上是将它添加到运⾏级别。在系统 V 中,OS 将以特定的运⾏
级别开始; 并且,当它启动时,它将尝试启动与该运⾏级别相关联的所有服务。
运⾏级别成为 systemd 的⽬标,我们将在 systemd 部分讨论。
Init 和 PID 1
初始化是在计算机启动和内核加载到内存中后,开始在 Linux 系统中的第⼀个进程。
除此之外,它决定了⽤户进程或系统服务应该按什么顺序加载,以及是否应该⾃动启动。
在 Linux 中每个进程都有⼀个进程 ID(PID)和init有 1. PID 就这么随后产卵系统⾃带的在线所有其他进程的⽗。
Init 的历史
随着 Linux 的发展,init 守护进程的⾏为也发⽣了变化。最初,Linux 开始使⽤ System V init,与 UNIX 中使⽤的相同。⾃那时以来,Linux 已经实施了Upstart的 init 守护进程(被 Ubuntu 创建)现在systemd的 init 守护进程(最初由 Fedora 的实现)。
⼤多数 Linux 发⾏版已逐渐从 System V 迁移或逐步淘汰,只保留向后兼容性。 FreeBSD 是 UNIX 的⼀种变体,它使⽤ System V 的不同实现,称为 BSD init。旧版本的 Debian 也使⽤ SysVinit。
每个版本的 init 守护程序都有不同的管理服务的⽅式。这些变化背后的原因是需要⼀个强⼤的服务管理⼯具,不仅处理服务,⽽且处理设备,端⼝和其他资源; 这将并⾏加载资源,这将从崩溃恢复。
系统 V 初始化序列
系统 V 使⽤了inittab⽂件,它像 Upstart 后的 init ⽅法已经保持向后兼容性。
让我们通过 System V 的启动顺序:
1. 在 init 守护进程从⼆进制⽂件创建/sbin/init
2. 第⼀个⽂件在 init 守护进程是读取/etc/inittab
3. 此⽂件中的⼀个条⽬决定机器应引导到的运⾏级别。例如,如果运⾏级别的值指定为 3,则 Linux 将在启⽤了联⽹的多⽤户⽂本模式下启动。(此运⾏级别称为
默认运⾏级别)
4. 接下来,init 守护进程会进⼀步眺望/etc/inittab的⽂件和在读什么初始化它需要为运⾏级别的脚本
因此,当 init 守护进程到它需要为给定的运⾏级别运⾏的 init 脚本时,它基本上出了启动它需要什
么服务。这些 init 脚本是您可以在其中配置单个服务的启动⾏为,就像我们在第⼀个教程中对 MySQL 的启动⾏为⼀样。
接下来,让我们详细了解 init 脚本。
系统 V 配置⽂件:Init 脚本
init 脚本是控制系统 V 中的特定服务(如 MySQL 服务器)的脚本。
服务的 Init 脚本由应⽤程序的供应商提供,或者带有 Linux 发⾏版(适⽤于本地服务)。我们还可以为⾃定义创建的服务创建⾃⼰的 init 脚本。
当⼀个进程或服务(如 MySQL 服务器)启动时,其⼆进制程序⽂件必须加载到内存中。
根据服务的配置,此程序可能必须持续在后台执⾏(并接受客户端连接)。启动,停⽌或重新加载此⼆进制应⽤程序的任务由服务的 init 脚本处理。这就是所谓的初始化脚本,因为它初始化服务。
在 System V 中,init 脚本是 shell 脚本。
初始化脚本也被称为RC(运⾏命令)的脚本。
⽬录结构
将/etc⽬录是启动脚本的⽗⽬录。
init 的 shell 脚本的实际位置是在/etc/init.d。这些脚本符号链接到rc⽬录。
内/etc⽬录下,我们有⼀些rc⽬录,每⼀个在其名称中的数字。
数字表⽰不同的运⾏级别。因此,我们有/etc/rc0.d,/etc/rc1.d,/etc/rc2.d等等。
然后,每个内rc n .d⽬录,我们有⼀个既具有开始的⽂件K或S在他们的⽂件名,后⾯两个数字。这些是指向实际 init shell 脚本的符号链接⽂件。为什么K和S? K 表⽰停⽌(即停⽌),“S”表⽰开始。
两个数字表⽰脚本的执⾏顺序。因此,如果我们有⼀个名为 K25 some_script⽂件,它将 K99 another_script之前执⾏。
启动
让我们回来跟我们的启动顺序。那么如何调⽤ init 脚本呢?谁叫他们?
在 K 和 S 脚本不会由 init 守护程序直接调⽤,⽽是由另外⼀个脚本:在/etc/init.d/rc脚本。
如果你还记得,在/etc/inittab的⽂件通知 init 守护进程的运⾏级别,系统默认情况下应进⼊。对于每⼀个运⾏级别,在⼀条线/etc/inittab⽂件调⽤/etc/init.d/rc脚本,传递上的运⾏级别作为参数。基于此参数,脚本然后调⽤相应的下的⽂件/etc/rc n .d⽬录。所以,如果服务器靴⼦的 runlevel 2,根据脚本/etc/rc2.d会被调⽤; 为级别 3,根据脚
本/etc/rc3.d被执⾏,等等。
在⼀个rc⽬录,⾸先,所有 K 个脚本都按数字顺序以“⼀站式”的参数运⾏,然后所有的 S 脚本都以类似的⽅式⽤的参数运⾏“开始。” 在后台,将分别使⽤ stop 和 start 参数调⽤相应的 init shell 脚本。
现在,因为下的⽂件/etc/rc n .d⽬录(K nn和S nn⽂件)符号链接⽽已,美其名⽈意味着调⽤与站的实际初始化 shell 脚本和启动参数。
总⽽⾔之,当 Linux 服务器进⼊运⾏级别时,将运⾏某些脚本以停⽌某些服务,⽽其他脚本将运⾏以启动其他服务。
启动脚本中调⽤这个也恰好当系统切换到⼀个新的运⾏级别:对应/etc/rc<n>.d⽬录的脚本执⾏。⽽且,由于这些钾和硫的⽂件是什么,但环节,根据实际的 shell 脚
本/etc/init.d⽬录与相应的启动执⾏或停⽌争论。
整个过程确保任何不应该在该运⾏级别运⾏的服务被停⽌,并且所有服务应该在该运⾏级别运⾏。
系统 V ⾃动启动
由于我们使服务在引导时⾃动启动,我们实际上是修改 init ⾏为。
因此,例如,当我们在运⾏级别 3 使能⾃动启动服务,幕后的过程中会在适当的环节/etc/rc3.d⽬录。
如果这听起来很混乱,不要担⼼ – 我们会在⼀分钟内看到这⼀切意味着什么。
系统 V ⽰例
我们将回到我们的 MySQL 服务⽰例,这次有更多的理论。
第 1 步 – 登录 Debian Droplet
为了本教程的这⼀部分,我们将回到我们在第 1 部分中创建的 Debian 6 Droplet。使⽤ SSH 命令连接到服务器(Windows ⽤户可以使⽤像 PuTTy 这样的⼯具连接)。
ssh sammy@your_server_ip
第 2 步 – 查看 inittab
运⾏以下命令来查看inittab⽂件的内容:
cat /etc/inittab | grep initdefault
输出应该是这样的:
Outputid:2:initdefault:
2 后的 id 字段显⽰系统被配置为以 runlevel 2 开始。这是默认的运⾏级别。在这种情况下,Debian 将 2 指定为多⽤户⽂本模式。如果执⾏以下命令:
cat /etc/inittab | grep Runlevel
输出确认:
Output# Runlevel 0 is halt.
# Runlevel 1 is single-user.
# Runlevels 2-5 are multi-user.
# Runlevel 6 is reboot.
第 3 步 – 查看 rc ⽬录
运⾏以下命令列出rc⽬录。你应该看到有以下六个:
ls -ld /etc/rc*.d
Outputdrwxr-xr-x 2 root root 4096 Jul 31 07:09 /etc/rc0.d
drwxr-xr-x 2 root root 4096 Jul 31 07:09 /etc/rc1.d
drwxr-xr-x 2 root root 4096 Jul 31 07:21 /etc/rc2.d
drwxr-xr-x 2 root root 4096 Jul 31 07:21 /etc/rc3.d
drwxr-xr-x 2 root root 4096 Jul 31 07:21 /etc/rc4.d
drwxr-xr-x 2 root root 4096 Jul 31 07:21 /etc/rc5.d
drwxr-xr-x 2 root root 4096 Jul 31 07:09 /etc/rc6.d
drwxr-xr-x 2 root root 4096 Jul 23  2012 /etc/rcS.d
由于在运⾏级别 2(从 inittab ⽂件默认的 init)在系统启动时,根据脚本/etc/rc2.d的⽬录会在系统启动时执⾏。
列出此⽬录的内容:
ls -l /etc/rc2.d
这显⽰⽂件只是符号链接,每个指向/etc/init.d 下的脚本⽂件:
Output. . .
lrwxrwxrwx 1 root root  17 Jul 23  2012 S01rsyslog -> ../init.d/rsyslog
lrwxrwxrwx 1 root root  22 Jul 23  2012 S02acpi-support -> ../init.d/acpi-support
lrwxrwxrwx 1 root root  15 Jul 23  2012 S02acpid -> ../init.d/acpid
lrwxrwxrwx 1 root root  17 Jul 23  2012 S02anacron -> ../init.d/anacron
lrwxrwxrwx 1 root root  13 Jul 23  2012 S02atd -> ../init.d/atd
lrwxrwxrwx 1 root root  14 Jul 23  2012 S02cron -> ../init.d/cron
lrwxrwxrwx 1 root root  15 Jul 31 07:09 S02mysql -> ../init.d/mysql
lrwxrwxrwx 1 root root  13 Jul 23  2012 S02ssh -> ../init.d/ssh
. . .
我们可以看到这⾥没有 K 脚本,只有 S(start)脚本。脚本启动知名的服务,如rsyslog 现在,cron 的,或ssh。
记住,S 之后的两个数字决定起始顺序:例如,rsyslog 在 cron 守护程序之前启动。我们还可以看到 MySQL 在这⾥列出。
第 4 步 – 查看 Init 脚本
现在我们知道,安装在系统 V 兼容的服务时,它会创建下 shell 脚本/etc/init.d⽬录。检查 MySQL 的 shell 脚本:
ls -l /etc/init.d/my*
Output-rwxr-xr-x 1 root root 5437 Jan 14  2014 /etc/init.d/mysql
要查看启动脚本的外观,请阅读⽂件:
cat /etc/init.d/mysql | less
从输出,你会看到它是⼀个⼤的 bash 脚本。
第 5 步 – 使⽤ chkconfig 或 sysv-rc-conf
在基于 RHEL 的发⾏像 CentOS 的,⼀个命令调⽤chkconfig可以⽤来启⽤或系统五,禁⽤服务,它还可以列出已安装的服务和他们的运⾏级别。
检查 CentOS 系统上所有运⾏级别的服务状态的语法如下:
chkonfig --list | grep service_name
没有这样的⼯具附带的 Debian 本⾝(update-rc.d安装或只从运⾏级别删除服务)。我们可以,但是,安装定制的⼯具,称为sysv-rc-conf帮助我们管理服务。运⾏以下命令来安装sysv-rc-conf:
sudo apt-get install sysv-rc-conf -y
安装⼯具后,只需执⾏此命令即可查看各种服务的运⾏级别⾏为:
sudo sysv-rc-conf
输出将是⼀个漂亮的图形窗⼝,如下所⽰。从这⾥,我们可以清楚地看到什么服务启⽤了什么运⾏级别(标记为 X)。
利⽤箭头键和SPACEBAR,可以启⽤或对⼀个或多个运⾏级别禁⽤服务。
现在,按离开屏幕Q。
第 7 步 – 在引导时测试 MySQL 启动⾏为
从上⼀节的截图中可以看出,根据我们在本教程第 1 部分的测试,MySQL ⽬前在运⾏级别 2-5 上启⽤。
运⾏下⾯的命令关闭 MySQL 服务:
sudo update-rc.d mysql disable
Outputupdate-rc.d: using dependency based boot sequencing
insserv: warning: current start runlevel(s) (empty) of script `mysql' overwrites defaults (2 3 4 5).
insserv: warning: current stop runlevel(s) (0 1 2 3 4 5 6) of script `mysql' overwrites defaults (0 1 6).
现在运⾏命令:
ls -l /etc/rc2.d
输出应显⽰从符号链接/etc/rc2.d以/etc/init.d/mysql已更改为K:
Output. . .
lrwxrwxrwx 1 root root  15 Jul 31 07:09 K02mysql -> ../init.d/mysql
. . .
换句话说,MySQL 将不再在默认 runlevel(2)启动。
这是当我们启⽤和禁⽤服务时,在 System V 的幕后发⽣的。只要在服务的缺省 runlevel ⽬录下有⼀个 S 脚本,init 将在启动时启动该服务。
再次启⽤服务:
sudo update-rc.d mysql enable
第 8 步 – 测试崩溃时 MySQL 启动⾏为
让我们看看 System V 如何处理服务崩溃。
请记住,我们做了⼀个改变了/etc/inittab在本教程的第 1 部分⽂件,以使 MySQL 的系统崩溃后⾃动启动。我们添加了以下⾏:
/ etc / inittab
ms:2345:respawn:/bin/sh /usr/bin/mysqld_safe
这是为了确保 MySQL 服务在崩溃后启动。要检查是否发⽣这种情况,请⾸先重新启动服务器:
sudo reboot
⼀旦服务器回来,SSH 到它并检查 MySQL 进程 ID 像之前⼀样:
ps -ef | grep mysql
注意进程 ID mysqld_safe和mysqld。在我们的例⼦中,分别是 895 和 1019:
Outputroot      907    1  0 07:30 ?        00:00:00 /bin/sh /usr/bin/mysqld_safe
mysql    1031  907  0 07:30 ?        00:00:00 /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --user=mysql --pid-file=/var/run/mysqld/mysqld.pid --socket=/var/run/mysqld/mysqld.sock --port=3306 root      1032  907  0 07:30 ?        00:00:00 logger -t mysqld -
root      2550  2532  0 07:31 pts/0    00:00:00 grep mysql
有⼀次终⽌这些进程-9开关(替代与 Debian 系统的 PID):
sudo kill -9 907
sudo kill -9 1031
<! – 标记变量为红⾊ – >
等待五分钟左右,然后执⾏命令:
sudo service mysql status
输出将显⽰ MySQL 服务正在运⾏,从这⾏开始:
Output/usr/bin/mysqladmin  Ver 8.42 Distrib 5.1.73, for debian-linux-gnu on x86_64
如果您运⾏ps -ef | grep mysql ps -ef | grep mysql命令再次,你会看到,⽆论是mysqld_safe和mysqld进程已经上来了。
尝试杀死进程⼏次,在每种情况下,它应该在五分钟后重⽣。
这是我们增加的原因,额外⾏/etc/inittab:你这是怎么配置的 System V 服务崩溃重⽣。还有就是语法此⾏的详细解释第 1 部分。
但是,为服务添加⾃动重新启动时请⼩⼼:如果服务尝试重新⽣成并在两分钟内失败超过⼗次,则 Linux 将禁⽤在接下来的五分钟内重新启动。这就是系统保持稳定,不会耗尽计算资源。
如果您碰巧在控制台中收到有关此类事件的消息或在系统⽇志中到该消息,您将知道应⽤程序存在需要修复的问题,因为它会持续崩溃。
Upstart 简介
经典 SysVinit 在 Upstart 出现之前已经成为主流 Linux 发⾏版的⼀部分。
随着 Linux 市场的增长,加载作业和服务的序列化⽅法变得更加耗时和复杂。与此同时,随着越来越多的现代设备(如可热插拔的存储介质)激增了市场,SysVinit 被发现⽆法快速处理它们。
需要更快的加载操作系统,正常清理崩溃的服务,以及可预测的系统服务之间的依赖驱动了对更好的服务管理器的需要。 Ubuntu 的开发⼈员提出了另⼀种初始化⽅法,即 Upstart 守护进程。
Upstart init 在⼏个⽅⾯优于 System V init:
Upstart 不处理奥术 shell 脚本加载和管理服务。相反,它使⽤易于理解和修改的简单配置⽂件
Upstart 不像 System V ⼀样连续加载服务。这减少了系统引导时间
Upstart 的采⽤了灵活的事件系统定制服务是如何在各种状态下处理
Upstart 有更好的⽅式来处理崩溃的服务应该重⽣的⽅式
没有必要保留⼀些冗余的符号链接,都指向同⼀个脚本
linux怎么读取文件Upstart 与 System V 的向后兼容/etc/init.d/rc脚本仍然运⾏管理本地系统 V 服务
Upstart 活动
Upstart 允许将与服务相关联的多个事件。这种基于事件的架构允许 Upstart 灵活地处理服务管理。
每个事件都可以触发⼀个处理该事件的 shell 脚本。
Upstart 活动包括:
开始
开始
停⽌
停⽌
在这些事件之间,服务可以是在许多州,像:
等候
预启动
开始
运⾏
预停
停⽌
等等
Upstart 也可以对这些状态中的每⼀个采取⾏动,创建⼀个⾮常灵活的架构。
Upstart Init 序列
如 System V,也 Upstart 运⾏/etc/init.d/rc在启动脚本。此脚本正常执⾏任何 System V init 脚本。
Upstart 也期待下/etc/init⽬录,并在每个服务配置⽂件执⾏ shell 命令。
Upstart 配置⽂件
Upstart 使⽤配置⽂件来控制服务。
Upstart 不使⽤系统 V 的⽅式使⽤ Bash 脚本。相反,Upstart 使⽤服务配置⽂件与命名标准service_na
me .conf。该⽂件的纯⽂本内容不同的部分,称为节。每节描述了服务的不同⽅⾯以及它应该如何运⾏。
不同的控制节为服务不同的事件,如预启动,启动,前期停⽌或停⽌后。
节本⾝包含 shell 命令。因此,可以为每个服务的每个事件调⽤多个操作。
每个配置⽂件还指定了两件事:
服务应该启动和停⽌的运⾏级别
⽆论它是否崩溃服务应该重⽣
⽬录结构
Upstart 配置⽂件位于下/etc/init⽬录(不要与混淆/etc/init.d)。
Upstart ⽰例
让我们来看看 Upstart 如何再次处理 MySQL Server,这次有更多的背景知识。
第 1 步 – 登录到 Ubuntu Droplet
回到我们在第 1 部分中创建的 Ubuntu 14.04 Droplet。
使⽤ SSH 命令连接到服务器(Windows ⽤户可以使⽤像 PuTTy 这样的⼯具进⾏连接)。
ssh sammy@your_server_ip
第 2 步 – 查看 init 和 rc ⽬录
⼤多数 Upstart 的 config ⽂件在/etc/init⽬录中。这是创建新服务时应使⽤的⽬录。
登录服务器后,执⾏以下命令:
sudo ls -l /etc/init/ | less
结果将显⽰⼤量的服务配置⽂件,⼀次⼀屏。这些是在 Upstart 下本机运⾏的服务:
Outputtotal 356
. . .
-rw-r--r-- 1 root root  297 Feb  9  f