2.1 启动管理
Linux启动过程是如何引导的?系统服务如何设置?要深入了解Linux,首先必须能回答这两个问题。本节主要介绍Linux启动的相关知识。
2.1.1 Linux系统的启动过程
RHEL 8采用了systemd,启动过程被大大缩短了。具体的启动步骤如下:
步骤01 开机自检。
步骤02 从硬盘的MBR中读取引导程序GRUB。
步骤03 引导程序根据配置文件显示引导菜单。
步骤04 如果选择进入Linux系统,此时引导程序就会加载Linux内核文件。
步骤05 当内核全部载入内存后,GRUB的任务完成。此时全部控制权限交给Linux,CPU开始执行Linux内核代码,如初始化任务调度、分配内存、加载驱动等。简而言之,此步骤将建立一个内核运行环境。
步骤06 内核代码执行完后,开始执行Linux系统的第一个进程——systemd,进程号为1。
步骤07 systemd进程启动后将读取/etc/systemd/system/default.target(这个文件的作用是设置系统的运行级别)。systemd会根据此文件设置系统的运行级别并启动相应的服务。
步骤08 服务启动完成后,将引导login弹出登录界面。
当系统首次引导时,处理器会执行一个位于已知位置处的代码,一般保存在基本输入/输出系统BIOS中。当找到一个引导设备之后,第一阶段的引导加载程序就被装入RAM并执行。这个引导加载程序小于512字节(一个扇区),它是加载第二阶段的引导加载程序。
当第二阶段的引导加载程序被装入RAM并执行时,通常会显示一个引导屏幕,并将Linux和一个可选的初始RAM磁盘(临时根文件系统)加载到内存中。在加载映像时,第二阶段的引导加载程序就会将控制权交给内核映像,然后内核就可以进行解压和初始化。在这个阶段中,第二个阶段的引导加载程序会检测系统硬件、枚举系统链接的硬件设备、挂载根设备,然后加载必要的内核模块。完成这些操作之后启动进程(systemd),并执行高级系统初始化工作。通过以上过程,系统完成引导,等待用户登录。
2.1.2 Linux运行级别
Linux系统不同的运行级别可以启动不同的服务。Linux系统共有7个运行级别,传统上分别用数字0~6来表示,但在systemd中通常是以英文加目标来表示。各个运行级别的定义如表2.1所示。
表2.1 Linux运行级别说明
需要特别说明的是,虽然许多Linux系统对运行级别2、3、4的定义不同,但是在RHEL 8中都统一设置成了多用户模式,这一点可以从表2.1中目标名称相同上看出。另外,以上目标名称还有一些别名,比如还可以使用runlevel0.target、runlevel1.target等来表示。
标准的Linux运行级别为3或5:如果是3,那么系统工作在多用户状态;如果是5,则运行着X Window系统。
要查看当前用户所处的运行级别,可以使用runlevel命令,如示例2-1所示。
【示例2-1】
[root@localhost ~]# runlevel N 3 [root@localhost ~]# init 5 [root@localhost ~]# runlevel 3 5 [root@localhost ~]# init 5 #系统重启,谨慎使用 [root@localhost ~]# init 6
其中,N代表上次所处的运行级别,3代表当前系统正运行在运行级别3。由于系统开机就进入运行级别3,因此上一次的运行级别没有,用N表示。要切换到其他运行级别,可使用init命令。例如,现在运行在级别3,即多用户文本登录界面,若要进入图形登录界面,则需进入级别5,可以执行命令“init 5”;若要重新启动系统,则可执行命令“init 6”。
2.1.3 服务单元控制
RHEL 8使用systemd替换了Sys V,其中最大的改变是控制服务的方式产生了变化。本小节将介绍如何在systemd中控制服务。
在控制服务之前需要注意的是,在systemd中通常将服务称为“单元”。systemd单元中包含服务、挂载点、系统设备等,这些都称为单元。查看系统中的单元,如示例2-2所示。
【示例2-2】
对服务单元的控制通常有激活单元(相当于启动服务)、停止单元、重启单元及重新读取配置等,这些控制操作如示例2-3所示。
【示例2-3】
在生产环境中,通常需要让服务在系统启动时也跟随系统一起启动,以便系统启动后能提供服务。设置系统服务自动激活,如示例2-4所示。
【示例2-4】
#查询服务是否为自动启动 [root@localhost ~]# systemctl is-enabled httpd Disabled #将服务设置为自动启动 [root@localhost ~]# systemctl enable httpd Created symlink from /etc/systemd/system/multi-user.target.wants/httpd.service to /usr/lib/systemd/system/httpd.service. #再次查询是否为自动启动 [root@localhost ~]# systemctl is-enabled httpd Enabled #取消服务自动启动 [root@localhost ~]# systemctl disable httpd Removed symlink /etc/systemd/system/multi-user.target.wants/httpd.service. [root@localhost ~]# systemctl is-enabled httpd disabled
除了以上这些变化外,关机等操作也由systemd来执行,可以使用示例2-5中的命令实现关机、重启等操作。
【示例2-5】
#关机操作 [root@localhost ~]# systemctl poweroff #重启 [root@localhost ~]# systemctl reboot #待机 [root@localhost ~]# systemctl suspend
与Sys V中的服务相似,systemd中的服务也是由文件控制的,不同的是systemd中使用的是单元配置文件而不是脚本。此处我们以httpd服务的单元配置文件为例简要说明其结构,内容如示例2-6所示。
【示例2-6】
[root@localhost ~]# cat /usr/lib/systemd/system/httpd.service #“[]”中的内容为配置文件的不同小节 #Unit小节中主要是单元的描述及依赖 [Unit] Description=The Apache HTTP Server #下面这行表示依赖的目标 After=network.target remote-fs.target nss-lookup.target Documentation=man:httpd(8) Documentation=man:apachectl(8) #Service小节是单元的最主要内容 #其中主要定义了服务的类型,启动、停止使用的命令,杀死服务使用的信号等 [Service] Type=notify EnvironmentFile=/etc/sysconfig/httpd ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND ExecReload=/usr/sbin/httpd $OPTIONS -k graceful ExecStop=/bin/kill -WINCH ${MAINPID} # We want systemd to give httpd some time to finish gracefully, but still want # it to kill httpd after TimeoutStopSec if something went wrong during the # graceful stop. Normally, Systemd sends SIGTERM signal right after the # ExecStop, which would kill httpd. We are sending useless SIGCONT here to give # httpd time to finish. KillSignal=SIGCONT #将该单元启动的进程加入到列表单元的临时文件命名空间中 PrivateTmp=true #安装单元,目前未使用 [Install] WantedBy=multi-user.target
以上是单元配置文件的示例,通常单元的配置文件会放在/usr/lib/systemd/system/(主要存放软件包安装的单元)和/etc/systemd/system/(主要存放由系统管理员安装的与系统密切相关的单元)目录中。如果需要添加单元配置文件,只需要将配置文件放到相应的目录中,然后执行命令“systemctl daemon-reload”即可。关于单元的更多详细信息,可执行命令“man 5 systemd.service”和“man systemd”以参考联机帮助手册。