Linux启动流程和内核管理
CentOS 6 启动流程
-
加载BIOS的硬件信息,获取第一个启动设备
-
读取第一个启动设备MBR的引导加载程序(grub)的启动信息
-
加载核心操作系统的核心信息,核心开始解压缩,并尝试驱动所有的硬件设备
-
核心执行init程序,并获取默认的运行信息
-
init程序执行/etc/rc.d/rc.sysinit文件,重新挂载根文件系统
-
启动核心的外挂模块
-
init执行运行的各个批处理文件(scripts)
-
init执行/etc/rc.d/rc.local
-
执行/bin/login程序,等待用户登录
-
登录之后开始以Shell控制主机
硬件启动POST
BIOS
Basic Input and Output System(基本输入输出系统),保存着有关计算机系统最重要的基本输入输出 程序,系统信息设置,开机加电自检程序和系统启动自举程序等。
BIOS 就是一个程序,其代码存储在主板的一颗ROM存储芯片上,ROM是只能读不能写的,这颗芯片上 的BIOS程序,在主板出厂的时候,己经固化好了,所以不管断不断电,这个BIOS程序都会一直存储在这 颗芯片上。
当我们修改了BIOS里面的某些设置时,这个修改的数据是存储在另外一颗RAM存储芯片上,RAM掉电后 数据就会消失,所以主板上有一颗纽扣电池来给这个RAM供电,当这颗纽扣电池没电了,BIOS里面的设 置项,就又恢复成出厂设置了。
POST
Power-On-Self-Test (加电自检),是BIOS程序中的一个主要功能,负责完成对CPU、主板、内存、硬 盘子系统、显示子系统、串并行接口、键盘等硬件情况的检测。
ROM
Read-Only Memory (只读存储),该存储器上的数据只能读出,不能写入,其存储的数据一般在硬件 出厂时就写入固定下来了,所以即使切断电源,数据也不会丢失,所以又称为固定存储器。
RAM
Random Access Memory (随机存取存),这里的随机取存,是指通电后,随时可在任意位置单元存 取数据信息,不过断电后内部信息也随之消失。
所以 对于一台计算机来讲,通电后第一件事件就是运行BIOS程序,BIOS程序最先做的,就是对硬件执行 POST(加电自检),如果硬件自检不通过,会显示相应的错误,还会有相应的蜂鸣音。
启动加载器 bootloader
bootloader 基本概念
Bootloader
引导加载器,引导程序。
是底层硬件与上层应用软件(操作系统)之间的一个中间接口软件。
它不是BIOS中的功能,也不是操作系统中的功能,它是一个独立的软件,运行在BIOS之后,操作系统启动之前。
它的主要作用就是引导操作系统启动。
Bootloader 是一个独立软件,可以单独安装,
但在一般情况下,安装操作系统时,也会一起安装Bootloader程序
不同的操作系统,会安装不同的Bootloader程序
WIndows中的Bootloader
ntloader 仅用来启动OS
Linux中的Bootloader
功能丰富,提供菜单,允许用户选择要启动系统或不同的内核版本;把用户选定的内核装载到内存中的 特定空间中,解压、展开,并把系统控制权移交给内核
LILO:LInux LOader,早期的bootloader,功能单一
GRUB:GRand Unified Bootloader,CentOS 5,6 GRUB 0.97(GRUB Legacy), CentOS 7 以后使 用 GRUB 2.02
系统的启动引导方式有两种,分别是BIOS模式和UEFI模式:
在BIOS模式下,Bootloader第一阶段的程序(代码)存储在硬盘0磁道0扇区的前446个字节的空间内,由 第一阶段的程序来引导第二阶段的bootloader程序,像ntloader,LILO,GRUB等都是采用这种分段执 行的方式。
在UEFI模式下,直接由EFI系统分区中的 .efi 引导程序来引导操作系统。
grub 功能和组成
GRUB 启动阶段
阶段 | 阶段顺序 | 存储位置和功能 |
---|---|---|
primary boot loader | 1st stage | 存储在0磁道0扇区的前446字节空间内 |
primary boot loader | 1.5 stage | 1扇区到2047扇区,存储2阶段的文件系统驱动,保证2nd中 的文件可读 |
secondary boot loader | 2 stage | /boot/grub/grub.conf |
grub 配置文件
[root@c6 ~]# ll /etc/grub.conf
lrwxrwxrwx. 1 root root 22 Aug 29 05:50 /etc/grub.conf -> ../boot/grub/grub.conf
[root@c6 ~]# cat /boot/grub/grub.conf
# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE: You have a /boot partition. This means that
# all kernel and initrd paths are relative to /boot/, eg.
# root (hd0,0)
# kernel /vmlinuz-version ro root=/dev/mapper/vg_c6-lv_root
# initrd /initrd-[generic-]version.img
#boot=/dev/sda
default=0
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title CentOS (2.6.32-71.el6.x86_64)root (hd0,0)kernel /vmlinuz-2.6.32-71.el6.x86_64 ro root=/dev/mapper/vg_c6-lv_root
rd_LVM_LV=vg_c6/lv_root rd_LVM_LV=vg_c6/lv_swap rd_NO_LUKS rd_NO_MD rd_NO_DM
LANG=en_US.UTF-8 SYSFONT=latarcyrheb-sun16 KEYBOARDTYPE=pc KEYTABLE=us
crashkernel=auto rhgb quietinitrd /initramfs-2.6.32-71.el6.x86_64.img
主要配置项说明
选项 | 值 | 说明 |
---|---|---|
default | 0 | 默认使用哪个系统启动,0表示第一个 |
timeout | 5 | 启动界面项选择项停留时长 |
splashimage | (hd0,0)/grub/splash.xpm.gz | 背景图片,可自定义路径和文件 |
password | [--md5|encrypt] STRING | 启动菜单编辑认证 |
hiddenmenu | 表示默认隐藏选择菜单 | |
title | CentOS (2.6.32- 71.el6.x86_64) | 菜单选择的标题,一个title表示一个系统,一 台机可以有多个系统 |
root (hd0,0) | /boot 所在的设备和分区,hd0,0表示第一块 磁盘第一个分区 | |
kernel /vmlinuz-2.6.32- 71.el6.x86_64 | 内核文件路径,以/boot为根目录 | |
root=/dev/mapper/vg_c6- lv_root | 操作系统根目录挂载设备 | |
initrd /initramfs-2.6.32- 71.el6.x86_64.img | 临时根系统,包含驱动,常用工具等 | |
password [--md5 encrypt] STRING | 启动选定的内核或操作系统时进行认证 |
init进程
init进程是一个由内核启动的用户级进程。
内核启动(己被载入内存,开始运行,并己经初始化了所有设备驱动和数据结构等)之后,就通过启动 一个用户级的程序 /sbin/init来完成引导进程。
/sbin/init 程序是内核启动之后的第一个进程,也是进程树中的树根,所以其进程ID始终为1 。
但是这里有一个问题
/sbin/init 程序的功能之一就是要挂载整个根文件系统, /sbin/init 这个程序的可执行文件,它自 己也是在根文件系统里面,
也就是说,得先运行 /sbin/init 程序才有文件目录结构树,但是得先有目录结构,才能通过 /sbin/init 这个路径找到可执行文件
initrd机制
initramfs:(init ram filesystem) 初始 ram 文件系统
是在内核启动的早期提供一个用户态环境,用于完成在内核启动阶段不易完成的工作
通过此系统先形成一个精简版的linux系统,里面包含常用的文件系统的驱动,以及常用的工具和命令, 然后再挂载真正的根文件系统,再定位到 /sbin/init 程序,从而完在真正的启动。
grub 管理
启动界面的grub管理
该界面的默认项由 /boot/grub/grub.conf 中的配置项决定,用户可在此界面输入命令进行操作。
选择键 | 作用 |
---|---|
上下方向键 | 选择不同的操作系统启动 |
ESC键 | 返回主界面 |
a | 修改内核参数 |
c | 进入grub交互式界面 |
e | 修改当前选中系统的启动参数 |
p | 密码校验 |
e --> b | 启动系统 |
e --> e | 修改选中项 |
e --> o | 添加新行 |
e --> d | 删除行 |
grub 修复
删除整个boot目录下的所有文件
[root@c6 ~]# ls /boot/
config-2.6.32-71.el6.x86_64 initramfs-2.6.32-71.el6.x86_64.img System.map2.6.32-71.el6.x86_64
efi lost+found vmlinuz-2.6.32-
71.el6.x86_64
grub symvers-2.6.32-71.el6.x86_64.gz
#删除
[root@c6 ~]# rm -rf /boot/*
[root@c6 ~]# ls /boot/
重启,从光盘启动,进入救援模式
选择shell
执行下列命令
chroot /mnt/sysimage/
grub-install /dev/sda
mount /dev/sr0 /mnt
rpm -ivh /mnt/Packages/kernel-2.6.32-71.el6.x86.rpm --force
vim /boot/grub/grub.conf
default=0
timeout=5
hiddenmenu
title CentOS6root (hd0,0)kernel /vmlinuz-2.6.32-71.el6.x86_64 ro root=/dev/mapper/vg_c6-lv_root initrd /initramfs-2.6.32-71.el6.x86_64.img
sync
sync
exit
exit
再次重启,硬盘启动即可
grub修复总结
阶段:第1阶段
原因:磁盘分区上的第一阶段二进制数数据被破坏
修复:光盘启动,进救援模式,重装grub 即可
chroot /mnt/sysimage/
grub-install /dev/sda
sync
sync
exit
exit
阶段:第1.5阶段
原因:磁盘分区上的第1.5阶段二进制数数据被破坏
修复:同上
阶段:第2阶段
原因: /boot/grub/ 目录内的文件丢失,或 /boot/ 目录下的文件丢失
修复:光盘启动,进救援模式,重装grub,重装内核,手写 /boot/grub/grub.conf ,然后重启
chroot /mnt/sysimage/
grub-install /dev/sda
mount /dev/sr0 /mnt
rpm -ivh /mnt/Packages/kernel-2.6.32-71.el6.x86.rpm --forcevim /boot/grub/grub.conf
default=0
timeout=5
hiddenmenu
title CentOS6root (hd0,0)kernel /vmlinuz-2.6.32-71.el6.x86_64 ro root=/dev/mapper/vg_c6-lv_root initrd /initramfs-2.6.32-71.el6.x86_64.imgsync
sync
exit
exit
grub 安装
centos6中的 grub 有两种安装方式,分别是 grub-install 命令和 grub交互式命令
grub-install 安装grub stage1和stage1_5到/dev/DISK磁盘上,并复制GRUB相关文件到 DIR/boot目录 下
grub-install --root-directory=DIR /dev/DISK
grub命令
[root@c6 ~]# grub
grub> root (hd0,0)
grub> setup (hd0)
grub> quit
grub常用命令
help #获取帮助列表
help KEYWORD #获取指定内容帮助
root (hd#,#) #指定操作系统所在的设备和分区
kernel /PATH/TO/KERNEL_FILE #指定kernel文件位置,后面可以加参数
initrd /PATH/TO/INITRAMFS_FILE #设定为选定的内核提供额外文件的ramdisk
boot #使用选中的内核启动
查看当前启动内核的启动时的参数
[root@c6 ~]# cat /proc/cmdline
ro root=/dev/mapper/vg_c6-lv_root
手动在grub命令行下指定内核并启动
grub> root (hd#,#)
grub> kernel /vmlinuz-VERSION-RELEASE ro root=/dev/DEVICE
grub> initrd /initramfs-VERSION-RELEASE.img
grub> boot
grub识别硬盘的方式
(hd0,0) #第一块硬盘第一个分区hd0 #磁盘编号,用数字表示, 从0开始编号
0 #分区编号,用数字表示, 从0开始编号
grub 安全
破解centos6 中的 root口令
-
编辑grub菜单(选定要编辑的title,而后使用a 或 e 命令)
-
在选定的kernel后附加参数 1(s|S|single),此参数是用来进入单用户模式
-
在kernel所在行,敲 b 键,以此配置启动,即可无密码以root身份进入系统
设置grub密码,防止破解系统root密码
grub 密码生成工具
grub-md5-crypt
grub-crypt#查看grub工具
[root@c6 ~]# grub
grub grubby grub-install grub-md5-crypt grub-terminfo
#使用md5工具生成密文
[root@c6 ~]# grub-md5-crypt
Password:
Retype password:
$1$B0do8$z5jKhXah4sInKxPGQRQWE0
[root@c6 ~]#
[root@c6 ~]# vim /etc/grub.conf
default=0
timeout=5
password --md5 $1$B0do8$z5jKhXah4sInKxPGQRQWE0
title Centos6root (hd0,0)kernel /vmlinuz-2.6.32-71.el6.x86_64 ro root=/dev/mapper/vg_c6-lv_rootinitrd /initramfs-2.6.32-71.el6.x86_64.img
想再次编辑grub,就需要密码认证
生成grub启动背景图片
[root@c6 ~]# convert -resize 640x480 -colors 14 winner.png splash.xpm
[root@c6 ~]# more splash.xpm
#生成splash.xpm.gz
[root@c6 ~]# gzip splash.xpm
[root@c6 ~]# mv splash.xpm.gz /boot/grub
加载 kernel
kernel 自身初始化过程
-
探测可识别到的所有硬件设备
-
加载硬件驱动程序(借助于ramdisk加载驱动)
-
以只读方式挂载根文件系统
-
运行用户空间的第一个应用程序:/sbin/init
Linux内核特点:
-
支持模块化:.ko(内核对象),如:文件系统,硬件驱动,网络协议等
-
支持内核模块的动态装载和卸载
内核组成部分:
-
核心文件:/boot/vmlinuz-VERSION-release
ramdisk:辅助的伪根系统,加载相应的硬件驱动,ramdisk --> ramfs 提高速度
CentOS 5 /boot/initrd-VERSION-release.img
CentOS 6 以后版本 /boot/initramfs-VERSION-release.img
-
模块文件:/lib/modules/VERSION-release
误删除内核文件/boot/vmlinuz-2.6.32-754.el6.x86_64无法启动,故障恢复
[root@centos6 ~]#rm -f /boot/vmlinuz-2.6.32-754.el6.x86_64
[root@centos6 ~]#reboot
#进入rescue模式
#chroot /mnt/sysimage
#mount /dev/sr0 /mnt/
#cp /mnt/isolinux/vmlinuz /boot/vmlinuz-2.6.32-754.el6.x86_64
#sync
#exit
#reboot
ramdisk文件的制作:
mkinitrd命令
mkinitrd /boot/initramfs-$(uname -r).img $(uname -r)
dracut命令
dracut /boot/initramfs-$(uname -r).img $(uname -r)
误删除/boot/initramfs-2.6.32-754.el6.x86_64.img无法启动,故障恢复
[root@centos6 ~]#rm -f /boot/initramfs-2.6.32-754.el6.x86_64.img
[root@centos6 ~]#reboot
#进入rescue模式
#chroot /mnt/sysimage
#mkinitrd /boot/initramfs-$(uname -r).img $(uname -r)
#sync
#exit
#exit
#reboot
init初始化
/sbin/init 程序是内核启动之后的第一个进程,也是进程树中的树根,所以其进程ID始终为1
init程序的类型:
适用系统 | 配置文件 | |
---|---|---|
Sysvinit | CentOS5以及之前 | /etc/inittab |
upstart | CentOS6 | /etc/initab,/etc/init/*.conf |
CentOS7以及之后 | /usr/lib/systemd/systemd |
CentOS6中的init
[root@c6 ~]# which init
/sbin/init[root@c6 ~]# rpm -qf /sbin/init
upstart-0.6.5-6.1.el6.x86_64
运行级别
运行级别:为系统运行或维护等目的而设定;0-6:7个级别,一般使用3, 5做为默认级别
运行级别 | 说明 |
---|---|
0 | 关机 |
1 | 单用户模式(root自动登录),single,维护模式 |
2 | 多用户模式,启动网络功能,但不会启动NFS;维护模式 |
3 | 多用户模式,正常模式;文本界面 |
4 | 预留级别;可同3级别 |
5 | 多用户模式,正常模式;图形界面 |
6 | 重启 |
查看现在使用的默认级别
[root@c6 ~]# cat /etc/inittab
#
#
# 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:5:initdefault:
切换级别
init N
相关配置文件
CentOS 6 init程序为 upstart, 其配置文件/etc/inittab, /etc/init/*.conf,配置文件的语法遵循 upstart配 置文件语法格式
/etc/inittab #设置系统默认的运行级别
/etc/init/control-alt-delete.conf
/etc/init/tty.conf
/etc/init/start-ttys.conf
/etc/init/rc.conf
/etc/init/prefdm.conf
......
初始化脚本 sysinit
系统初始化脚本功能
-
设置主机名
-
设置欢迎信息
-
激活udev和selinux
-
挂载/etc/fstab文件中定义的文件系统
-
检测根文件系统,并以读写方式重新挂载根文件系统
-
设置系统时钟
-
激活swap设备
-
根据/etc/sysctl.conf文件设置内核参数
-
激活lvm及software raid设备
-
加载额外设备的驱动程序
-
清理操作
服务管理
/etc/rc.d/rc 控制服务脚本的开机自动运行
K(kill) 开头表示关闭服务,K后面的数字表示运行顺序,数字越小,越先运行,表示越先被停止,这类服 务通常是要依赖其它服务
S(start) 开头表示开启服务,S后面的数字表示运行顺序,数字越小,越先运行,表示越先被启动,这类 服务通常是要被其它服务依赖
chkconfig 命令管理服务
chkconfig [--list] [--type <type>] [name]
chkconfig --add <name>
chkconfig --del <name>
chkconfig --override <name>
chkconfig [--level <levels>] [--type <type>] <name>
<on|off|reset|resetpriorities> #--level 默认为2,3,4,5#范例:
#查看所有服务在不同运行级别下的停启情况
[root@c6 ~]# chkconfig --list
NetworkManager 0:off 1:off 2:on 3:on 4:on 5:on 6:off
abrtd 0:off 1:off 2:off 3:on 4:off 5:on 6:off
acpid 0:off 1:off 2:on 3:on 4:on 5:on 6:off
atd 0:off 1:off 2:off 3:on 4:on 5:on 6:off
......#查看指定服务
[root@c6 ~]# chkconfig --list crond
crond 0:off 1:off 2:on 3:on 4:on 5:on 6:off#查看链接
[root@c6 ~]# ll /etc/rc3.d/*cron*
lrwxrwxrwx. 1 root root 15 Aug 29 05:40 /etc/rc3.d/S90crond -> ../init.d/crond#修改服务
[root@c6 ~]# chkconfig --level 3 crond off#再次查看,变成了K开头
[root@c6 ~]# ll /etc/rc3.d/*cron*
lrwxrwxrwx. 1 root root 15 Aug 30 14:49 /etc/rc3.d/K60crond -> ../init.d/crond#crond在3模式下变成了off
[root@c6 ~]# chkconfig --list crond
crond 0:off 1:off 2:on 3:off 4:on 5:on 6:off
服务脚本
服务脚本放在 /etc/init.d/ 目录下,除了 #!/bin/sh 机制外,还要有 chkconfig 和 description 项
#!/bin/bash
#chkconfig: LLLL nn nn #LLLL 表示初始在哪个级别下启动,-表示都不启动,nn表示数字
#description: #描述信息
......#范例:
#Start是S90,Kill是K60, 90/60 是定义在对应的脚本文件中
[root@c6 ~]# ll /etc/rc3.d/*cron*
lrwxrwxrwx. 1 root root 15 Aug 29 05:40 /etc/rc3.d/S90crond -> ../init.d/crond
[root@c6 ~]# ll /etc/rc3.d/*cron*
lrwxrwxrwx. 1 root root 15 Aug 30 14:49 /etc/rc3.d/K60crond -> ../init.d/crond#查看脚本文件
[root@c6 ~]# cat /etc/init.d/crond
#!/bin/sh
#
# crond Start/Stop the cron clock daemon.
#
# chkconfig: 2345 90 60 表示默认
2345是S90, 其它模式是K60
# description: cron is a standard UNIX program that runs user-specified \
# programs at periodic scheduled times. vixie cron adds a \
# number of features to the basic UNIX cron, including better \
# security and more powerful configuration options.
......
自定义服务脚本
#创建服务脚本
[root@c6 ~]# vim /etc/init.d/testsrv
#!/bin/bash# chkconfig: - 96 3
# description: This is test service script. /etc/init.d/functions
start(){[ -e /var/lock/subsys/testsrv ] && exit || touch /var/lock/subsys/testsrvecho $PATHaction "Starting testsrv"sleep 3000 &
}
stop(){[ -e /var/lock/subsys/testsrv ] && rm /var/lock/subsys/testsrv || exitaction "Stopping testsrv"
}
status(){[ -e /var/lock/subsys/testsrv ] && echo "testsrv is running..." || echo
"testsrv is stopped"
}
case $1 instart)start;;stop)stop;;restart)stopstart;;status)status;;*)echo $"Usage $0 {start|stop|status|restart}"exit 2
esac
#加可执行权限
[root@c6 ~]# chmod a+x /etc/init.d/testsrv#添加服务
[root@c6 ~]# chkconfig --add testsrv#查看
[root@c6 ~]# chkconfig --list testsrv
testsrv 0:off 1:off 2:off 3:off 4:off 5:off 6:off#开机启动
[root@c6 ~]# chkconfig testsrv on
[root@c6 ~]# chkconfig --list testsrv
testsrv 0:off 1:off 2:on 3:on 4:on 5:on 6:off#启动
[root@c6 ~]# service testsrv start
/sbin:/usr/sbin:/bin:/usr/bin
Starting testsrv [ OK ]#停止
[root@c6 ~]# service testsrv stop
Stopping testsrv [ OK ]#删除服务
[root@c6 ~]# chkconfig --del testsrv
service 命令手动管理服务
service < option > | --status-all | [ service_name [ command | --full-restart ] ]#示例:
[root@c6 ~]# service crond stop
Stopping crond: [ OK ]
[root@c6 ~]# service crond start
Starting crond: [ OK ]
[root@c6 ~]# service crond startt
Usage: /etc/init.d/crond {start|stop|status|restart|condrestart|tryrestart|reload|force-reload}
[root@c6 ~]# service crond status
crond (pid 1756) is running...
非独立服务
有很多服务不是常用服务,使用频率不高,如果这种服务也加入开机启动,则会消耗服务器资源, 为了平衡资源与服务使用之间的关系,我们可以用一个代理服务来管理这些不常用的服务。
这些被代理的服务就称之为非独立服务
一般用 xinetd 服务来管理非独立服务,默认没有安装xinetd,但当安装非独立服务时,就会安装xinetd 服务
[root@c6 ~]# rpm -qi xinetd
package xinetd is not installed#安装非独立服务telnet-server
[root@c6 ~]# yum install -y telnet-server
[root@c6 ~]# rpm -ql telnet-server
/etc/xinetd.d/telnet
/usr/sbin/in.telnetd
/usr/share/man/man5/issue.net.5.gz
/usr/share/man/man8/in.telnetd.8.gz
/usr/share/man/man8/telnetd.8.gz[root@c6 ~]# rpm -q xinetd
xinetd-2.3.14-29.el6.x86_64
开机启动文件 rc.local
正常级别下,最后启动一个服务S99local没有链接至/etc/rc.d/init.d一个服务脚本,而是指向 了/etc/rc.d/rc.local脚本
不便或不需写为服务脚本放置于/etc/rc.d/init.d/目录,且又想开机时自动运行的命令,可直接放置 于/etc/rc.d/rc.local文件中
/etc/rc.d/rc.local在指定运行级别脚本后运行
注意:默认Ubuntu 无 /etc/rc.local 文件,需要手动创建并添加可执行权限,首行必须有shebang机制
CentOS 6 启动过程总结
POST #加电自检
boot loader #引导启动内核
vmlinux(initrd /initramfs-2.6.32-71.el6.x86_64.img) #临时系统
rootfs #根文件系统
/sbin/init #执行init程序
/etc/inittab #设置默认运行级别
/etc/rc.d/rc.sysinit #运行系统初始脚本完成系统初始化
/etc/rcN.d/KNN #当前级别下需要停止的服务
/etc/rcN.d/SNN #当前级别下需要启动的服务
/etc/rc.d/rc.local #没加服务的自定义开机启动项设置登录终端
systemd 和启动流程
systemd 特性
Systemd:从 CentOS 7 版本之后开始用 systemd 实现init进程,系统启动和服务器守护进程管理器, 负责在系统启动或运行时,激活系统资源,服务器进程和其它进程
Systemd 新特性
-
系统引导时实现服务并行启动
-
按需启动守护进程
-
自动化的服务依赖关系管理
-
同时采用socket式与D-Bus总线式激活服务
-
socket与服务程序分离
-
向后兼容sysv init脚本
-
使用systemctl 命令管理,systemctl命令固定不变,不可扩展,非由systemd启动的服务, systemctl无法与之通信和控制
-
系统状态快照
systemd 中的 unit
unit表示不同类型的systemd对象,通过配置文件进行标识和配置;
文件中主要包含了系统服务、监听socket、保存的系统快照以及其它与init相关的信息
查看Unit类型
#查看unit类型
[root@ubuntu ~]# systemctl -t help
Available unit types:
service
mount
swap
socket
target
device
automount
timer
path
slice
scope
常见Unit类型说明
unit类型 | 后缀 | 作用 |
---|---|---|
service | .service | 定义系统服务 |
socket | .socket | 定义进程间通信用的socket文件,可以延迟启动,按需启动 |
target | .target | 不同服务的集合,用于模拟运行级别 |
device | .device | 用于定义内核识别的设备 |
mount | .mount | 定义文件系统挂载点 |
automount | .automount | 文件系统的自动挂载点 |
swap | .swap | 用于标识swap设备 |
timer | .timer | 用于安排激活另一个单元的计时器 |
path | .path | 用于定义文件系统中的文件或目录,常用于当文件系统变化时, 延迟激活服务,如spool 目录 |
slice | .slice | 通过 Linux 控制组节点 (cgroups) 限制资源 |
scope | .scope | systemd 总线接口的信息,常用于管理外部系统进程 |
unit的配置文件
/usr/lib/systemd/system/ #每个服务最主要的脚本文件目录,类似于之前的/etc/init.d/
/run/systemd/system/ #系统执行过程中所产生的服务脚本,比上面目录优先运行
/etc/systemd/system/ #管理员建立的执行脚本,类似于/etc/rcN.d/Sxx的功能,比上面目录优先运行
范例:列出所有在内存中的单元
#systemctl 或 systemctl list-units
[root@ubuntu ~]# systemctlUNIT LOAD ACTIVE SUB
DESCRIPTION sys-devices-virtual-block-dm\x2d0.device loaded active plugged
/sys/devices/virtual/block>sys-subsystem-net-devices-virbr0.device loaded active plugged
/sys/subsystem/net/devices>-.mount loaded active mounted
Root Mount boot.mount loaded active mounted
/boot dev-mqueue.mount loaded active mounted
POSIX Message Queue File S>home.mount loaded active mounted
/home ......
范例:列出所有己加载到内存的 service
#systemctl list-units --type=service -a 或 systemctl --type=service --all
[root@ubuntu ~]# systemctl list-units --type=service -aUNIT LOAD ACTIVE SUB DESCRIPTIONaccounts-daemon.service loaded active running Accounts Servicealsa-restore.service loaded inactive dead Save/Restore
Sound Card State
● apparmor.service not-found inactive dead apparmor.serviceatd.service loaded active running Job spooling
toolsauth-rpcgss-module.service loaded inactive dead Kernel Module
supporting RPCSEC_GSSavahi-daemon.service loaded active running Avahi mDNS/DNS-SD
Stackblk-availability.service loaded inactive dead Availability of
block devices
● cloud-init-local.service not-found inactive dead cloud-initlocal.service......
字段说明
字段 | 说明 |
---|---|
UNIT | 服务名称 |
LOAD | 加载状态 loaded|not-found|bad-setting|error|masked |
ACTIVE | 服务状态 active|reloading|inactive|failed|activating|deactivating |
SUB | 详细状态,与 LOAD和ACTIVE列有关,具体可执行 systemctl --state=help 查看 |
DESCRIPTION | unit 描述信息 |
service 系统服务管理
systemctl COMMAND name.service [name2.service] ...
常用操作
操作类型 | systemctl 命令 | service 命 令 |
---|---|---|
启动服务 | systemctl start name1.service[name2.service] | service name start |
停止服务 | systemctl stop name.service | service name stop |
重启服务 | systemctl restart name.service | service name restart |
查看状态 | systemctl status name.service | service name status |
禁止服务启动 | systemctl mask name.service | |
恢复可启动 | systemctl unmask name.service | |
当前是否是可启动状态 | systemctl is-active name.service | |
查看service服务脚本内容 | systemctl cat name.service | |
查看所有已经激活的服务 | systemctl list-units--type service | -t service | |
查看所有服务 | systemctl list-units--type service | -t service -all | -a | |
设定服务开机启动 | systemctl enable name.service | chkconfig name on |
设定服务开机禁止启动 | systemctl disable name.service | chkconfig name off |
查看所有服务开机启动状态 | systemctl list-unit-files --type service --all | -a | chkconfig -- list |
查看服务在不同运行级别下的启用禁用 | ls /etc/systemd/system/*.wants/name.service | chkconfig - list name |
查看服务是否开机自启 | systemctl is-enable name.service | |
列出失败的服务 | systemctl --fail --type=service | |
开机启动并立即启动 | systemctl enable --now name.service | |
开机禁用并立即禁用 | systemctl disable --now name.service | |
查看服务依赖 | systemctl list-dependencies name.service | |
杀进程 | systemctl kill unitname |
service unit 文件格式
[root@ubuntu ~]# apt install nginx
[root@ubuntu ~]# systemctl cat nginx.service
# /lib/systemd/system/nginx.service
# Stop dance for nginx
# =======================
#
# ExecStop sends SIGSTOP (graceful stop) to the nginx process.
# If, after 5s (--retry QUIT/5) nginx is still running, systemd takes control
# and sends SIGTERM (fast shutdown) to the main process.
# After another 5s (TimeoutStopSec=5), and if nginx is alive, systemd sends
# SIGKILL to all the remaining processes in the process group (KillMode=mixed).
#
# nginx signals reference doc:
# http://nginx.org/en/docs/control.html
#[Unit]
Description=A high performance web server and a reverse proxy server
Documentation=man:nginx(8)
After=network.target nss-lookup.target[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t -q -g 'daemon on; master_process on;'
ExecStart=/usr/sbin/nginx -g 'daemon on; master_process on;'
ExecReload=/usr/sbin/nginx -g 'daemon on; master_process on;' -s reload
ExecStop=-/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile
/run/nginx.pid
TimeoutStopSec=5
KillMode=mixed[Install]
WantedBy=multi-user.target
unit 文件格式说明
-
以 # 开头的行后面的内容会被认为是注释
-
相关布尔值 1,yes,on,true 等可以表示开启,0,no,off,false 等都可以表示关闭
-
时间单位默认是秒,如果要使用其它时间单位,毫秒(ms),分钟(m) 等须显式说明
service unit file文件通常由三部分组成
字段 | 说明 |
---|---|
[Unit] | 定义与Unit类型无关的通用选项;用于提供unit的描述信息、unit行为及依赖关系等 |
[Service] | 与特定类型相关的专用选项;此处为Service类型 |
[Install] | 定义由“systemctl enable”以及"systemctl disable“命令在实现服务启用或禁用时用到 的一些选项 |
[Unit] 字段中的常用选项
字段 | 作用 |
---|---|
Description | 描述信息 |
Documentation | 帮助信息 |
After | 定义unit的启动次序,表示当前unit应该晚于哪些unit启动,其功能与Before 相反 |
Before | 定义unit的启动次序,表示当前unit应该早于哪些unit启动,其功能与After相 反 |
Requires | 依赖到的其它units,强依赖,被依赖的units无法激活时,当前unit也无法激 活 |
Wants | 依赖到的其它units,弱依赖 |
Conflicts | 定义units间的冲突关系 |
[Service] 字段中的常用选项
字段 | 说明 |
---|---|
Type | 定义影响ExecStart及相关参数的功能的unit进程启动类型 |
EnvironmentFile | 环境配置文件 |
PIDFile | 指明生成进程文件路径 |
ExecStartPre | ExecStart前运行,可以有多条 |
ExecStart | 指明启动unit要运行命令或脚本的绝对路径 |
ExecStartPost | ExecStart后运行,可以有多条 |
ExecReload | 指明重新加载unit 配置要运行的命令或脚本 |
ExecStop | 指明停止unit要运行的命令或脚本 |
KillSignal | 以何信号杀死进程,默认SIGTERM |
KillMode | 以何种方式杀死进程control-group |
TimeoutStopSec | 在超过此时间后,如果进程没有被杀死,则继续使用SIGKILL配置或 FinalKillSignal配置停止进程 |
PrivateTmp | 布尔值,true 表示会生成私有的tmp目录,路径是/tmp/systemd-privateUUID-NAME.service-XXXXX/tmp/ |
Restart | 当守护进程意外终止时,是否自动重启 |
RestartSec | 意外终止到自动重启之间的时间间隔,其目的是保证前面的程序彻底退出, 默认值100ms |
Type字段常用值
simple #默认值, 这个daemon主要由ExecStart接的指令串来启动,启动后常驻于内存中
forking #由ExecStart启动的程序透过spawns延伸出其他子程序来作为此daemon的主要服务, 原生父程序在启动结束后就会终止
oneshot #与simple类似, 不过这个程序在工作完毕后就结束了,不会常驻在内存中
dbus #与simple类似,但这个daemon必须要在取得一个D-Bus的名称后, 才会继续运作, 因此通常也要同时设定BusNname
notify #在启动完成后会发送一个通知消息, 还需要配合NotifyAccess来让Systemd 接收消息
idle #与simple类似, 要执行这个daemon必须要所有的工作都顺利执行完毕, 这类daemon通常是开机到最后才执行的服务
[Install] 字段中的常用选项
字段 | 说明 |
---|---|
Alias | 别名,可使用systemctl command Alias.service |
WantedBy | 工作模式,就是在哪种运行级别下 |
Also | 安装本服务的时候还要安装别的相关服务 |
对于新创建的unit文件,或者修改了的unit文件,要通知systemd重载此配置文件,或者选择重启系统
systemctl daemon-reload
init q
运行级别
centOS7开始,使用 target 来定义运行级别
查看所有target
[root@ubuntu ~]# ll /usr/lib/systemd/system/*target
......
......
[root@ubuntu ~]# systemctl list-unit-files --type target --all
......
......
centOS7之后的 runlevel 不再定义在 /etc/inittab 文件中,且 ubuntu 中没有该文件
[root@rocky86 ~]# cat /etc/inittab
# inittab is no longer used.
#
# ADDING CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM.
#
# Ctrl-Alt-Delete is handled by /usr/lib/systemd/system/ctrl-alt-del.target
#
# systemd uses 'targets' instead of runlevels. By default, there are two main
targets:
#
# multi-user.target: analogous to runlevel 3
# graphical.target: analogous to runlevel 5
#
# To view current default target, run:
# systemctl get-default
#
# To set a default target, run:
# systemctl set-default TARGET.target
查看默认启动级别
#相当于查看之前的 /etc/inittab
[root@rocky86 ~]# systemctl get-default
graphical.target
runlevel 和 target 之间的对应关系
运行级别 | target | 指向真实的文件 |
---|---|---|
0 | runlevel0.target | poweroff.target |
1 | runlevel1.target | rescue.target |
2 | runlevel2.target | multi-user.target |
3 | runlevel3.target | multi-user.target |
4 | runlevel4.target | multi-user.target |
5 | runlevel5.target | graphical.target |
6 | runlevel6.target | reboot.target |
#重启对应的target
/usr/lib/systemd/system/ctrl-alt-del.target -> reboot.target#默认target
/usr/lib/systemd/system/default.target -> graphical.target
查看当前运行级别
[root@ubuntu ~]# runlevel
N 5
[root@ubuntu ~]# who -rrun-level 5 2022-09-03 11:21
运行级别切换
#重启, 相录于 init 6
[root@ubuntu ~]# systemctl isolate reboot.target
#同样支持
[root@ubuntu ~]# init 6
#进入默认target
[root@ubuntu ~]# systemctl default
注意:只有/lib/systemd/system/*.target文件中AllowIsolate=yes 才能切换(修改文件需执行systemctl daemon-reload才能生效)
常用模式快捷切换
传统命令init,poweroff,halt,reboot都成为systemctl的软链接
rescue.target 比emergency.target 支持更多的功能,例如日志等
#切换至救援模式
systemctl rescue
#切换至紧急模式
systemctl emergency
#关机
systemctl halt
systemctl poweroff
#重启
systemctl reboot
#挂起
systemctl suspend
#休眠
systemctl hibernate
#休眠并挂起
systemctl hybrid-sleep
CentOS 7之后版本引导顺序
-
UEFi或BIOS初始化,运行POST开机自检
-
选择启动设备
-
引导装载程序, centos7是grub2,加载装载程序的配置文件: /etc/grub.d/, /etc/default/grub ,/boot/grub2/grub.cfg
-
加载initramfs驱动模块(可以实现根文件系统的挂载)
-
加载虚拟根中的内核
-
虚拟根的内核初始化,Centos7使用systemd代替init,第一个进程
-
执行initrd.target 所有单元,包括挂载 /etc/fstab
-
从initramfs根文件系统切换到磁盘根目录
-
systemd执行默认target配置,配置文件/etc/systemd/system/default.target
-
systemd执行sysinit.target初始化系统及basic.target准备操作系统
-
systemd启动multi-user.target 下的本机与服务器服务
-
systemd执行multi-user.target 下的/etc/rc.d/rc.local
-
Systemd执行multi-user.target下的getty.target及登录服务
-
systemd执行graphical需要的服务
从 RHEL 9.1 开始,如果 RHEL 是唯一安装的操作系统,并且之前的引导成功,则 GRUB 引导装载程序 被配置为默认隐藏引导菜单
要访问引导菜单:
-
在启动系统后,重复按 Esc 键
-
引导系统后,重复按 F8
-
在启动过程中按住 Shift
要禁用这个功能并配置引导装载程序菜单默认显示
grub2-editenv - unset menu_auto_hide
破解 root 密码
破解CentOS8,7的root密码
方法一
启动时任意键暂停启动
按e键进入编辑模式
将光标移动linux 开始的行,添加内核参数 rd.break
按ctrl+x启动
mount –o remount,rw /sysroot
chroot /sysroot
passwd root
#如果SELinux是启用的,才需要执行下面操作,如查没有启动,不需要执行
touch /.autorelabel
exit
reboot
方法二
#此方式也适用于ubuntu18.04
启动时任意键暂停启动
按e键进入编辑模式
将光标移动linux 开始的行,添加 rw init=/sysroot/bin/sh
按ctrl+x启动
chroot /sysroot
passwd root
#如果SELinux是启用的,才需要执行下面操作,如查没有启动,不需要执行
touch /.autorelabel
exit
reboot
方法三
#ubuntu中显示 grub 菜单,同上
/etc/default/grub[root@ubuntu ~]# cat /etc/default/grub
GRUB_DEFAULT=0
GRUB_TIMEOUT_STYLE=timeout #改成 timeout
GRUB_TIMEOUT=10 #大于0
[root@ubuntu ~]# update-grub
grub2 安全
#添加grub2密码,会生在一个配置文件
[root@rocky86 ~]# ll /boot/grub2/user.cfg
ls: cannot access '/boot/grub2/user.cfg': No such file or directory
[root@rocky86 ~]# grub2-setpassword
Enter password:
Confirm password:
[root@rocky86 ~]# ll /boot/grub2/user.cfg
-rw------- 1 root root 298 Sep 3 14:56 /boot/grub2/user.cfg#清空grub2密码
[root@rocky86 ~]# cat /dev/null > /boot/grub2/user.cfg#或者直接删除文件
[root@rocky86 ~]# rm -f /boot/grub2/user.cfg
[root@ubuntu ~]# grub-mkpasswd-pbkdf2
Enter password:
Reenter password:
PBKDF2 hash of your password is
grub.pbkdf2.sha512.10000.DE4B1993A5CB6504E9DA91746673413CD4C3B3FD390FDD4001EAD67
2DE281448CF2AF64000B95C378D7948E2243771A45E10E1B99FF879C4F8F08EDDA25C5536.331999
A3DFD5ECF205440CBBC48B2B1A2F4D08BB8731FA00E03ADBA990C228AD4D3D5D515EAED2350B20DB
F74810700A2E0003FAEF3E5F25D24E877385A3714F#修改此文件,将上述生成的内容追加到该文件最后
[root@ubuntu ~]# vim /etc/grub.d/40_customset superusers="tom"
password_pbkdf2 tom
grub.pbkdf2.sha512.10000.DE4B1993A5CB6504E9DA91746673413CD4C3B3FD390FDD4001EAD67
2DE281448CF2AF64000B95C378D7948E2243771A45E10E1B99FF879C4F8F08EDDA25C5536.331999
A3DFD5ECF205440CBBC48B2B1A2F4D08BB8731FA00E03ADBA990C228AD4D3D5D515EAED2350B20DB
F74810700A2E0003FAEF3E5F25D24E877385A3714F#更新
[root@ubuntu ~]# update-grub#重启,下次再选择grub,要输入用户名和密码
grub2 修复
grub2修复本质上来讲,跟grub修复同理
第1阶段或第1.5阶段,二进制数据损失,重装 grub2 即可
grub2-install /dev/sda #BIOS环境
grub2-install #UEFI环境
第二阶段 /boot/ 目录下文件丢失,则要重装内核,重装grub2,并重新生成配置文件
#删除/boot/下所有内容
[root@rocky86 ~]# rm -rf /boot/*
[root@rocky86 ~]# ls /boot/#重启,从光盘启动,进救援模式#切根
chroot /mnt/sysimage #centos7
chroot /mnt/sysroot #centos8#安装grub2
grub2-install /dev/sda #BIOS环境
grub2-install #UEFI环境#挂载光盘
mount /dev/sr0 /mnt#安装内核
rpm –ivh /mnt/Packages/kernel-3.10.0-1062.el7.x86_64.rpm --force
#centos7
rpm -ivh /mnt/BaseOS/Packages/k/kernel-core-4.18.0-372.9.1.el8.x86_64.rpm --force #centos8#生成配置文件
grub2-mkconfig -o /boot/grub2/grub.cfg#重启
exit
reboot
内核参数管理
sysctl 命令用来配置linux 系统内核参数,这些参数以文件的形式显示在 /proc/sys/ 目录中, 配置项就是目录名加文件名,值就是该文件中的内容
注意:不是所有内核参数都是可以被修改的
查看所有配置项
#内核参数配置目录
[root@ubuntu ~]# ll /proc/sys
total 0
dr-xr-xr-x 1 root root 0 May 21 08:42 ./
dr-xr-xr-x 294 root root 0 May 21 08:42 ../
dr-xr-xr-x 1 root root 0 May 21 08:48 abi/
dr-xr-xr-x 1 root root 0 May 21 08:48 debug/
dr-xr-xr-x 1 root root 0 May 21 08:48 dev/
dr-xr-xr-x 1 root root 0 May 21 08:43 fs/
dr-xr-xr-x 1 root root 0 May 21 08:42 kernel/
dr-xr-xr-x 1 root root 0 May 21 08:43 net/
dr-xr-xr-x 1 root root 0 May 21 08:48 sunrpc/
dr-xr-xr-x 1 root root 0 May 21 08:48 user/
dr-xr-xr-x 1 root root 0 May 21 08:43 vm/
sysctl 格式
sysctl [options] [variable[=value] ...]#常用选项
-a|-A|-x|--all #显示所有内核参数
-p|--load #重载
-N|--names #仅显示参数名称
-n|--values #仅显示参数值
-w|--write #设置内核参数
可用的配置文件
系统在启动时,会按下列顺序加载配置文件,读取参数值
/run/sysctl.d/*.conf
/etc/sysctl.d/*.conf
/usr/local/lib/sysctl.d/*.conf
/usr/lib/sysctl.d/*.conf
/lib/sysctl.d/*.conf
/etc/sysctl.conf
常用内核参数
net.ipv4.ip_forward #是否开启ipv4地址转发
net.ipv4.icmp_echo_ignore_all #是否禁用ping功能
net.ipv4.ip_nonlocal_bind #允许应用程序可以监听本地不存在的IP
vm.drop_caches #缓存回收机制 3 回收所有 2 释放数据区和信息节点1 释放页面缓存
fs.file-max = 1020000 #内核可以支持的全局打开文件的最大数
vm.overcommit_memory = 0 #超分 0表示进程申请内存时会判断,不够则返回错误,1表示内核允许分配所有的物理内存,而不管当前的内存状态如何,2表示内核允许分配超过所有物理内存和交换空间总和的内存
vm.swappiness = 10 #使用swap空间时物量内存还有多少可用,10 表示物理存只有10%时才使用swap#禁用IPv6
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
对于网络接口的配置,则会在对应的网络接口出现的时候才会生效,具体来说就是 net.ipv4.conf, net.ipv6.conf,net.ipv4.neigh, net.ipv6.neigh 等参数。
有部份sysctl 参数仅在加载了相应的内核模块之后才可用,因为内核模块是按需动态加载的(例如加入了 新的硬件或启动网络时),所以在 sysctl.conf 文件中无法设置的那些依赖于特定模块的参数。