本章节重点:
- Linux操作系统引导过程
- 会修复系统启动中的三种故障
- 服务 会写service文件
- 运行级别 runlevel
一、Linux系统引导过程
1. 引导过程总览
1.1 开机自检(BIOS)
服务器主机开机以后,将根据主板BIOS中的设置对CPU、内存、显卡、键盘等设备进行初步检测,检测成功后根据预设的启动顺序移交系统控制权,大多时候会移交给本机硬盘。
作用: ①开机检测硬件是否有故障 ②指引硬件去哪里找操作系统(根据bios中设置的开机启动顺序去找操作系统 1本地硬盘 2外接设备 3网卡)
1.2 MBR引导
当从本机硬盘中启动系统时,首先根据硬盘第一个扇区中MBR(主引导记录)的设置,将系统控制权传递给包含操作系统引导文件的分区;或者直接根据MBR 记录中的引导信息调用启动菜单(如 GRUB)。
总结: 运行放在MBR扇区里的启动GRUB引导程序。
1.3 GRUB菜单
对于Linux操作系统来说,GRUB(统一启动加载器)是使用最为广泛的多系统引导器程序。系统控制权传递给GRUB以后,将会显示启动菜单给用户选择,并根据所选项(或采用默认值)加载Linux内核文件,然后将系统控制权转交给内核。
CentOS 7 采用的是 GRUB2 启动引导器。
总结: GRUB引导程序通过读取GRUB配置文件/boot/grub2/grub.cfg,来获取内核和镜像文件系统的设置和路径位置,并屏幕显示grub菜单。(即选择内核文件和系统类型)
bootloader:引导加载器,引导硬件去找到内核(操作系统的核心)
1.4 加载内核(kernel)
Linux内核是一个预先编译好的特殊二进制文件,介于各种硬件资源与系统程序之间,负责资源分配与调度。内核接过系统控制权以后,将完全掌控整个Linux操作系统的运行过程。
CentOS 7系统中,默认的内核文件位于“/boot/vmlinuz-3.10.0-514.el7.x86_64”。
总结: 把内核和镜像文件系统加载到内存中,使其可以使用。
1.5 启动程序
- centos7 启动的第一个程序 systemd 守护进程
- centos6 启动的第一个程序 init
init进程初始化: 为了完成进一步的系统引导过程,Linux内核首先将系统中的“/sbin/init”程序加载到内存中运行(运行中的程序称为进程),init 进程负责完成整个系统的初始化,最后等待用户进行登录。
总结: 加载硬件驱动程序,内核把init进程加载到内存中运行
2. 运行级别所对应的 Systemd 目标
| 运行级别 | systemd的target | 说明 |
|---|---|---|
| 0 | poweroff.target | 关机状态,使用该级别时将会关闭主机 |
| 1 | rescue.target | 单用户模式,不需要密码验证即可登录系统,多用于系统维护 |
| 2 | rescue.target | 用户定义/域特定运行级别。默认等同于3 |
| 3 | multi-user.target | 字符界面的完整多用户模式,大多数服务器主机运行在此级别 |
| 4 | multi-user.target | 用户定义/域特定运行级别。默认等同于3 |
| 5 | graphical.target | 图形界面的多用户模式,提供了图形桌面操作环境 |
| 6 | reboot.target | 重新启动,使用该级别时将会重启主机 |
0关机 ; 1 急救模式 ; 2、3、4字符界面 ; 5 图形界面 ; 6 重启 。常用和
systemctl get-default #获得当前的运行级别
systemctl set-default [unit.target] #设置指定的target为默认运行级别
systemctl isolate [unit.target] #在不重启的情况下,切换到指定的运行级别
3. 系统初始化进程(init和Systemd介绍)
3.1 init进程
- 由Linux内核加载运行/sbin/init 程序;
- init进程是系统中第一个进程;
- init进程的PID(进程标记)号永远为1。
3.2 Systemd进程
- Systemd是Linux操作系统中的一种init软件;
- CentOS7中采用全新的Systemd启动方式,取代传统的SysVinit;
- CentOS7中运行的第一个init进程是/lib/systemd/systemd
使用 pstree 命令可以查看系统中的所有进程,可以看出systemd是所有进程的父进程。
3.3 init和Systemd区别
先启动systemd 或init ,再启动其他程序
- init:启动其他程序时是串行,12345678排队启动
- systemd:启动其他程序时是并行,12345678同时启动
传统init依赖于串行执行Shell 脚本启动服务,导致效率低下,系统启动速度较慢。
systemd能够将更多的服务进程并行启动,并且具有提供按需启动服务的能力,使得启动更少进程,从而提高系统启动速度。
二、解决系统启动中的故障
1. 修复mbr扇区故障
1.1 故障原因和解决思路
故障原因:
- 病毒、木马的等造成的破坏;
- 不正确的分区操作、磁盘读写误操作等。
故障现象:
- 找不到引导程序,启动中断;
- 无法加载操作系统,开机后黑屏。
解决思路:
- 提前添加一块新硬盘;
- 提前做好备份文件(将MBR扇区备份到另一块硬盘上);
- 以安装光盘引导进入急救模式;
- 从备份文件中恢复。
1.2 实验 ( MBR扇区备份 )
备份命令:
mkdir /bak
mount /dev/sdb1 /bak
dd if=/dev/sda of=/bak/mbr.bak count=512 bs=1 #备份sda系统盘
dd 命令可以对硬盘空间进行备份
dd 命令格式:dd if=[输入文件] of=[输出文件] [选项]
选项:
bs:指定数据块的大小,也就是定义一次性读取或写入多少字节。模式数据块大小是 512 字节;
count:复制多少次;
skip:从输入文件开头跳过 x个块后再开始复制;
seek:从输出文件开头跳过 x 个块后再开始复制;
conv=标志:依据标志转换文件。
在光盘中恢复MBR扇区命令:
sh-4.2# mkdir /bak
sh-4.2# mount /dev/sdb1 /bak
sh-4.2# dd if=/bak/mbr.bak of=/dev/sda count=512 bs=1
实验步骤
- 提前添加一块新硬盘,将MBR扇区备份到新硬盘中。
提前添加好新硬/dev/sdb,设置分区sdb1,将sdb1挂载到/mnt目录下,之后将/dev/sda的MBR扇区备份到/mnt目录下。
- 破坏MBR分区表,模拟扇区故障.
先查看正常的MBR扇区,之后使用空字符串覆盖掉MBR扇区内容(即/dev/sda的前512字节),再查看破坏后的MBR扇区。最后进行重启,查看能否正常启动。
- 重启观察故障情况。因为第一块硬盘的引导程序被破坏,系统自动改用光驱启动。选择Troubleshooting,之后选择rescue mode(急救模式),使用备份文件恢复MBR扇区。
重启发生故障,无法正常启动。当出现安装向导界面时,选择“Troubleshooting”选项
再选择“Rescue a CentOS Linux system”选项,进入急救模式
选择“1”选择 Continue并按 Enter 键继续
再次按 Enter 键后将进入带“sh-4.2#”提示符的 Bash Shell 环境
2. 修复grub引导故障
2.1 故障原因和解决思路
故障原因:
- MBR中的GRUB引导程序遭到破坏
- grub.cfg 文件丢失、引导配置有误
故障现象:
- 系统引导停滞,显示“grup>” 提示符
解决思路:
- 尝试手动输入引导命令(笨拙繁琐,不建议使用)
- 提前备份文件,恢复MBR扇区中的grub引导程序
- 进入急救模式,重写或者从备份中恢复grub.cfg 文件
2.2 实验( 重建grub.cfg 文件 )
重建GRUB菜单配置文件命令
chroot /mnt/sysimage
#进入急救模式后,加载光盘镜像,切换到光驱系统的根环境
grub2-install /dev/sda
#重新将GRUB引导程序安装到第一块硬盘(dev/sda)的MBR扇区
grub2-mkconfig -o /boot/grub2/grub.cfg
#重新构建GRUB菜单配置文件
实验步骤
- 模拟丢失grub.cfg文件
- 重启观察故障。之后重新启动,在读条界面按 Esc 键(只有0.5秒时间)进入启动菜单,改用光驱启动,引导界面进入急救模式,重建GRUB菜单配置文件。
故障现象:出现 gurb> 提示符
重新启动,在读条界面按 Esc 键(只有0.5秒时间)进入启动菜单,改用光驱启动
引导界面进入急救模式
重建GRUB菜单配置文件
3. 忘记root密码
3.1 故障原因和解决思路
故障原因:
- 遗忘root用户的密码
故障现象:
- 无法进行需要root权限的管理操作;
- 若没有其他可用账号,将无法登陆操作系统。
解决思路
- 进入急救模式,重设密码。
3.2 实验
情况一:
有光驱的情况下,借助光驱里面的操作系统来修改密码,使用光驱启动,进入急救模式。使用root环境,passwd修改root用户密码。
命令:
chroot /mnt/sysimage
#进入急救模式后,更改环境
passwd
#修改密码
情况二:
没有光盘的情况下,启动时按任意键暂停启动,之后按e键进入编辑模式。
将光标移动到 linux 开始的行,添加内核参数 rd.break,之后按ctrl-x启动进入单用户模式。
启动时任意键暂停启动
按e键进入编辑模式
将光标移动linux 开始的行,添加内核参数 rd.break
按ctrl-x启动
mount –o remount,rw /sysroot
chroot /sysroot
passwd root
#如果SELinux是启用的,才需要执行下面操作,如没有启动,不需要执行
touch /.autorelabel
exit
reboot
:给grub添加密码,增强安全性
[root@localhost ~]# grub2-setpassword #直接设置密码
三、 服务
所谓“服务”这类程序,就是要为其他程序或者是用户提供服务的,所以这些服务进程要在系统后台始终处于运行状态,以随时等待被调用。Linux系统中服务名称的最后一般都带有字母d,如 vsftpd,httpd、sshd等,d是英文单词daemon的缩写,表示这是一种守护进程。
按照所服务的对象不同,Linux系统中的服务分为对内和对外两种类型。对内的服务面向的是本地计算机,主要作用是维持本地计算机的正常运行;对外的服务面向的是网络上的用户,主要作用是为网络中的用户提供各种功能。
CentOS系统主要就是用来搭建各种网络服务器,而绝大多数的服务器程序都是以服务的状态在系统中运行的,所以我们所要研究的主要是那些对外提供功能的网络服务。通常情况下,运行了某种对外的服务后,都会在系统中开放相应的端口,如运行了httpd服务后会开放TCP80端口,运行了FTP服务后会开放TCP20,21端口等。关于如何对某种具体的服务进行配置和管理,在这里将要介绍的是如何启动、停止、重启服务等通用操作,而所有这些操作都离不开系统初始化进程systemd。
- 本地服务程序,管理本机
- 网络服务程序,接待网络上的客户
1. systemd服务
systemd:管家式的程序,管理系统中其他程序
为了方便管理将系统中的程序按照一定的规则进行管理
1.1 systemd单元类型
在Systemd中不同类型的systemd对象被统一称为单元(unit),是让系统知道该如何进行操作和管理资源的主要对象,所以systemd有许多单元类型。 Systemd单元文件最初默认存放在/lib/systemd/system目录中,每当安装新的软件都会自动在这个目录中添加一个配置文件。通过配置文件进行标识和配置不同单元;文件中主要包含了系统服务、监听。
| 单元类型 | 护展名 | 说明 |
|---|---|---|
| Service | .service | 描述一个系统服务软件 |
| Socket | .socket | 描述一个进程间通信的套接字 |
| Device | .device | 描述一个内核识别的设备文件 |
| Mount | .mount | 描述一个文件系统的挂载点 |
| Automoun | .automount | 描述一个文件系统的自动挂载点 |
| Swap | .swap | 描述一个内存交换设备或目录 |
| Timer | .timer | 描述一个定时器(用于实现类似cron的调度任务) |
| Path | .path | 描述一个文件系统中文件或目录(path 路径) |
| Snapshot | .snapshot | 用于保存一个systemd的状态(snapshot 快照) |
| Scope | .scope | 使用systemd的总线接口以编程的方式创建外部进程 |
| Slice | .slice | 描述居于Cgroup的一组通过层次组织的管理系统进程 |
| Target | .target | 描述一组systemd的单元(target 目标) |
systemctl 命令用于管理各种类型的systemd单元,可以使用 “systemctl -t help” 命令来查询systemd支持的单元类型。
1.2 系统服务控制 systemctl
systemd 进行管理的时候使用 systemctl命令
:systemctl 控制类型 服务名称
| 命令 | 效果 |
|---|---|
| systemctl start 服务名 | 开启服务 |
| systemctl stop 服务名 | 关闭服务 |
| systemctl status 服务名 | 查看服务状态 |
| systemctl restart 服务名 | 重启服务 |
| systemctl reload 服务名 | 重新加载服务,不影响客户使用 |
| systemctl enable 服务名 | 开机自启 |
| systemctl disable 服务名 | 关闭开机自启 |
| systemctl enable-now 服务名 | 开机自启,并立即启动 |
| systemctl disable-now 服务名 | 关闭开机自启,并立即关闭 |
1.3 service unit文件格式
1.3.1 unit 格式说明
- 以 “#” 开头的行后面的内容会被认为是注释
- 相关布尔值,1、yes、on、true 都是开启,0、no、off、false 都是关闭
- 时间单位默认是秒,所以要用毫秒(ms)分钟(m)等须显式说明
1.3.2 service unit file文件组成部分
- [Unit]:定义与Unit类型无关的通用选项;用于提供unit的描述信息、unit行为及依赖关系等
- [Service]:与特定类型相关的专用选项;此处为Service类型
- [Install]:定义由“systemctl enable”以及"systemctl disable“命令在实现服务启用或禁用时用到的一些选项
Unit段的常用选项:
- :描述信息
- After:定义unit的启动次序,表示当前unit应该晚于哪些unit启动,其功能与Before相反
- Requires:依赖到的其它units,强依赖,被依赖的units无法激活时,当前unit也无法激活
- Wants:依赖到的其它units,弱依赖
- Conflicts:定义units间的冲突关系
Service段的常用选项:
- Type:定义影响ExecStart及相关参数的功能的unit进程启动类型
simple:默认值,这个daemon主要由ExecStart接的指令串来启动,启动后常驻于内存中
forking:由ExecStart启动的程序透过spawns延伸出其他子程序来作为此daemon的主要服务。原生父程序在启动结束后就会终止
notify:在启动完成后会发送一个通知消息。还需要配合 NotifyAccess 来让 Systemd 接收消息
- EnvironmentFile:环境配置文件
- :指明启动unit要运行命令或脚本的绝对路径
- ExecStartPre: ExecStart前运行
- ExecStartPost: ExecStart后运行
- :指明停止unit要运行的命令或脚本
- Restart:当设定Restart=1 时,则当次daemon服务意外终止后,会再次自动启动此服务
- RestartSec: 设置在重启服务( Restart= )前暂停多长时间。 默认值是100毫秒(100ms)。 如果未指
- 定时间单位,那么将视为以秒为单位。 例如设为"20"等价于设为"20s"。
- PrivateTmp:设定为yes时,会在生成/tmp/systemd-private-UUID-NAME.service-XXXXX/tmp/目录
Install段的常用选项:
- :被哪些units所依赖,弱依赖
- Alias:别名,可使用systemctl command Alias.service
- RequiredBy:被哪些units所依赖,强依赖
- Also:安装本服务的时候还要安装别的相关服务
1.4 用systemd管理 写service文件
以nginx为例:
mkdir /data #新建/data文件夹
cd /data #切换到data下
wget http://nginx.org/download/nginx-1.18.0.tar.gz #官网下载源码包
tar xf nginx-1.18.0.tar.gz #解压
yum -y install pcre-devel zlib-devel gcc gcc-c++ make #安装依赖关系
cd nginx-1.18.0/ #切换到nginx中
./configure --prefix=/apps/nginx #检测环境,指定安装目录为/apps/nginx
make #编译
make install #将软件安装进指定的路径
ln -s /apps/nginx/sbin/nginx /usr/local/bin #建立软连接,可以补全nginx
vim /lib/systemd/system/nginx.service #手写.service文件
[Unit]
Description=The nginx HTTP and reverse proxy server
[Service]
Type=forking
PIDFile=/apps/nginx/logs/nginx.pid #pid文件位置
ExecStart=/apps/nginx/sbin/nginx #指明启动unit要运行命令的绝对路径
ExecReload=/apps/nginx/sbin/nginx -s reload
ExecStop=/usr/bin/kill -s TERM ${MAINPID} #指明关闭unit要运行命令的绝对路径
[Install]
WantedBy=multi-user.target #被字符界面所依赖
systemctl daemon-reload #重新加载配置
systemctl start nginx #开启服务
systemctl status nginx #查看服务状态
systemctl stop nginx #开启服务
systemctl status nginx #查看服务状态
2. init服务
init (daemon守护进程)想要管理其他服务, 需要手写脚本 , 不能复制粘贴
(了解,在centos6 上用的较多)
以nginx为例:
wget http://nginx.org/download/nginx-1.18.0.tar.gz
tar xf nginx-1.18.0.tar.gz
yum -y install pcre-devel zlib-devel gcc gcc-c++ make
cd nginx-1.18.0/
./configure --prefix=/usr/local/nginx
make -j2 && make install
ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/
#这步可以不做,做软链接,让系统可以直接使用
cd /etc/init.d/
vim /etc/init.d/nginx #写一个脚本
#!/bin/bash
#chkconfig: - 99 20 # - 代表全部启动;第99个启动;第20个关闭
#description:Nginx Service Control Script
PROG="/usr/local/nginx/sbin/nginx" #主程序的绝对路径
PIDF="/usr/local/nginx/logs/nginx.pid" #安装好nginx软件后并且启动后,会自动将自己的pid号存到该文件中
case "$1" in
start) $PROG
;;
stop)
kill -s QUIT $(cat $PIDF) # $( ) 调用命令执行的结果
;;
restart)
$0 stop $0 start
;;
reload)
kill -s HUP $(cat $PIDF) #kill 发信号
;;
*) echo "Usage: $0 {start|stop|restart|reload}"
exit 1
esac
exit 0
chmod +x /etc/init.d/nginx
#给脚本加上权限
ss -ntap |grep nginx
#查看服务有没有启动
chkconfig --add nginx
#将服务加入 init
chkconfig --list nginx
#查看服务
chkconfig --level 35 nginx on
#开启3和5自动开启
补充: 怎么知道nginx.pid文件是否存在呢?使用 [ ] 命令判断一个文件是否存在
chkconfig
- 在centos6 中,init 进行管理的时候使用 chkconfig 命令
- 在centos7 中,systemd 进行管理的时候使用 systemctl命令
centos7上也支持 chkconfig ,但是不推荐使用
命令格式:
chkconfig --list [服务名称] #显示所有运行级系统服务的运行状态信息(on或off)
chkconfig --add 服务名称 #增加一项新的服务
chkconfig --level 级别 服务名称 on/off
例如
chkconfig --list nginx #查看服务
chkconfig --add httpd #增加httpd服务
chkconfig --level 35 httpd on #设置nginx在运行级别为3、5的情况下都是on(开启)的状态
3. Linux系统的运行级别
1. 查看运行级别
- runlevel命令
runlevel只能查看切换运行级别与当前运行级别
[root@localhost ~]# runlevel //查看切换运行级别与当前运行级别
N 5
#N:表示前一次没有切换过运行级别
#5:当前运行级别5,处于图像界面的多用户模式
- systemctl工具
systemctl能查看默认的运行级别
[root@localhost ~]# systemctl get-default //查看默认的运行级别
graphical.target //默认运行级别为图形界面
2. 临时切换运行级别
- init命令
init的命令参数是运行级别所对应的数字
init 0 //关机
init 1 //切换到单用户模式(single,维护模式)
init 3 //切换到字符界面的多用户模式
init 5 //切换到图形界面的多用户模式
init 6 //重启
- systemctl工具
systemctl的命令参数是具体的target
systemctl [command] [unit.target]
systemctl get-default #获得当前的运行级别
systemctl set-default [unit.target] #设置指定的target为默认运行级别
systemctl isolate [unit.target] #在不重启的情况下,切换到指定的运行级别
systemctl isolate poweroff.target //关机
systemctl isolate rescue.target //切换到单用户模式(single,维护模式)
systemctl isolate multi-user.target //切换到字符界面的多用户模式
systemctl isolate graphical.target //切换到图形界面的多用户模
systemctl isolate reboot.target //重启
临时切换运行级别,使用 init 命令更为方便
3. 设置永久运行级别
使用 systemctl set-default 命令
[root@localhost ~]# systemctl get-default //查看当前默认运行级别,为图形界面
graphical.target
[root@localhost ~]# systemctl set-default multi-user.target //将默认运行级别修改为字符界面
Removed symlink /etc/systemd/system/default.target.
Created symlink from /etc/systemd/system/default.target to /usr/lib/systemd/system/multi-user.target.
[root@localhost ~]# systemctl get-default //查看修改后的默认运行级别,为字符界面
multi-user.target