二维码

服务管理与开机流程管理

844 人阅读 | 时间:2021年12月17日 23:37

13.1:服务管理

服务就是一个被启动的程序,这个程序可以常驻于存储器当中提供网络连线、例行工作调度等任务,就可称为服务。

13.1.1:程序的管理通过 kill 与 signal

一个程序被执行触发之后会变成在内存当中的一个活动的单位,那就是程序(process)。 之前的课程介绍过 PID 与程序的观察, 本小节会继续介绍 PID 的管理方面的任务。

管理员可以通过给某程序一个信号(signal)去告知该程序你想要让它作什么。 主要的程序信号可以使用 kill -l 或 man 7 signal 查询, 底下撷取较常见的信号代号与对应内容:

代号名称内容
1SIGHUP启动被终止的程序,可让该 PID 重新读取自己的配置文件,类似重新启动
2SIGINT相当于用键盘输入 [ctrl]-c 来中断一个程序的进行
9SIGKILL代表强制中断一个程序的进行,如果该程序进行到一半, 那么尚未完成的部分可能会有'半产品'产生,类似 vim会有 .filename.swp 保留下来。
15SIGTERM以正常的结束程序来终止该程序。 由于是正常的终止,所以后续的动作会将他完成。 不过,如果该程序已经发生问题,就是无法使用正常的方法终止时, 输入这个 signal 也是没有用的。
19SIGSTOP相当于用键盘输入 [ctrl]-z 来暂停一个程序的进行

至于传输 signal 则是通过 kill 这个指令。 举例来说,若管理员想要直接让前一堂课介绍的rsyslogd这个程序重读其设定文件,而不透过服务管理的正常机制时,可以尝试如下处理方式:

[root@localhost ~]# pstree -p | grep rsyslog
           |-rsyslogd(1769)-+-{rsyslogd}(1778)
           |                |-{rsyslogd}(1779)
           |                `-{rsyslogd}(1781)

[root@localhost ~]# kill -1 1769[root@localhost ~]# rjournalctl -u rsyslog[root@localhost ~]# tail /var/log/messages......
May 26 17:14:00 station200 rsyslogd[1769]: [origin software="rsyslogd" swVersion="8.37.0-13.el8" 
  x-pid="1769" x-info="http://www.rsyslog.com"] rsyslogd was HUPed

读者可以发现在登录文件出现了 rsyslogd 被要求重新读取配置文件的记录 (HUPed)! 而除了 PID 之外,管理员也能够使用指令名称来给予 signal, 直接通过 killall 即可。 如下管理方式:

[root@localhost ~]# killall -1 rsyslogd
例题 13.1.1-1: 使用程序管理与讯号传递管理程序
  1. 使用 ps 这个指令,列出系统全部程序的' pid, nice值, pri值, command '信息

  2. 找出系统内程序执行文件名为 sshd 的 PID

  3. 将上述的 PID 给予 signal 1 的方式为何?

  4. 观察一下 /var/log/secure 的内容是否正确的输出相关的程序行为?

  5. 如何将系统上所有的 bash 程序通通删除?

13.1.2:systemd 简介

从 CentOS 7 以后,Red Hat 系列的 distribution 放弃沿用多年的 System V 开机启动服务的流程, 改用 systemd 这个启动服务管理机制~采用 systemd 的原因如下:

  • 平行处理所有服务,加速开机流程

  • 一经要求就响应的 on-demand 启动方式 (因为 systemd 为单一程序且常驻于内存)

  • 服务相依性的自我检查

  • 依 daemon 功能分类

  • 将多个 daemons 集合成为一个群组

但是 systemd 也有许多存在的问题:

  • 全部的 systemd 都用 systemctl 这个管理程序管理,而 systemctl 支持的语法有限制,不可自定义参数 (所以使用 shell script 外带参数的方法就不行了! )。

  • 如果某个服务启动是管理员自己手动执行启动,而不是使用 systemctl 去启动的,那么 systemd 将无法检测到该服务

  • systemd 启动过程中,无法与管理员透过 standard input 传入讯息! 因此,自行撰写 systemd 的启动设定时,务必要取消互动机制

  • systemd 的配置文件放置目录

基本上, systemd 将过去所谓的 daemon 执行脚本通通称为一个服务单位 (unit),而每种服务单位依据功能来区分时,就分类为不同的类型 (type)。 基本的类型有包括系统服务、数据监听与交换的插槽文件服务(socket)、存储系统状态的快照类型、提供不同类似执行级别分类的操作环境(target)等等。 在配置文件放置在下面的目录中:

  • /usr/lib/systemd/system/:每个服务最主要的启动脚本设定;

  • /run/systemd/system/:系统执行过程中所产生的服务脚本,这些脚本的优先序要比 /usr/lib/systemd/system/ 高!

  • /etc/systemd/system/:管理员依据主机系统的需求所建立的执行脚本,执行优先序又比 /run/systemd/system/ 高!

也就是说,到底系统开机会不会执行某些服务其实是看 /etc/systemd/system/ 底下的设定,所以该目录底下就是一大堆链接文件。 而实际执行的 systemd 启动脚本配置文件, 其实都是放置在 /usr/lib/systemd/system/ 底下的!

  • systemd 的 unit 类型分类说明

/usr/lib/systemd/system/ 内的数据主要使用副档名来进行分类,底下尝试找出 cron 与 multi-user 这些服务的数据:

[root@localhost ~]# ll /usr/lib/systemd/system/ | egrep 'multi-user|cron'-rw-r--r--. 1 root root  356 11月  9  2019 crond.service-rw-r--r--. 1 root root  532  6月 22  2018 multi-user.targetdrwxr-xr-x. 2 root root  258  5月 25 21:28 multi-user.target.wants
lrwxrwxrwx. 1 root root   17  4月 10 05:52 runlevel2.target -> multi-user.target
lrwxrwxrwx. 1 root root   17  4月 10 05:52 runlevel3.target -> multi-user.target
lrwxrwxrwx. 1 root root   17  4月 10 05:52 runlevel4.target -> multi-user.target

所以我们可以知道 crond 其实算是系统服务 (service),而 multi-user 要算是执行环境相关的类型 (target type)。 根据这些扩展名类型, 我们大概可以找到几种比较常见的 systemd 的服务类型如下:

副档名主要服务功能
.service一般服务类型 (service unit):主要是系统服务,包括服务器本身所需要的本机服务以及网络服务都是! 比较经常被使用到的服务大多是这种类型!
.socket

内部程序数据交换的插槽服务(socket unit): 这种类型的服务通常在监控讯息传递的插槽文件,当有透过此插槽文件传递讯息来说要链接服务时,就依据当时的状态将该用户的要求传送到对应的daemon,若daemon尚未启动,则启动该daemon后再传送用户的要求。

使用socket类型的服务一般是比较不会被用到的服务,因此在开机时通常会稍微延迟启动的时间。 一般用于本地服务比较多, 例如我们的图形界面很多的软件都是通过 socket 来进行本地程序数据交换的行为。

.target执行环境类型 (target unit):其实是一群 unit 的集合,例如上面表格中谈到的 multi-user.target 其实就是一堆服务的集合~也就是说, 选择执行 multi-user.target 就是执行一堆其他 .service 或/及 .socket 之类的服务就是了!

其中又以 .service 的系统服务类型最常见。

例题 13.1.2-1:尝试找出 systemd 的实际路径与软件名称
  1. 透过 ps 找出 systemd 这个执行文件的完整路径

  2. 上述的指令是由那一个软件所提供?

  3. 该软件提供的全部文件名如何查询?

13.1.3:systemctl 管理服务的启动与关闭

一般来说,服务的启动有两个阶段,一个是'开机的时候设定要不要启动这个服务', 以及'现在要不要启动这个服务'两个阶段。 这两个阶段都可以使用 systemctl 指令来管理。 systemctl 的基本语法为:

[root@localhost ~]# systemctl [command] [unit]

上表所谓的 command 主要有:

  • start:立刻启动后面接的 unit

  • stop :立刻关闭后面接的 unit

  • restart :立刻关闭后启动后面接的 unit,亦即执行 stop 再 start 的意思

  • reload :不关闭后面接的 unit 的情况下,重新加载配置文件,让设定生效

  • enable :设定下次开机时,后面接的 unit 会被启动

  • disable :设定下次开机时,后面接的 unit 不会被启动

  • status :目前后面接的这个 unit 的状态,会列出有没有正在执行、开机预设执行否、登录等信息等!

例题 13.1.3-1: 学习使用 systemctl
  1. 查询系统有没有 cupsd 这个指令?

  2. 使用 rpm 查询该指令属于哪个软件?

  3. 使用 rpm 查询该软件的功能为何?

  4. 请观察 cups 这个服务目前是启动或关闭? 开机时会不会启动这个服务?

  5. 请将 cups 关闭,且下次开机还是会关闭

  6. 再次观察 cups 这个服务。

  7. 观察登录文件有没有记录 cups 这个服务的相关资料?

13.1.4:systemctl 列表系统服务

默认的情况下, systemctl 可以列出当前系统已经启动的服务群,如下列表:

[root@localhost ~]# systemctlUNIT                                    LOAD   ACTIVE SUB       DESCRIPTION
.....
proc-sys-fs-binfmt_misc.automount       loaded active waiting   Arbitrary Executable File>
sys-devices-pci0000:00-0000:00:01.1-ata2-host1-target1:0:0-1:0:0:0-block-sr0.device loade>
sys-devices-pci0000:00-0000:00:03.0-virtio0-net-ens3.device loaded active plugged   Virti>
chronyd.service                         loaded active running   NTP client/server
colord.service                          loaded active running   Manage, Install and Gener>
crond.service                           loaded active running   Command Scheduler
firewalld.service                       loaded active running   firewalld - dynamic firew>
ModemManager.service                    loaded active running   Modem Manager
graphical.target                        loaded active active    Graphical Interface

LOAD   = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB    = The low-level unit activation state, values depend on unit type.

170 loaded units listed. Pass --all to see loaded but inactive units, too.
To show all installed unit files use 'systemctl list-unit-files'.

列表当中,LOAD/ACTIVE/DESCRIPTION 等意义为:

  • UNIT :项目的名称,包括各个 unit 的类(看扩展名)

  • LOAD :开机时是否会被加载,默认 systemctl 显示的是有加载的项目而已喔!

  • ACTIVE :目前的状态,须与后续的SUB搭配! 就是我们用 systemctl status 观察时,active 的项目!

  • DESCRIPTION :服务的详细描述

如上表显示 chronyd 为 service 的类别,下次开机会启动 (load),而现在的状态是运作中 (active running)。 最底下两行显示共有 170 的 unit 显示在上面, 如果想要列出系统上还没有被列出的服务群,可以加上 --all 来继续观察。 此外,我们也能够仅针对 service 的类别来观察,如下所示:

[root@localhost ~]# systemctl list-units --type=service --all

如果想要观察更详细的每个启动的数据,可以通过底下的方式来处理:

[root@localhost ~]# systemctl list-unit-filesUNIT FILE                                  STATE
proc-sys-fs-binfmt_misc.automount          static
.......
atd.service                                enabled
crond.service                              enabled
.......
unbound-anchor.timer                       enabled

416 unit files listed.
例题 13.1.4-1:找出 systemd 管理的服务列表信息
  1. 找出系统中以 ksm 为开头的所有的服务名称,并观察其状态

  2. 将该服务设定为'开机不启动'且'目前立刻关闭'的情况

13.1.5:systemctl 取得与切换预设操作界面

Linux 默认的操作画面可以是纯文字也能够是文字加上图形界面。 早期的 systemV 系统称文字界面为 runlevel 3 而图形界面为 runlevel 5。 systemd 提供多种的操作界面,主要是通过' target'这种 unit 来作为规范。 读者可以使用如下的指令来观察所有的 target:

[root@localhost ~]# systemctl list-units --type=target --all

在 CentOS 8 底下常见的操作界面 (target unit) 有底下几种:

  • multi-user.target:纯文字模式

  • graphical.target:文字加上图形界面,其实就是 multi-user.target 再加图形操作。

  • rescue.target:在无法使用 root 登录的情况下,systemd 在开机时会多加一个额外的暂时系统,与你原本的系统无关。 这时你可以获取 root 的权限来维护你的系统。

  • emergency.target:紧急处理系统的错误,还是需要使用 root 登入的情况,在无法使用 rescue.target 时,可以尝试使用这种模式!

  • shutdown.target:就是关机的流程。

  • getty.target:可以设定你需要几个 tty 之类的,如果想要降低 tty 的项目,可以修改这个东西的配置文件!

而上述的操作模式中,默认的是multi-user与 graphical 这两种。 其实这些模式彼此之间还是有相依性的,读者可以使用如下的方式查出来 graphical 执行前, 有哪些 target 需要被执行:

[root@localhost ~]# systemctl list-dependencies graphical.targetgraphical.target
● ├─.......
● └─multi-user.target
●   ├─.......
●   ├─basic.target
●   │ ├─.......
●   │ ├─sockets.target
●   │ │ └─.......
●   │ ├─sysinit.target
●   │ │ ├─.......
●   │ │ ├─local-fs.target
●   │ │ │ └─.......
●   │ │ └─swap.target
●   │ │   └─.......
●   │ └─timers.target
●   │   └─.......
●   ├─getty.target
●   │ └─.......
●   ├─nfs-client.target
●   │ └─.......
●   └─remote-fs.target
●     └─nfs-client.target
●       └─.......

上述的表格已经精简化过,仅保留了 unit=target 的项目,从里面读者也能够发现到要执行 graphical 之前,还得需要其他的 target 才行。 若须取得目前的操作界面,可以使用如下的方式来处理:

[root@localhost ~]# systemctl get-defaultgraphical.target

如果需要设置默认的操作界面,例如将原本的图形界面改为文字界面的操作方式时,可以使用如下的方式来处理:

[root@localhost ~]# systemctl set-default multi-user.targetRemoved /etc/systemd/system/default.target.
Created symlink /etc/systemd/system/default.target 
   → /usr/lib/systemd/system/multi-user.target.

[root@localhost ~]# systemctl get-defaultmulti-user.target

如此即可将文字界面设定为预设的操作环境。 上述的作法是开机时才进行的预设操作环境界面,若需要即时将图形界面改为文字界面, 或者反过来处理时,可以使用如下的方式来处置:

[root@localhost ~]# systemctl isolate multi-user.target
例题 13.1.5-1: 变更操作环境的方式
  1. 使用 netstat -tlunp 查看一下系统的网络监听埠口

  2. 请在本机目前的状态下,将操作界面模式更改为 rescue.target 这个救援模式

  3. 使用 netstat -tlunp 查看一下系统的网络监听埠口是否有变少?

  4. 将环境改为原本的操作界面( 默认为图形、更改为 GUI)

13.1.6:网络服务管理初探

如果是网络服务,一般都会启动监听界面在 TCP 或 UDP 的封包埠口上。 获取目前监听的端口口可以使用如下的方式:

[root@localhost ~]# netstat -tlunpActive Internet connections (only servers)
Proto Recv-Q Send-Q Local Address     Foreign Address   State   PID/Program name
tcp        0      0 0.0.0.0:5355      0.0.0.0:*         LISTEN  3076/systemd-resolv
tcp        0      0 0.0.0.0:111       0.0.0.0:*         LISTEN  1/systemd
tcp        0      0 192.168.122.1:53  0.0.0.0:*         LISTEN  2136/dnsmasq
tcp        0      0 0.0.0.0:22        0.0.0.0:*         LISTEN  2390/sshd
tcp        0      0 127.0.0.1:25      0.0.0.0:*         LISTEN  2765/master
tcp6       0      0 :::5355           :::*              LISTEN  3076/systemd-resolv
tcp6       0      0 :::111            :::*              LISTEN  1/systemd
tcp6       0      0 :::22             :::*              LISTEN  2390/sshd
tcp6       0      0 ::1:25            :::*              LISTEN  2765/master
udp        0      0 0.0.0.0:50055     0.0.0.0:*                 2247/avahi-daemon:
udp        0      0 127.0.0.53:53     0.0.0.0:*                 3076/systemd-resolv
udp        0      0 192.168.122.1:53  0.0.0.0:*                 2136/dnsmasq
udp        0      0 0.0.0.0:67        0.0.0.0:*                 2136/dnsmasq
udp        0      0 0.0.0.0:35930     0.0.0.0:*                 3082/rsyslogd
udp        0      0 0.0.0.0:111       0.0.0.0:*                 1/systemd
udp        0      0 0.0.0.0:5353      0.0.0.0:*                 2247/avahi-daemon:
udp        0      0 0.0.0.0:5355      0.0.0.0:*                 3076/systemd-resolv
udp        0      0 127.0.0.1:323     0.0.0.0:*                 2262/chronyd
udp        0      0 0.0.0.0:514       0.0.0.0:*                 3082/rsyslogd
udp6       0      0 :::111            :::*                      1/systemd
udp6       0      0 :::5353           :::*                      2247/avahi-daemon:
udp6       0      0 :::5355           :::*                      3076/systemd-resolv
udp6       0      0 :::57581          :::*                      2247/avahi-daemon:
udp6       0      0 ::1:323           :::*                      2262/chronyd
udp6       0      0 :::514            :::*                      3082/rsyslogd

重点在 Local Address 那一行,会显示该服务是启动在本机的哪一个 IP 界面的哪一个端口上,如此管理员即可了解启动该端口的服务是哪一个。 若无须该网络服务,则可以将该程序关闭。 以上述表格来说,如果需要关闭 avahi-daemon, systemd-resolv 时,可以使用如下的方式取得服务名称:

[root@localhost ~]# systemctl list-unit-files | egrep 'avahi|systemd-resolv'avahi-daemon.service           enabled
systemd-resolved.service       enabled
avahi-daemon.socket            enabled

若需要将其关闭,则应该使用如下的方式,将'目前'与'默认'的服务启动都关闭才行:

[root@localhost ~]# systemctl stop avahi-daemon.service systemd-resolved.service avahi-daemon.socket[root@localhost ~]# systemctl disable avahi-daemon.service systemd-resolved.service avahi-daemon.socket[root@localhost ~]# netstat -tlunp

读者将可发现到 avahi-daemon 以及 systemd-resolv 的服务已经被关闭。 而若需要启动某个网络服务,则需要了解到该服务是由哪一个软件所启动的, 该软件需要先安装后才可以启动该服务。 比较特别的是 dnsmasq 这个服务,事实上,这个服务是被虚拟化系统所唤醒使用的,所以, 要关闭这个服务,得要关闭虚拟化数据才行。

实际练习:尝试关闭虚拟化环境的服务:
  1. 先查阅 libvirtd 有没有在启动,同时,使用 virsh list 指令查询目前有没有虚拟机在运作?

    [root@localhost ~]# systemctl status libvirtd● libvirtd.service - Virtualization daemon
       Loaded: loaded (/usr/lib/systemd/system/libvirtd.service; enabled; vendor preset: enabled)
       Active: active (running) since Tue 2020-05-26 23:08:27 CST; 8min ago
         Docs: man:libvirtd(8)
               https://libvirt.org
     Main PID: 2391 (libvirtd)
    .....# 確實活著喔![root@localhost ~]# virsh list
     Id    名稱                         狀態
    ----------------------------------------------------
  2. 查询是否有特定的虚拟化网络界面,因为使用 nmcli 时,有看到以 virbr 开头的网络界面之故:

    [root@localhost ~]# virsh net-list
     名稱               狀態     自動啟動  Persistent
    ----------------------------------------------------------
     default              啟用     yes           yes
  3. 关闭此网络界面,并且永远取消设置:

    [root@localhost ~]# virsh net-destroy default[root@localhost ~]# virsh net-undefine default
  4. 这时再回头看看网络端口口的情况:

    [root@localhost ~]# netstat -tlunpActive Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address    Foreign Address  State   PID/Program name
    tcp        0      0 0.0.0.0:111      0.0.0.0:*        LISTEN  1/systemd
    tcp        0      0 0.0.0.0:22       0.0.0.0:*        LISTEN  2390/sshd
    tcp        0      0 127.0.0.1:25     0.0.0.0:*        LISTEN  2765/master
    tcp6       0      0 :::111           :::*             LISTEN  1/systemd
    tcp6       0      0 :::22            :::*             LISTEN  2390/sshd
    tcp6       0      0 ::1:25           :::*             LISTEN  2765/master
    udp        0      0 0.0.0.0:35930    0.0.0.0:*                3082/rsyslogd
    udp        0      0 0.0.0.0:111      0.0.0.0:*                1/systemd
    udp        0      0 127.0.0.1:323    0.0.0.0:*                2262/chronyd
    udp        0      0 0.0.0.0:514      0.0.0.0:*                3082/rsyslogd
    udp6       0      0 :::111           :::*                     1/systemd
    udp6       0      0 ::1:323          :::*                     2262/chronyd
    udp6       0      0 :::514           :::*                     3082/rsyslogd

上面这几个服务大概就是一台正常的 Linux 系统应该要具有的服务,所以,不要在随便关闭喔!

例题 13.1.6-1:尝试安装、启动、开机启动、防火墙、测试等五步骤处理正常的网络服务!
  1. 安装:WWW 网络服务是由 httpd 这个软件所提供的,请先安装该软件;并查询是否有 httpd 的服务存在了?

  2. 启动:启动该服务,并且查询该服务启动的端口为何

  3. 启动启动:设置为默认启动该服务,并查询该服务的状态是否正确 (默认启动/现在启动)

  4. 防火墙:将 http 服务的防火墙埠口放行

  5. 测试:使用浏览器查询本地 WWW 服务是否正确启动了。

13.1.7:系统性能优化 - tuned, tuned-adm

因为每个 Server 的使用情境不同,有的在虚拟机当中,有的是实体机,有的需要使用一般网络服务功能,有的要加强本身网络传输, 有的则是需要进行科学运算等等。 也因为不同的设计参考依据不一样,因此预设的系统参数可能就不会相当适合于你的环境。

以前要调整 (tune) 系统效能时,需要进行一大堆的设定,包括核心模块、核心参数、网路参数、磁盘参数等等,相当复杂。 现在的系统则加入了名为 tuned 这个服务,通过这个服务的动态处理,可以随时以你选定的环境 (profile) 来统一处理效能优化的相关问题, 而无须每项事情都要管理员去处理了!

tuned 这个服务默认提供了许多的环境让你选择优化的情境,要查阅可以使用底下的方式处理:

[root@localhost ~]# tuned-adm listAvailable profiles:
- balanced                - General non-specialized tuned profile
- desktop                 - Optimize for the desktop use-case
- hpc-compute             - Optimize for HPC compute workloads
- latency-performance     - Optimize for deterministic performance at the cost of 
                            increased power consumption
- network-latency         - Optimize for deterministic performance at the cost of 
                            increased power consumption, focused on low latency network performance
- network-throughput      - Optimize for streaming network throughput, generally only necessary 
                            on older CPUs or 40G+ networks
- powersave               - Optimize for low power consumption
- throughput-performance  - Broadly applicable tuning that provides excellent performance across 
                            a variety of common server workloads
- virtual-guest           - Optimize for running inside a virtual guest
- virtual-host            - Optimize for running KVM guestsCurrent active profile: virtual-guest

一般来说,如果是实体机器且没有启用虚拟化功能的话,建议使用' throughput-performance '即可,一般用来当测试机或桌机的话,选择 ' desktop '应该是不错的,如果是用来跑科学计算,或许也能使用' hpc-compute ',只是用来作为 IoT 的数据收集用服务器, 使用' powersave '应该也可以。 如果是在虚拟机里面,但是有需要用到网络功能,想要降低延迟的话 (代价就是整体带宽使用率会较低), 或许也能使用' network-latency 』。 总之,要依据你的使用情境而挑选。

为了避免麻烦,其实 tuned-adm 也会自己分析你的系统所处环境,然后给予适当的建议! 你就可以依据该建议来设计你的环境优化。

当然这个建议或许不是很适合你,只是单纯依据当下的系统而给的建议而已喔! 以鸟哥的科学计算环境来说,该环境底下经常会有大量网络传输的需求,并且需要的并不是带宽(因为带宽已经达到10G了),而是反应速度。 此时,该环境比较适合的情境或许要选择『network-latency』才对! 但是一般这样的实体机器系统,tuned 会建议使用 throughput-performance。 然而鸟哥的经验中, throughput-performance 确实是当中效能最高的! 不过,如果不是单独本机运作的软件,需要跨足到其他台主机协同运作时,经常会有网络延迟的问题啊!

实际练习: 以 tuned 建议的方式设计优化环境
  1. 先查看 tuned 的建议: 看起来是建议使用 virtual-guest 的环境,因为教材的系统就是使用虚拟化,所以这个建议应该是没问题的!

    [root@localhost ~]# tuned-adm recommendvirtual-guest
  2. 以建议的优化环境参数设计 tuned 的运作: 这样应该就已经设定好我们的环境了!

    [root@localhost ~]# tuned-adm profile virtual-guest[root@localhost ~]# tuned-adm activeCurrent active profile: virtual-guest
  3. 使用 tuned 的检查功能,看看环境设定有没有问题? 有些时候设计完毕后, tuned 可能没有办法直接处理,这时可以依据上述的登录文件内容,查询一下可能的问题。 虚拟机会失败的原因,是因为虚拟机不能改 CPU 的运作模式,该模式必需要实体机器去设定才行。 要确认你的系统是否能够支持 CPU 的修改,可以使用底下的方式来处理: 正常的情境下,上面表格中的 cpufreq governors 会告诉你可用的 CPU 环境设计,这里并不行啊! 这是因为虚拟机的影响所致。 所以,上面的检测错误是可以被忽略的!

    [root@localhost ~]# tuned-adm verifyVerification failed, current system settings differ from the preset profile.
    You can mostly fix this by restarting the Tuned daemon, e.g.:
      systemctl restart tuned
    or
      service tuned restart
    Sometimes (if some plugins like bootloader are used) a reboot may be required.
    See tuned log file ('/var/log/tuned/tuned.log') for details.
    [root@localhost ~]# cpupower frequency-infoanalyzing CPU 0:
      no or unknown cpufreq driver is active on this CPU
      CPUs which run at the same hardware frequency: Not Available
      CPUs which need to have their frequency coordinated by software: Not Available
      maximum transition latency:  Cannot determine or is not supported.
    Not Available  available cpufreq governors: Not Available
      Unable to determine current policy
      current CPU frequency: Unable to call hardware
      current CPU frequency:  Unable to call to kernel
      boost state support:
        Supported: no
        Active: no

13.2:开机流程管理

系统如果出错,可能需要进入救援模式才能够处理相关的任务。 但如何进入救援模式? 这就需要从开机流程分析来下手。

13.2.1:Linux 系统在 systemd 底下的开机流程

正常正常的情况下, Linux 的开机流程会是如下所示:

  1. 硬件阶段:加载 BIOS / UEFI 的硬件信息与进行自我测试,并依据设定取得第一个可开机的装置;

  2. 系统启动阶段:这个阶段大致又分两种机制,一种是使用传统 BIOS 读取设备,一种是通过 UEFI 读取设备:

    • BIOS:根据设定,读取并执行第一个开机装置内 MBR 的 boot Loader (亦即是 grub2, spfdisk 等程序);

    • UEFI:搜索系统内的开机分割槽 (分割槽 System ID 为 EF00, 文件系统 FAT),读取内部的开机 loader

  3. 依据 boot loader 的设定加载 Kernel,Kernel 会开始侦测硬件与加载驱动程序;

    • 载入 kernel file 与 initramfs 文件在内存内解压缩

    • initramfs 会在内存模拟出系统根目录,提供 kernel 相关的驱动程式模块

    • 核心装置驱动程序完整的驱动硬件

  4. 在硬件驱动成功后,Kernel 会主动呼叫 systemd 程序,并以 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 需要的服务

如上,读者们可以发现核心档案驱动系统完成后,接下来就是 systemd 的任务,也就是前一小节所探讨的内容。 但核心档案在哪里? 以及如何设定不同的核心档案开机,那就是开机管理程序的任务了。

例题 13.2.1-1: 启动旧版 Linux distribution 经常使用的 /etc/rc.d/rc.local 开机流程处理文件
  1. 找出和 local, rc 有关的服务或文件数据 :

    1. 使用 systemctl list-units --all 的功能,找出 local 关键词

    2. 使用 systemctl list-unit-files 的功能,找出 local 关键词

    3. 使用 systemctl show xxx.service 的功能,找出上述软件的执行文件

  2. 实际装入 rc.local 的服务,让系统开机后能够运行 rc.local 的内容:

    1. 查阅 /etc/rc.d/rc.local 的权限,同时加上 x 的权限

    2. 重新加载 systemd,让上述修订生效

    3. 使用 systemctl status XXX 的功能,判断一下有没有启用该服务喔!

13.2.2:核心与核心模块

系统的核心大多放置于 /boot/vmlinuz* 开头的文件中,而 initramfs 则放置于 /boot/initramfs* 。 至于核心的模块则放置于 /lib/modules/$(uname -r)/ 目录内。

当前系统上面已经加载的模块,可以使用底下的方式来观察:

[root@localhost ~]# lsmod[root@localhost ~]# lsmod | egrep 'Module|xfs'Module          Size  Used by
xfs          1474560  2
libcrc32c      16384  3 nf_conntrack,nf_nat,xfs

如上所示,xfs 为独立运作的模块,不过还是被 2 个其他程序所使用 (Used by)! 如果你使用 df -T | grep xfs 去查阅一下, 就会知道目前系统应该有两个设备就是使用 xfs 档案系统挂载的情境。 另外,这个 xfs 模块会去使用到 libcrc32c 这个模块的意思! 也就是说,其实,模组也是有相依性的喔!

至于,若找到名为 xfs 的模块后,要想了解该模块的功能,可以使用如下的方式查询:

[root@localhost ~]# modinfo xfsfilename:       /lib/modules/4.18.0-147.8.1.el8_1.x86_64/kernel/fs/xfs/xfs.ko.xz
license:        GPL
description:    SGI XFS with ACLs, security attributes, no debug enabled
author:         Silicon Graphics, Inc.
alias:          fs-xfs
rhelversion:    8.1
srcversion:     6EB85FD6AC0E0ED926C6D92
depends:        libcrc32c
intree:         Y
name:           xfs
vermagic:       4.18.0-147.8.1.el8_1.x86_64 SMP mod_unload modversions
sig_id:         PKCS#7
signer:         CentOS Linux kernel signing key
sig_key:        57:35:0B:1E:DC:CE:14:72:7C:A0:26:12:B2:7B:38:69:93:62:B5:22
sig_hashalgo:   sha256
signature:      4B:ED:60:E8:55:5D:A1:67:0A:56:A8:74:89:1B:C0:92:CE:A1:09:2A:
.....

若想要加载某个模块,就使用 modprobe 来加载,卸载则使用 modprobe -r 来卸载即可。

例题 13.2.2-1: 核心模块的使用
  1. 在核心模块的目录下,使用 find 找出系统有没有 fat 关键词的模块?

  2. 是否已经有加载 fat 相关的模块了? 若无,请加载该模块,再次检查是否加载成功。

  3. 再次检查有无 cifs 模块,若无,请加载,并查询该模组的功能为何?

  4. 卸载 cifs 模块。

  5. 在核心模块的目录下,有没有 ntfs 的关键词?

  6. 在 yum 的使用上,启用 epel 软件库,搜索 ntfs 这个关键词软件

  7. 尝试安装上述找到的软件名称

  • 使用 /etc/sysctl.conf 处理核心参数

某些情况下,你会需要更动核心参数。 而默认的核心参数位于 /proc/sys/ 底下。 一般不建议用户直接使用手动修改方式处理 /proc 内的档案 (因为下次开机就不会持续提供),应使用修改 /etc/sysctl.conf 来处理。 举例而言,若你的 server 不想要回应 ping 的封包, 则可以如此测试:

[root@localhost ~]# ping -c 2 localhost4PING localhost (127.0.0.1) 56(84) bytes of data.
64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.044 ms
64 bytes from localhost (127.0.0.1): icmp_seq=2 ttl=64 time=0.047 ms

--- localhost ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 30ms
rtt min/avg/max/mdev = 0.044/0.045/0.047/0.006 ms

[root@localhost ~]# echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all[root@localhost ~]# ping -c 2 localhost4PING localhost (127.0.0.1) 56(84) bytes of data.
--- localhost ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 31ms

[root@localhost ~]# echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_all

读者可以发现icmp确实不会回应ping的要求了。 而这个设定值如果一定要每次开机都生效, 可以写入 /etc/sysctl.d/*.conf 内,写法为:

[root@localhost ~]# vim /etc/sysctl.d/mycentos.confnet.ipv4.icmp_echo_ignore_all = 1[root@localhost ~]# sysctl -p /etc/sysctl.d/mycentos.conf[root@localhost ~]# cat /proc/sys/net/ipv4/icmp_echo_ignore_all1

如此则可以每次都生效了。 不过,这个功能对于内部环境的测试还是很重要的,因此还是请修订回来比较妥当。

例题 13.2.2-2: 调整系统的一些参数设定
  1. 请将 icmp_echo_ignore_all 改为默认的不要启动 ( 0)

  2. 让ip_forward设定为启动

  3. 让 /proc/sys/dev/raid/speed_limit_{max|min} 分别设定为 50000/40000 (单位为 Kbytes)。

  4. 立刻启动上述设定

13.2.3:grub2 设定文件初探

核心的加载与设定是由开机管理程序来处理的,而CentOS 8默认的开机管理程序为 grub2 这一个软件。 该软件的优点包括有:

  • 认识与支持较多的文件系统,并且可以使用 grub2 的主程序直接在档案系统中搜索核心文件名;

  • 开机的时候,可以'自行编辑与修改开机设定项目',类似 bash 的指令模式;

  • 可以动态搜索配置文件,而不需要在修改配置文件后重新安装 grub2 。 亦即是我们只要修改完 /boot/grub2/grub.cfg 里头的设定后,下次开机就生效了!

  • 磁盘在 grub2 内的代号定义

开机时,数据得从磁盘读出,因此磁盘、分割槽的代号信息得先要了解厘清才行。 grub2 对磁盘的代号定义如下:

(hd0,1)         # 一般的預設語法,由 grub2 自動判斷分割格式(hd0,msdos1)    # 此磁碟的分割為傳統的 MBR 模式(hd0,gpt1)      # 此磁碟的分割為 GPT 模式
  • 硬盘代号以小括号 ( ) 或单引号 ' " 包起来;

  • 硬盘以 hd 表示,后面会接一组数字;

  • 以『搜索顺序』做为硬盘的编号! (这个重要! )

  • 第一个搜索到的硬盘为 0 号,第二个为 1 号,以此类推;

  • 每颗硬盘的第一个 partition 代号为 1 ,依序类推。

所以说,整个硬盘代号为:

硬盘搜寻顺序在 Grub2 当中的代号
第一颗(MBR)(hd0) (hd0,msdos1) (hd0,msdos2) (hd0,msdos3)....
第二颗(GPT)(hd1) (hd1,gpt1) (hd1,gpt2) (hd1,gpt3)....
第三颗(hd2) (hd2,1) (hd2,2) (hd2,3)....
  • /boot/grub2/grub.cfg 设定文件的理解

基本上,开机时 grub2 会去读取的配置文件就是 grub.cfg 这个文件,但是这个档案是由系统程序分析建立的,不建议读者们手动修改。 因此底下读者先观察该档案内容即可,先不要修订。

[root@localhost ~]# cat /boot/grub2/grub.cfg### BEGIN /etc/grub.d/00_header ###
set pager=1

if [ -f ${config_directory}/grubenv ]; then
  load_env -f ${config_directory}/grubenv
elif [ -s $prefix/grubenv ]; then
  load_env
fi
........
if [ x$feature_timeout_style = xy ] ; then
  set timeout_style=menu  set timeout=5# Fallback normal timeout code in case the timeout_style feature is
# unavailable.
else  set timeout=5fi
### END /etc/grub.d/00_header ###

.......

### BEGIN /etc/grub.d/10_linux ###
insmod part_gpt
insmod ext2set root='hd0,gpt2'   <==Linux 核心所在的分割槽if [ x$feature_platform_search_hint = xy ]; then  search --no-floppy --fs-uuid --set=root --hint='hd0,gpt2'  73f13e7b-43c4-43c5-93b4-9e65b962752d
  # 上一列的 --set=root 則是指定具有這個 UUID 的檔案系統為根目錄else
  search --no-floppy --fs-uuid --set=root 73f13e7b-43c4-43c5-93b4-9e65b962752d
fiset default_kernelopts="root=/dev/mapper/centos-root ro crashkernel=auto  quiet "# This section was generated by a script. Do not modify the generated file - all changes
# will be lost the next time file is regenerated. Instead edit the BootLoaderSpec files.
#
# The blscfg command parses the BootLoaderSpec files stored in /boot/loader/entries and
# populates the boot menu. Please refer to the Boot Loader Specification documentation
# for the files format: https://www.freedesktop.org/wiki/Specifications/BootLoaderSpec/.insmod blscfg
blscfg### END /etc/grub.d/10_linux ###

.......

### BEGIN /etc/grub.d/41_custom ###
if [ -f  ${config_directory}/custom.cfg ]; then  source ${config_directory}/custom.cfgelif [ -z "${config_directory}" -a -f  $prefix/custom.cfg ]; then
  source $prefix/custom.cfg;
fi
### END /etc/grub.d/41_custom ###

这个 grub.cfg 文件分为数个部份,分别由不同的配置文件整合而来,上表中的特殊字体是比较重要的部份。 至于比较重要的内容,大致说明如下:

  • /etc/grub.d/00_header 之 timeout=5 : 00_header 文件里面规范到是否要列出菜单, 以及等待的时间 timeout 资料等。 开机选单会倒数 5 秒钟,就是在这个阶段以' timeout=5 '来设定的结果。

  • /etc/grub.d/10_linux 的 insmod 与 set root 功能:10_linux 的阶段则是实际的 Linux 核心菜单重头戏! 该段落的过程中,首先是加载 GPT 以及 ext2 的档案系统模块 (insmod),然后配置放置 /boot 这个目录的分割槽代码,在本系统当中是 /dev/vda2,也就是 (hd0,2) 这个磁盘代码,因此设定了『 set root='hd0,gpt2' 』这个设定值。

  • /etc/grub.d/10_linux 的 search 功能:开机的时候总是需要挂载根目录的,根目录就根据 search 这个项目去搜寻。 根据整体Linux内含的档案系统,该档案系统 UUID 若为 73f13e7b-43c4-43c5-93b4-9e65b962752d 时,就将该档案系统设定为根目录。

  • /etc/grub.d/10_linux 的 set default_kernelopts 功能:核心功能参数写入在这里。 因为核心可能有多个菜单,每个菜单若需要分别设计,那未来修改很麻烦,因此就将共享的核心参数写入在这个变量中!

  • /etc/grub.d/10_linux 的 blscfg 功能:事实上,所有的开机菜单是分别放置到 /boot/loader/entries/ 里面的 .conf 档案, 每一个档案就是一个菜单。 透过 blscfg 指令,会将 /boot/loader/entries/ 中的档案呼叫进来成为菜单之意。

  • /etc/grub.d/41_custom 阶段:若有更多的开机菜单或设定,再写入到这个档案中。

在 10_linux 的阶段中,有两个主要的 root 设定,一个是设定核心所在处的『 set root='hd0,gpt2' ',另一个则是设定根目录的所在档案系统, 也就是『 search --no-floppy --fs-uuid --set=root 』那一行! 两个 root 的意义不相同喔! 这点要特别留意!

上面谈到的 blscfg 当中,通过文件的说明,可以发现 blscfg 会去呼叫 /boot/loader/entries/ 里面的配置文件,先来看看该目录有什么信息:

[root@localhost ~]# ls /boot/loader/entries/502dbaaf2a074134909a59ef9ab651c1-0-rescue.conf
502dbaaf2a074134909a59ef9ab651c1-4.18.0-147.8.1.el8_1.x86_64.conf
502dbaaf2a074134909a59ef9ab651c1-4.18.0-147.el8.x86_64.conf

直接拿 4.18.0-147.el8.x86_64 此文件内容来瞧瞧:

[root@localhost ~]# cat /boot/loader/entries/*-4.18.0-147.el8.x86_64.conftitle    CentOS Linux (4.18.0-147.el8.x86_64) 8 (Core)
version  4.18.0-147.el8.x86_64
linux    /vmlinuz-4.18.0-147.el8.x86_64
initrd   /initramfs-4.18.0-147.el8.x86_64.img $tuned_initrd
options  $kernelopts $tuned_params
id       centos-20191204215851-4.18.0-147.el8.x86_64
grub_users $grub_users
grub_arg   --unrestricted
grub_class kernel

这个档案当中,比较重要的项目大概是:

  • title :就是菜单的内容,选择一个易懂的名称显示即可。

  • version :通常是核心版本。

  • linux :就是核心档案放置的地方。 由于 /boot 已经设定为 root,就是 grub.cfg 里面已经指定了核心所在目录为 hd0,gpt2, 因此, /boot/vmlinuz-xxx ==> 'hd0,gpt2'/vmlinuz-xxx,所以,这里只要写 /vmlinuz 即可。 若 /boot 并没有独立的目录存在, 这边才写 /boot/vmlinuz-xxx 喔!

  • initrd :就是核心在开机过程当中需要加载的核心模块以及开机过程需要的根目录,默认解压缩后会以内存模拟根目录。

  • options :将刚刚 grub.cfg 的参数呼叫到这里来,这个 options 就是核心参数!

  • id :让这个开机菜单具有一个识别码,方便在其他地方也能呼叫到这个菜单!

13.2.4:grub2 设定文件维护

基本上,修改 grub2 设定文件你可以在如下的位置进行:

  • /etc/default/grub:主要修改环境设定

  • /etc/grub.d/ :可以设定其他菜单

  • /boot/loader/entries/:各别开机菜单放置的位置

主要环境设置内容为:

[root@www ~]# cat /etc/default/grubGRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="crashkernel=auto resume=/dev/mapper/centos-swap rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet"
GRUB_DISABLE_RECOVERY="true"
GRUB_ENABLE_BLSCFG=true
  • GRUB_TIMEOUT: 指定默认倒数读秒的秒数

  • GRUB_DISTRIBUTOR: 由释出系统的官网资料来展示开机的菜单

  • GRUB_DEFAULT: 指定预设由哪一个菜单来开机,默认开机菜单之意

  • GRUB_DISABLE_SUBMENU: 是否要隐藏次菜单,通常是藏起来的好!

  • GRUB_TERMINAL_OUTPUT: 指定数据输出的终端格式,默认是通过文字终端

  • GRUB_CMDLINE_LINUX: 就是在 /boot/loader/entries/ 内部文件的 linux 项目后续的核心参数

  • GRUB_DISABLE_RECOVERY: 取消救援菜单的制作

  • GRUB_ENABLE_BLSCFG: 就是使用 blscfg 去呼叫 /boot/loader/entries/ 里面的菜单之意

若有修改上述档案,则需要使用 grub2-mkconfig -o /boot/grub2/grub.cfg 来进行修订。 现在假设:

  • 开机菜单等待40秒钟

  • 核心外带' intel_iommu=on '的参数值

那应该要如何处理 grub.cfg 呢? 基本上,你应该要修订 /etc/default/grub 的内容如下:

[root@localhost ~]# vim /etc/default/grubGRUB_TIMEOUT=40GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="crashkernel=auto (..中間省略..) rhgb quiet intel_iommu=on"
GRUB_DISABLE_RECOVERY="true"
GRUB_ENABLE_BLSCFG=true

修改完毕之后再来则是进行输出修订的任务:

[root@localhost ~]# grub2-mkconfig -o /boot/grub2/grub.cfgGenerating grub configuration file ...
done

[root@localhost ~]# reboot

若想要知道是否完整的变更了,请 vim /boot/grub2/grub.cfg 查阅相关设定值是否变更即可。 重新开机后,你就可以发现菜单会等待到 40 秒喔! 然后,重新开机完毕并登入系统, 查询一下核心参数是否正确的启用了:

[root@localhost ~]# cat /proc/cmdlineBOOT_IMAGE=(hd0,gpt2)/vmlinuz-4.18.0-147.8.1.el8_1.x86_64 root=/dev/mapper/centos-root ro 
   crashkernel=auto resume=/dev/mapper/centos-swap rd.lvm.lv=centos/root 
   rd.lvm.lv=centos/swap rhgb quiet intel_iommu=on
  • 菜单建置的脚本 /etc/grub.d/*

grub2-mkconfig 执行之后会去分析 /etc/grub.d/* 里面的档案,然后执行该档案来建置 grub.cfg。 至于 /etc/grub.d/ 目录底下会有这些档案存在:

  • 00_header:主要在建立初始的显示项目,包括需要加载的模块分析、屏幕终端的格式、倒数秒数、菜单是否需要隐藏等等,大部分在 /etc/default/grub 里面所设定的变量,大概都会在这个脚本当中被利用来重建 grub.cfg 。

  • 10_linux:在CentOS 7以前的系统,这个10_linux会去找寻目前系统正确的核心,然后依据核心去建置菜单。 新的机制使用了 blscfg 了,菜单已经建置好放在 /boot/loader/entries/ 当中,所以这个档案的功能就剩下处理预设核心参数等项目。

  • 30_os-prober:这个脚本预设会到系统上找其他的 partition 里面可能含有的操作系统,然后将该操作系统做成菜单来处理就是了。 如果你不想要让其他的操作系统被侦测到并拿来开机,那可以在 /etc/default/grub 里面加上' GRUB_DISABLE_OS_PROBER=true '取消这个档案的运作。

  • 40_custom:如果你还有其他想要自己手动加上去的菜单项目,或者是其他的需求,那么建议在这里补充即可!

所以,一般来说,我们会更动到的就是仅有 40_custom 这个文件即可。 然而由于CentOS 8使用了blscfg的模块,因此Linux相关的档案系统菜单,请自行到/boot/loader/entries/去建置相关的设定即可。 那如果需要额外的其他操作系统的菜单时, 才需要用到 40_custom 的内容喔!

  • 直接指定 Linux 核心开机

在默认的核心里面,你还需要有额外的菜单,例如你要建立一个一定进入图形界面与一个一定进入文字界面的菜单时, 就可以额外建立两个菜单文件! 直接跑到 /boot/loader/entries/ 里头去处理即可! 也不需要重新建立 grub.cfg 喔! 相当简单:

实际练习:建立多重菜单的方式,思考方向如下:
  • 透过教材原有的核心版本(不是升级后的版本)开机菜单档案,额外建立两个菜单,一个强制 systemd 使用 graphical.target, 一个强制使用 multi-user.target 来启动,而不考虑源有的 default.target。

  • 要考量菜单的档案是放在哪里喔。

处理方式如下:
  1. 核心参数的设计:当核心外带参数中,有个『 systemd.unit=??? 』 的外带参数可以指定特定的 target 开机! 所以,来到 /boot/loader/entries 目录下,复制多个菜单项即可:

    [root@localhost ~]# cd /boot/loader/entries/[root@localhost entries]# cp 502...-4.18.0-147.el8.x86_64.conf custom-graphical-4.18.0-147.el8.x86_64.conf[root@localhost entries]# cp 502...-4.18.0-147.el8.x86_64.conf custom-textmode-4.18.0-147.el8.x86_64.conf[root@localhost entries]# vim custom-graphical-4.18.0-147.el8.x86_64.conftitle CentOS Linux (4.18.0-147.el8.x86_64) 8 (Core) - GUI Modeversion 4.18.0-147.el8.x86_64
    linux /vmlinuz-4.18.0-147.el8.x86_64
    initrd /initramfs-4.18.0-147.el8.x86_64.img $tuned_initrd
    options $kernelopts $tuned_params systemd.unit=graphical.targetid centos-20191204215851-4.18.0-147.el8.x86_64
    grub_users $grub_users
    grub_arg --unrestricted
    grub_class kernel
    
    [root@localhost entries]# vim custom-textmode-4.18.0-147.el8.x86_64.conftitle CentOS Linux (4.18.0-147.el8.x86_64) 8 (Core) - Text Modeversion 4.18.0-147.el8.x86_64
    linux /vmlinuz-4.18.0-147.el8.x86_64
    initrd /initramfs-4.18.0-147.el8.x86_64.img $tuned_initrd
    options $kernelopts $tuned_params systemd.unit=multi-user.targetid centos-20191204215851-4.18.0-147.el8.x86_64
    grub_users $grub_users
    grub_arg --unrestricted
    grub_class kernel

    接下来请重新开机,重新开机完毕后选择纯文本界面开机后,登录系统,再次查询核心的外带参数,看看有没有加入 multi-user 的相关字样:

    服务管理与开机流程管理
    图13.2.4-1、修改 grub 选单后的展示样式
    [root@localhost ~]# cat /proc/cmdlineBOOT_IMAGE=(hd0,gpt2)/vmlinuz-4.18.0-147.el8.x86_64 .... intel_iommu=on systemd.unit=multi-user.target
当你有特殊开机菜单的需求时,只要在 /boot/loader/entries/ 里面设计就好了!
  • 透过 chainloader 的方式移交 loader 控制权 - 仅针对 BIOS 系统

所谓的 chain loader (开机管理程序的链接) 仅是在将控制权交给下一个 boot loader 而已, 所以 grub2 并不需要认识与找出 kernel 的文件名 ,'他只是将 boot 的控制权交给下一个 boot sector 或 MBR 内的 boot loader 而已』 所以通常他也不需要去查验下一个 boot loader 的档案系统!

一般来说, chain loader 的设定只要两个就够了,一个是预计要前往的 boot sector 所在的分割槽代号, 另一个则是设定 chainloader 在那个分割槽的 boot sector (第一个磁区) 上! 假设我的 Windows 分割槽在 /dev/sda1 ,且我又只有一颗硬盘,那么要 grub 将控制权交给 windows 的 loader 只要这样就够了:

menuentry "Windows" {
        insmod chain      # 你得要先載入 chainloader 的模組對吧?
        insmod ntfs       # 建議加入 windows 所在的檔案系統模組較佳!
        set root=(hd0,1)  # 是在哪一個分割槽~最重要的項目!
        chainloader +1    # 請去 boot sector 將 loader 軟體讀出來的意思!}

透过这个项目我们就可以让 grub2 交出控制权了!

实际练习:通过分析原有的 Linux/Windows 系统,建置好多重开机菜单的方式
假设你的测试系统上面使用 MBR 分割槽,由于使用多重操作系统的安装,因此观察分割槽会出现如下的数据
: 其中 /dev/vda2 使用是 windows 10 的操作系统。 现在我需要增加两个开机选项,一个是取得 windows 10 的开机菜单,一个是回到 MBR 的预设环境,应该如何处理呢?
[root@study ~]# fdisk -l /dev/vda
   Device Boot      Start         End      Blocks   Id  System
/dev/vda1            2048    10487807     5242880   83  Linux
/dev/vda2   *    10487808   178259967    83886080    7  HPFS/NTFS/exFAT
/dev/vda3       178259968   241174527    31457280   83  Linux
实做的方法有点像底下这样:
windows 10 在 /dev/vda2 亦即是 hd0,msdos2 这个地方,而 MBR 则是 hd0 即可,不需要加上分割槽啊! 因此整个设定会变这样:
另外,如果每次都想要让 windows 变成预设的开机选项,那么在 /etc/default/grub 当中设定好『 GRUB_DEFAULT=win10 』 然后再次 grub2-mkconfig 这样即可啦! 不要去算 menuentry 的顺序喔! 透过 --id 内容来处理即可!
[root@study ~]# vim /etc/grub.d/40_custommenuentry 'Go to Windows 10' --id 'win10' {
        insmod chain
        insmod ntfs
        set root=(hd0,msdos2)
        chainloader +1
}
menuentry 'Go to MBR' --id 'mbr' {
        insmod chain
        set root=(hd0)
        chainloader +1
}

[root@study ~]# grub2-mkconfig -o /boot/grub2/grub.cfg

不同的文件系统允许安装 grub 的区块并不相同。 XFS 文件系统似乎没有预留 boot sector 给 boot loader 使用, 因此 XFS 并不能安装独立的 boot loader。 如果你想要让每个独立的 OS 都有自己的 boot sector,那么就得要使用 ext2 家族, 例如 ext4 才行!

至于 UEFI 的开机管理方式与 BIOS 并不相同,处理上就不能使用本章节的方式了!

13.2.5:开机档案的救援问题

一般来说,如果是档案系统错误,或者是某些开机过程中的问题,我们可以通过开机时进入 grub2 的交互界面中, 在 linux 的字段,加入 rd.break 或者是 init=/bin/bash 等方式来处理即可。 但是,如果是 grub2 本身就有问题, 或者是根本就是核心错误,或者是 initramfs 出错时,那就无法通过上述的方式来处理了。

在CentOS 7的操作经验中,在升级核心时,偶而会有initramfs制作错误的情况导致新核心无法开机的问题。 此时,若你已经没有保留旧的核心,此时就无法顺利开机了。 在CentOS 8里面倒是比较少出现这样的问题。

但若是发生这问题是,最常见的解决方法有两个:

  • 第一个比较单纯,如果还有之前旧版的核心存在,请使用旧版核心开机,正常进入系统之后,以dracut重建 initramfs 即可;

  • 第二个方法比较特别,如果无法使用旧核心开机,那请透过原版光盘开机,然后使用救援模式(rescue)来自动侦测硬盘系统,再透过 chroot 的动作取回到原本的系统环境,再以 dracut 来重建 initramfs '即可。

例题 13.2.5-1: 重建新版核心的 initramfs 虚拟根目录系统
  1. 观察你的系统内的核心版本,务必要有两个核心版本以上的环境 (若无两个环境,请依据前几章的内容升级一个新的核心)

  2. 重新开机后,使用旧版核心开机,并确认确实为旧版核心。

  3. 前往 /boot目录,将新版的 initramfs 暂时更名为其他档案,例如扩展名增加 .raw 之类的方式。

  4. 使用dracut重新建置该新版核心的initramfs,且文件名最好与原本的文件名相同。 另外,新建此initramfs时,加入ixbge这个网络卡模组。

  5. 重新开机之后,选择新核心开机,看看是否可以顺利开机进入系统。

如果是一开始安装就出事,那就得要透过底下的方案来处理了! 下面是模拟进入光盘救援模式的方式:

  1. 调整 BIOS 变成光盘启动 (或 USB 开机),同时放入原版光盘,之后开机

  2. 进入光盘安装模式后,选择' Troubleshooting '的项目,再选择' Rescue a CentOS Linux system '环境

    • 此时系统会自动侦测硬盘,然后加载适当的模块,之后应该会找到我们的硬盘

    • 当出现 1)Continue, 2)Read-only mount, 3)Skip to shell, 4)Quit(reboot) 时,按下 1 即可!

    • 若一切都顺利,光盘环境会提供' chroot /mnt/sysimage '指令,作为切换成原本系统的手动。

  3. 进入 shell 环境后,输入『 df』应该会看到原本系统资料通通挂载在 /mnt/sysimage 底下, 因此请使用『 chroot /mnt/sysimage 』指令来进入原本的系统。

  4. 接下来请按照上一题的流程来重新建置好你的initramfs档案即可。

  5. 将 initramfs 建置完毕后,还得要进行底下的流程才能够离开系统喔:

    sh4.2# touch /.autorelabelsh4.2# exit   sh4.2# reboot

13.3:课后练习操作

  • 上课的课后练习,非作业:

  1. 想出并执行两种重新装入 (reload) atd 的方法

  2. 一般来说,服务器系统通常不会启动图形化见面,所以,请让你的系统变成默认文字界面,然后有需要再登入切换成为图形界面即可。

  3. 尝试启动名为 vsftpd 的 FTP 网络服务。

  4. 强迫使用' network-latency '的 tuned 环境优化设定

  5. 让系统尽量少用 swap 的功能,同时减少 dirty page (磁盘与内存异步) 的要求,将底下的数据修改: 且每次系统开机都会生效!

    /proc/sys/vm/dirty_ratio            改成 40
    /proc/sys/vm/dirty_background_ratio 改成 5
    /proc/sys/vm/swappiness             改成 10
  6. 以现有的新的核心制作一个新的开机菜单,该选单每次都会主动进入图形界面,且预设开机菜单会指向这个图形界面的菜单!

  • 作业 (不提供学生答案,仅提供教师参考答案)

作业硬盘操作帮助:

  • 开启云端虚拟机前,请务必确认你开启的硬盘是'unit13',否则就会做错题目

  • 若要使用图形界面,请务必使用 student 身份登入,若需要切换身份,再启用终端机处理。

  • 若有简答题需要使用中文,请自行以第一堂课的动作自行处理输入法安装。

  • 每部虚拟机均有独特的网卡地址,请勿使用他人硬盘上传,否则计分为 0 分。

  • 每位同学均有自己的 IP 尾数,请先向老师询问您的 IP 尾数,才可以进行作业上传。

  • 最终上传作业结果,请务必使用 root 身份上传。

  • 进入操作硬盘后,先用 root 身份执行 vbird_book_setup_ip, 执行流程请参考:vbird_book_setup_ip

作业当中,某些部份可能为简答题~若为简答题时,请将答案写入 /home/student/ans.txt 当中,并写好正确题号,方便老师订正答案。 请注意,文件名写错将无法上传!


请使用 root 的身份进行如下实做的任务。 直接在系统上面操作,操作成功即可,上传结果的程序会主动找到你的实做结果。

  1. (20%) 系统救援:

    • 你目前这个系统上,由于某些缘故, initramfs 文件已经遗失,所以应该是无法成功开机到正常的系统中。

    • 请使用原版光盘进入系统救援的模式,并依据系统既有的核心版本 (/lib/modules/),将 initramfs 重建

    • 注意,重建时,应考虑 grub2 的原本设定文件 (参考 /boot/loader/entries/),以找到正确的文件名,方可顺利成功开机喔

    • 不要忘记了,如果顺利开机成功,请记得执行 vbird_book_setup_ip 设定好学号与 IP

  2. (20%) 请回答下列问题,并将答案写在 /root/ans13.txt 文件内:

    1. 管理系统的 process 时,通常是使用给予信号 (signal) 的方式。 而手动给予 Signal 的指令常见有哪两个?

    2. 承上,常见的 signal 有 1, 9, 15, 19,各代表甚么意思?

    3. 在 CentOS 8 系统上,所有的 systemd 服务脚本 (无论有没有 enable) 放在哪个目录内?

    4. 承上,但是系统【默认开机会加载】的脚本,又是放在哪个目录内?

    5. systemd 会将服务进行分类,主要分为 X.service, X.socket, X.target,请问这几个类型分别代表甚么意思?

    6. 在此课堂上,启动系统默认的网络服务,可以使用那五个口诀来处理? 每个口诀对应的指令为何?

  3. (20%) Systemd 的操作与核心功能

    1. 透过网络服务监听埠口观察的指令查出系统有多少服务在启动? 无论如何,请将服务关闭到只剩下 tcp 的 port 22 与 port 111 两个。 在底下有其他服务启动后,自然会有多的埠口,不过在这个题目前,只能有这两个埠口的存在。

    2. 让这部 Linux 主机,默认会启动在纯文字模式下,亦即开机时,默认不会有图形界面

    3. 让系统默认启动IP转递(IP forward)的功能,同时修改dirty_ratio成为60,dirty_background_ratio为3

    4. 系统开机之后,会自动寄出一封 email 给 root,说明系统开机了。 指令可以是' echo "reboot new" | mail -s 'reboot message' root ', 请注意,这个动作必须是系统'自动于开机完成后就动作',而不需要用户或管理员登入喔!

  4. (20%) 默认服务的启动

    1. 让系统使用' network-latency '的最佳化参数处理系统的优化功能。

    2. 请依据课堂上的服务启动口诀,启动 WWW 服务,WWW 服务使用 httpd 这个软件。 并假设你知道 WWW 的首页目录位于 /var/www/html/ 以及首页文件名为 index.html。 请在 index.html 内以 vim 新建两行,分别是学号与姓名。

    3. 请依据课堂上的服务启动口诀,启动 FTP 服务,FTP 服务使用 vsftpd 这个软件。 并假设你知道 FTP 的首页目录在 /var/ftp ,你要让 /etc/fstab 提供给客户端以 ftp://your.server.ip/pub/fstab 的网址下载,该如何复制 /etc/fstab 到正确的位置去?

  5. (20%) grub2 相关应用

    1. 修改开机时的预设值,让菜单等待达到30秒

    2. 让开机时,核心加入 noapic 及 noacpi 两个预设参数

    3. 在 grub2 主配置文件中增加一个菜单,菜单名称为【 Go go MBR 】,透过 chainloader 的方式,让这个菜单出现在开机时的选择画面中 (但是,默认值还是正常的 Linux 开机菜单)

    4. 在 /boot/loader/entries/ 中,建立名为 custom.conf 的菜单文件,从最新的核心菜单文件复制相关参数到此文件中, 然后再建立一个名为【Graphical Linux】的菜单,这个菜单会强制进入图形界面,而不是预设的文本界面。 (hint: systemd.unit=???)

作业结果传输:请以 root 的身份执行 vbird_book_check_unit 指令上传操作结果。 正常执行完毕的结果应会出现【XXXXXX_aa:bb:cc:dd:ee:ff_unitNN】字样。 若需要查阅自己上传资料的时间, 请在操作系统上面使用浏览器查询: http://192.168.251.254 检查相对应的课程档案。 相关流程请参考: vbird_book_check_unit


©著作权归作者所有:来自ZhiKuGroup博客作者没文化的原创作品,如需转载,请注明出处,否则将追究法律责任 来源:ZhiKuGroup博客,欢迎分享。

评论专区
  • 昵 称必填
  • 邮 箱选填
  • 网 址选填
◎已有 0 人评论
搜索
作者介绍
30天热门
×
×
本站会员尊享VIP特权,现在就加入我们吧!登录注册×
»
会员登录
新用户注册
×
会员注册
已有账号登录
×