troubleshoot:文件系统挂载错误致系统启动失败

1763789078147.jpg

今天启动虚拟机直接进紧急模式了,大概率是因为/etc/fstab文件配置错误:例如你之前挂载了一个磁盘,后来把磁盘删了,但忘记删除配置文件里的挂载项。

获取root权限之后使用:

1
journalctl -xb | grep failed

查看日志。

Job dev-sdb1.device/start failed with result ‘timeout’ (等待 sdb1 设备超时)

Dependency failed for mnt-data.mount - /mnt/data (因为找不到设备,所以无法挂载到 /mnt/data)
a
系统找不到 /dev/sdb1 这个分区。

问题就锁定好了。

troubleshoot

  1. 获取写权限:现在的系统通常是“只读”的,必须先重新挂载为“读写”模式,否则无法保存修改。输入以下命令并回车:
1
mount -o remount,rw /
  1. 修改配置文件,把之前关于/dev/sdb1的那一行注释掉。
1
vi /etc/fstab
  1. reboot

复盘

问题的根源是我新添加了一块和这个/dev/sdb完全一样大小的磁盘。这在 Linux 运维中是非常经典的“盘符漂移”事故。

发生了什么?

Linux 系统分配 /dev/sda, /dev/sdb 等名字的规则极其简单粗暴:排队领号,先到先得。它不认硬盘的“脸”(数据),只认硬盘“进门”的顺序。

  1. 以前的情况:

    • 系统盘 -> 抢到了 sda
    • 你的数据盘 -> 抢到了 sdb
    • /etc/fstab 里写着:“启动时去挂载 /dev/sdb1
  2. 刚才的操作:

    • 你加了一块新硬盘。
    • 在虚拟机的底层(SCSI 总线)顺序中,这块新硬盘可能插在了旧硬盘的前面(或者仅仅是因为扫描顺序的随机扰动)。
  3. 现在的启动顺序(漂移发生):

    • 系统盘 -> 依然是 sda
    • 新硬盘 -> 被内核先发现了,它抢走了 sdb 的名字。
    • 旧硬盘(原本的数据盘) -> 被挤到了后面,变成了 sdc
  4. 为什么会报错 Timeout?

    • 系统根据 /etc/fstab 去找 /dev/sdb1
    • 现在的 /dev/sdb 是刚加的那块崭新的空盘
    • 空盘没有分区,自然就没有 sdb1 这个分区设备。
    • 系统找不到 sdb1,等了 90 秒(默认超时时间),最后报错 Timeout,被踢进紧急模式。

建议使用UUID来作为盘名

VirtualBoxVM_RQzNBudtvu.png

使用lsblk我们可以看到那个我们曾经的数据盘的确到/dev/sdc1上去了。

  1. 查看真·数据盘的 UUID:

    1
    blkid /dev/sdc1

    复制输出的 UUID="xxxx-xxxx..." 那一串。

  2. 修改 /etc/fstab
    把:

    1
    /dev/sdb1  /mnt/data  xfs  defaults  0 0

    改成:

    1
    UUID=刚刚复制的UUID  /mnt/data  xfs  defaults  0 0

VirtualBoxVM_I76zkBZIpH.png

这样改完后,无论以后加多少硬盘,插在什么顺序,系统都只认这个“身份证号”,再也不会认错人了。

Linux 管理逻辑卷LVM

本文将介绍 Linux 中逻辑卷管理 (LVM) 的概念,它们是比传统分区更高级的存储管理技术。

1. LVM (Logical Volume Management)

LVM 是一种强大的存储管理技术,它允许你将多个物理磁盘或分区组合成一个或多个“卷组” (Volume Groups),然后在这些卷组之上创建灵活的“逻辑卷” (Logical Volumes)。

核心优势

  • 灵活性:可以轻松地调整逻辑卷的大小(扩大或缩小),而无需关心底层物理磁盘的布局。
  • 抽象化:将物理存储抽象化,使存储管理更加便捷。
  • 跨磁盘:一个逻辑卷可以跨越多个物理磁盘。

LVM 架构

LVM 的架构分为几个层次,从底层到顶层依次是:

Acrobat_oX1rBT6fuN.png

  1. 硬盘 (Hard Disks):物理存储设备,如 /dev/sda, /dev/sdb
  2. 分区 (Partitions):在硬盘上划分出的区域,需要将类型设置为 “Linux LVM”。
  3. 物理卷 (Physical Volumes - PV):将 LVM 类型的分区初始化后得到的,是 LVM 的基本构建块。
  4. 卷组 (Volume Groups - VG):一个或多个物理卷组成的存储池。
  5. 逻辑卷 (Logical Volumes - LV):从卷组中划分出的“虚拟分区”,可以像普通分区一样被格式化和挂载。
  6. 文件系统 (File System):在逻辑卷之上创建的文件系统,如 XFS, ext4。

图示解读:

  • 多个物理磁盘 (Disks) 被组合成一个卷组 (Volume Group)。
  • 从卷组中可以划分出多个逻辑卷 (Logical Volumes),例如 home, system, data1 等。
  • 这些逻辑卷可以被挂载到不同的目录,如 /, /home, /data1

Acrobat_QzYRN2lTUw.png

2. LVM 操作场景:扩容磁盘

当一个文件系统(例如 /oracle)空间不足时,LVM 提供了非常灵活的解决方案。

问题场景

假设 /oracle 目录挂载在一个 1GB 的逻辑卷上,现在空间已满。

解决方案

你有以下几种选择:

  • 清理文件:删除旧的或不再需要的文件以释放空间。
  • 添加新物理磁盘:添加一块全新的硬盘,创建分区、物理卷,然后将其加入现有的卷组,最后扩容逻辑卷。
  • 添加新虚拟磁盘:与添加物理磁盘类似,但操作在虚拟化层完成。
  • 通过 LVM 扩容:这是 LVM 最强大的功能之一。如果卷组中还有未分配的空间,可以直接扩展逻辑卷,然后扩展文件系统。

3. 实验:LVM 创建与管理

下面我们通过一个完整的实验来演示如何从一块新磁盘开始创建和管理 LVM。

准备工作:添加新磁盘并分区

首先,为虚拟机添加一块新的虚拟硬盘(本例中为 1GB)。然后使用 fdisk 对其进行分区。

注意:请根据你的环境确认新磁盘的设备名,例如 /dev/sdb, /dev/sdc 等。

1
fdisk /dev/sdb

VirtualBoxVM_tgl7RMmkEs.png

fdisk 交互界面中,按 n 创建一个新分区。

步骤 1: 修改分区类型为 “Linux LVM”

创建完分区后,不要立即写入退出。我们需要将分区类型更改为 LVM。

  1. t (change a partition’s system id).
  2. 系统会提示输入 Hex code。可以按 L 查看所有支持的类型。
  3. 找到 “Linux LVM” 对应的代码,通常是 8e
  4. 输入 8e 并回车。

VirtualBoxVM_kdZyWfuBRc.png

VirtualBoxVM_dVUPcdZXT2.png

步骤 2: 保存分区表并创建物理卷 (PV)

  1. fdisk 中按 w 保存更改并退出。

VirtualBoxVM_JOrWHPBagk.png

  1. 使用 pvcreate 命令在新创建的分区上初始化物理卷。
1
pvcreate /dev/sdb1

VirtualBoxVM_jigkScShRG.png

检查: 你可以使用 pvdisplay 命令查看物理卷的详细信息。

步骤 3: 创建卷组 (VG)

使用 vgcreate 命令创建一个名为 oracle_vg 的新卷组,并将刚才创建的物理卷 /dev/sdb1 添加进去。

1
vgcreate oracle_vg /dev/sdb1

VirtualBoxVM_6DwJ6paE0e.png

步骤 4: 创建逻辑卷 (LV)

从卷组 oracle_vg 中划分出一部分空间来创建逻辑卷。

  • -n oracle_lv: 指定逻辑卷的名称为 oracle_lv
  • -L 500M: 指定逻辑卷的大小为 500MB。
  • oracle_vg: 从 oracle_vg 卷组中分配。
1
lvcreate -n oracle_lv -L 500M oracle_vg

VirtualBoxVM_wlbMuOBTkw.png

步骤 5: 创建文件系统并挂载

逻辑卷创建后,它是一个原始的块设备。我们需要在上面创建文件系统才能使用。

  1. 格式化逻辑卷 (路径通常是 /dev/卷组名/逻辑卷名)。
1
mkfs.xfs /dev/oracle_vg/oracle_lv
  1. 创建挂载点并挂载。
1
2
mkdir /oracle
mount /dev/oracle_vg/oracle_lv /oracle

VirtualBoxVM_fmwKuEchmb.png

4. 实验:LVM 扩容

现在,我们模拟一个场景:/oracle 目录空间不足,需要扩容。

准备工作:添加新磁盘

我们添加一块新的 512MB 虚拟磁盘,并重复之前的分区步骤,将其分区类型也设置为 8e (Linux LVM)。

VirtualBox_vav1sSOK2G.png

VirtualBoxVM_lj8sBPqT2n.png

注意: 添加新硬件后,建议重启或使用 partprobe 等命令让系统重新扫描磁盘。重启后请用 fdisk -l 再次确认新磁盘的设备名(例如 /dev/sdc)。

VirtualBoxVM_NIsrwTd5u5.png

步骤 1: 创建新的物理卷 (PV)

在新磁盘的分区(例如 /dev/sdc1)上创建物理卷。

1
pvcreate /dev/sdc1

VirtualBoxVM_U6T4WIqYrO.png

步骤 2: 扩展卷组 (VG)

使用 vgextend 命令将新的物理卷加入到现有的 oracle_vg 卷组中,为卷组增加容量。

1
vgextend oracle_vg /dev/sdc1

检查: 此时使用 vgdisplay oracle_vg,你会看到卷组的总大小 (VG Size) 已经增加了。

步骤 3: 扩展逻辑卷 (LV)

使用 lvextend 命令来扩展逻辑卷。

  • -L +512M: 表示在原有基础上增加 512MB。你也可以用 -l +100%FREE 来使用卷组中所有剩余的空闲空间。
  • /dev/oracle_vg/oracle_lv: 你要扩展的目标逻辑卷。
1
lvextend -L +512M /dev/oracle_vg/oracle_lv

VirtualBoxVM_0QbTNw0zt0.png

步骤 4: 扩展文件系统

最后一步是通知文件系统去使用新增加的空间。这是非常关键的一步,否则空间虽然分配了,但操作系统无法使用。

对于 XFS 文件系统,使用 xfs_growfs 命令。

1
xfs_growfs /oracle

对于 ext2/3/4 文件系统,使用 resize2fs 命令。

1
# resize2fs /dev/oracle_vg/oracle_lv  (ext4示例)

VirtualBoxVM_JQjPhpxp6c.png

最终检查

使用 df -h 命令检查 /oracle 目录,可以看到文件系统的大小确实已经扩展成功。

VirtualBoxVM_C7zbaQP9YM.png

Linux 管理基本存储

本文将介绍 Linux 中的基本存储概念,并提供一个从添加新硬盘到分区、格式化、并最终挂载使用的完整分步教程。

1. 核心概念

存储类型

首先,了解三种主要的存储类型:

  • 本地存储 (Local Storage):直接连接到计算机的物理磁盘,如 /dev/sda
  • SAN (Storage Area Network):一种专用的高速网络,用于将存储设备连接到服务器,通常表现为块设备。
  • NAS (Network Attached Storage):一种专用的文件存储服务器,通过网络(如 NFS 或 SMB)向客户端提供文件服务。

常用命令

以下是管理磁盘和分区的两个基础命令:

  • df:报告文件系统的磁盘空间使用情况。使用 -h 选项可获得更易读的输出。
    df -h 命令的输出
  • fdisk:一个强大的分区表编辑器。使用 fdisk -l 可以列出所有磁盘的分区信息。
    fdisk -l 命令的输出

理解 fdisk -l 的输出

以上图为例,物理硬盘 /dev/sda (一个 40 GiB 的 VBOX 硬盘) 被分成了三个主分区:

Device Size Type 描述
/dev/sda1 1M BIOS boot 用于 BIOS 启动的引导分区。
/dev/sda2 1G Linux extended boot 一个扩展的 Linux 启动分区。
/dev/sda3 39G Linux LVM LVM (逻辑卷管理) 分区,它本身可容纳多个逻辑卷。

什么是逻辑卷 (LVM)?

你可能注意到截图中还有两个 “Disk”:

  • Disk /dev/mapper/rhel-root (36.95 GiB)
  • Disk /dev/mapper/rhel-swap (2.04 GiB)

这些不是物理分区,而是逻辑卷 (Logical Volumes)。它们都位于 /dev/sda3 (Linux LVM) 物理分区内部。LVM 是一种高级磁盘管理技术,它允许在物理分区之上创建灵活的逻辑卷,可以轻松地调整大小、迁移数据,而无需改动底层的物理分区。

  • rhel-root 是根文件系统 ( / )。
  • rhel-swap 是交换空间 (swap)。

2. 教程:添加、分区和挂载新磁盘

本节将演示如何为系统添加一块新硬盘,并投入使用。

重要提示:以下操作涉及磁盘修改,建议在虚拟机中进行,并提前创建快照以便在出错时恢复。

步骤 1: 添加新磁盘 (物理或虚拟)

我通过 VirtualBox 为虚拟机添加了一块 1GB 的新虚拟磁盘。

通过 VirtualBox 设置添加新磁盘

创建 VDI 格式的 1GB 磁盘

添加后,重启虚拟机。使用 fdisk -l 命令,你应该能看到新添加的磁盘,例如 /dev/sdb

fdisk 确认新磁盘 /dev/sdb

步骤 2: 为新磁盘创建分区 (fdisk)

  1. 运行 fdisk /dev/sdb 进入分区编辑器。
    运行 fdisk /dev/sdb
  2. 在提示符下输入 n 创建一个新分区。
  3. 按照提示配置分区类型、起始和结束扇区(通常可以直接接受默认值以使用整个磁盘)。
  4. 最后,输入 w 将分区表写入磁盘并退出。
    fdisk 创建新分区并保存

再次运行 fdisk -l /dev/sdb,可以看到新的分区(如 /dev/sdb1)已经创建成功。

步骤 3: 创建文件系统 (mkfs)

分区创建后,需要对其进行格式化,即创建一个文件系统。这里我们使用 XFS 文件系统作为示例。

1
mkfs.xfs /dev/sdb1

mkfs.xfs 格式化分区

步骤 4: 挂载文件系统 (mount)

什么是挂载?
在 Linux 中,挂载 (Mounting) 是将一个存储设备(或其上的文件系统)附加到主文件系统树上的一个目录(称为“挂载点”)的过程。一旦挂载完成,对该挂载点目录的任何读写操作都会被透明地重定向到所附加的设备上。

  1. 首先,创建一个目录作为挂载点:
    1
    mkdir /mnt/data
  2. 然后,将新分区挂载到该目录:
    1
    mount /dev/sdb1 /mnt/data
  3. 使用 df -h 验证挂载是否成功。
    mount 命令挂载分区

这种挂载是临时的,系统重启后会失效。

步骤 5: 实现永久挂载 (/etc/fstab)

为了让系统在每次启动时自动挂载该分区,我们需要编辑 /etc/fstab 文件。

在文件末尾添加一行:

1
/dev/sdb1    /mnt/data    xfs    defaults    0 0

编辑 /etc/fstab 实现永久挂载

现在,你可以使用 rebootinit 6 重启系统。重启后,再次使用 df -h 查看,分区应该被自动挂载了。

重启后验证永久挂载

3. 总结与思考

取消挂载

你可以随时使用 umount 命令来卸载一个分区(请注意是 umount 而不是 unmount):

1
umount /mnt/data

思考题解答

问题:如果在 /etc/fstab 中配置了永久挂载,然后手动执行 umount,那么重启后挂载还会生效吗?

答案会生效umount 命令只对当前会话有效,它会临时卸载文件系统。但由于 /etc/fstab 的配置会在系统每次启动时被读取和执行,因此下次重启后,该分区依然会被自动挂载到指定的挂载点。

Linux 管理 SELinux 安全性 (补图中)

什么是 SELinux?

  • Security-Enhanced Linux (SELinux) 是一个 Linux 内核安全模块,它提供了一种支持访问控制安全策略的机制,包括强制访问控制 (MAC)。
  • 它是美国国家安全局 (NSA) 和 SELinux 社区的一个项目。
  • 与标准的自由访问控制 (DAC)(如 chmod)不同,SELinux 强制执行系统范围的策略,即使是 root 用户也可能受到限制。

image.png

上图解释:在传统的 DAC 模型下,如果 Apache 服务被攻破,攻击者可能获得该进程的所有者权限,从而访问用户主目录中的文件。在 SELinux (MAC) 模型下,即使服务被攻破,SELinux 策略也会阻止它访问策略之外的资源(如用户主目录),除非有明确的规则允许。

SELinux (Security Enhanced Linux)

SELinux 模式

  • Enforcing: 默认启用。强制执行 SELinux 安全策略,阻止并记录所有违反策略的活动。
  • Permissive: 禁用强制执行,但会记录所有违反策略的活动。这对于调试和排查问题非常有用。
  • Disabled: 完全禁用 SELinux,不记录任何活动。

检查 SELinux 状态

您可以使用 sestatusgetenforce 命令来查看 SELinux 的当前状态。

1
2
3
4
5
# 查看详细的 SELinux 状态
sestatus

# 或者只查看当前模式
getenforce

VirtualBoxVM_2QqUku9Tn5.png

SELinux 设置

  • 临时更改模式
    您可以使用 setenforce 命令在 EnforcingPermissive 模式之间切换。这在系统重启后会失效。

    1
    2
    3
    4
    5
    # 切换到 Permissive 模式
    setenforce 0

    # 切换回 Enforcing 模式
    setenforce 1
  • 永久更改模式
    要永久更改 SELinux 模式,需要修改配置文件 /etc/selinux/config

    1
    2
    3
    # 编辑配置文件
    # 将 SELINUX=enforcing 修改为 SELINUX=permissive 或 SELINUX=disabled
    vi /etc/selinux/config

    注意: 修改此文件后需要重启系统才能生效。

  • .autorelabel 文件
    如果在禁用 SELinux 后重新启用它,或者文件系统的 SELinux 标签出现问题,您可以在根目录下创建一个名为 .autorelabel 的空文件,然后重启系统。这会强制系统在下次启动时重新标记所有文件。

    1
    2
    touch /.autorelabel
    reboot

SELinux 的两个核心概念

  • 标签 (Labeling): SELinux 为系统中的每个主体(进程)和客体(文件、目录、端口等)分配一个安全上下文(Context)。
  • 类型强制 (Type Enforcement): SELinux 的主要决策机制。它通过策略规则来控制一个特定类型的主体(如 httpd_t)能否访问一个特定类型的客体(如 httpd_sys_content_t)。

查看文件/目录的 SELinux 标签

  • 使用 ls -lZls -dZ 命令可以查看文件或目录的 SELinux 上下文。

    1
    2
    3
    4
    5
    6
    7
    # 查看 /usr/sbin/httpd 文件的标签
    [root@localhost ~]# ls -lZ /usr/sbin/httpd
    -rwxr-xr-x. root root system_u:object_r:httpd_exec_t:s0 /usr/sbin/httpd

    # 查看 /etc/httpd 目录的标签
    [root@localhost ~]# ls -dZ /etc/httpd
    drwxr-xr-x. root root system_u:object_r:httpd_config_t:s0 /etc/httpd

查看进程和套接字的 SELinux 标签

  • 查看进程标签: 使用 ps axZ

    1
    2
    3
    # 查看 httpd 进程的标签
    [root@localhost ~]# ps axZ | grep httpd
    system_u:system_r:httpd_t:s0 21289 ? Ss 0:00 /usr/sbin/httpd -DFOREGROUND
  • 查看套接字(端口)标签: 使用 netstat -tnlpZ

    1
    2
    3
    # 查看 httpd 监听的端口标签
    [root@localhost ~]# netstat -tnlpZ | grep http
    tcp6 0 0 :::80 :::* LISTEN system_u:system_r:httpd_t:s0 21289/httpd

SELinux 标签(安全上下文)详解

SELinux 标签也称为安全上下文,其标准格式为 user:role:type:level。让我们用 system_u:object_r:httpd_exec_t:s0 这个例子来详细解释每个部分:

  1. User (system_u): 代表 SELinux 用户。这与常规的 Linux 用户账户(如 root)不同。它定义了该用户在 SELinux 策略中的权限范围。system_u 是一个用于系统进程和对象的通用 SELinux 用户。

  2. Role (object_r): 代表 SELinux 角色。它作为“用户”和“类型”之间的桥梁。对于文件、目录等资源(即“客体”),其角色几乎总是 object_r。对于正在运行的进程(即“主体”),您通常会看到 system_r 角色。

  3. Type (httpd_exec_t): 这是日常 SELinux 管理中最关键的部分类型定义了一个文件或进程的“身份”。SELinux 的所有策略规则都是基于类型来制定的。例如:

    • httpd_exec_t: 表示这是一个可供 Apache (httpd) 服务执行的文件。
    • httpd_config_t: 表示这是一个 Apache 服务的配置文件
    • httpd_t: 表示这是正在运行的 Apache 服务进程自身的类型。

    SELinux 的核心机制是“类型强制 (Type Enforcement)”,它会制定类似这样的规则:“类型为 httpd_t 的进程,被允许读取类型为 httpd_config_t 的文件,并执行类型为 httpd_exec_t 的文件。”

  4. Level (s0): 这与一个叫做“多级别安全 (MLS)”的高级功能相关。它定义了一个“敏感度级别”,其中 s0 是最低级别。该机制用于防止信息从高密级流向低密级。在大多数标准服务器配置中,这个值通常固定为 s0,您一般无需关心。

总而言之,在处理 SELinux 问题时,类型 (Type) 是您最需要关注的部分。它精确地告诉 SELinux 系统中的每个文件和进程是什么,以便 SELinux 能够严格执行策略,决定“谁可以对谁做什么”。

管理 SELinux 设置的命令

  • semanage 命令用于管理 SELinux 的设置,包括:
    • login:管理 SELinux 用户到 Linux 用户的映射。
    • user:管理 SELinux 用户。
    • port:管理端口的 SELinux 类型。
    • interface:管理网络接口的 SELinux 类型。
    • module:管理 SELinux 策略模块。
    • node:管理网络节点的 SELinux 类型。
    • file context:管理文件上下文的映射规则。
    • boolean:管理 SELinux 布尔值,用于启用或禁用策略中的特定规则。
    • permissive state:管理域的宽容状态。
    • dontaudit:管理 dontaudit 规则,用于隐藏某些拒绝消息。

使用布尔值和 chcon

SELinux 布尔值 (Boolean)

布尔值是 SELinux 中的一种开关机制(ON / OFF),用于在运行时动态修改策略行为,而无需重写或重新加载整个策略。

  • SELinux 提供了许多预定义的布尔值。

  • 例如,您可以通过布尔值来控制:

    • 是否允许 FTP 服务访问用户主目录 (ftp_home_dir)。
    • Web 服务器是否可以连接到 LDAP 服务器 (httpd_can_network_connect)。
  • 列出所有布尔值及其当前状态

    1
    2
    3
    getsebool -a
    # 或者
    semanage boolean -l
  • 启用或禁用一个布尔值
    使用 setsebool 命令。-P 标志使其永久生效(即重启后保持不变)。

    1
    2
    # 永久开启一个名为 boolean_name 的布尔值
    setsebool -P boolean_name on

检查 SELinux 错误

当 SELinux 阻止某个操作时,相关的错误信息通常会被记录到审计日志中。您可以使用 journalctl 来查看它们。

1
2
# 过滤与 "avc: denied" 相关的日志
journalctl -g "avc: denied"

更改文件或目录的类型标签

在某些情况下,您可能需要手动更改文件或目录的 SELinux 类型以匹配策略。

  • 临时更改 (chcon)
    chcon 命令可以立即更改文件或目录的类型,但这种更改是临时的。如果系统执行了文件系统重新标记 (restorecontouch /.autorelabel),这些更改将会丢失。

    1
    chcon -t httpd_sys_content_t /path/to/your/file
  • 永久更改 (semanage fcontext)
    要进行永久性更改,您应该使用 semanage fcontext 来定义一个文件路径的默认上下文规则,然后使用 restorecon 来应用这个规则。

    1
    2
    3
    4
    5
    # 1. 添加一个新的上下文规则
    semanage fcontext -a -t httpd_sys_content_t "/path/to/your/directory(/.*)?"

    # 2. 应用规则,恢复默认上下文
    restorecon -Rv /path/to/your/directory

Linux ACL 控制文件访问

什么是 ACL?

  • 访问控制列表(ACL)为文件系统提供了一种额外的、更灵活的权限机制。
  • 它旨在辅助标准的 UNIX 文件权限(用户、组、其他)。
  • ACL 允许您为文件或目录的属主和属组之外的特定用户或组设置精细的读、写、执行权限。

ACL 的用途

  • 设想一个场景:用户 alice 需要访问 /data/report.txt,但这个文件属于 bob,属组是 sales,而 alice 不在 sales 组里。在不改变文件所有权或将 alice 加入 sales 组的情况下,ACL 可以轻松地为 alice 单独授予访问权限。
  • 基本上,ACL 用于在 Linux 中实现更灵活、更细粒度的权限管理。

ACL 命令

getfacl:查看 ACL 权限

getfacl 命令用于显示文件或目录的访问控制列表。

  • 查看文件 ACL
    1
    getfacl /path/to/file
    • 输出示例:
      1
      2
      3
      4
      5
      6
      7
      8
      # file: my_file.txt
      # owner: alice
      # group: alice
      user::rw-
      user:bob:r--
      group::r--
      mask::r--
      other::r--

VirtualBoxVM_RKvvoYDfbI.png

setfacl:设置或修改 ACL 权限

setfacl 命令用于修改文件或目录的 ACL。

  • 为用户添加/修改权限 (-m)

    1
    setfacl -m u:bob:rwx /path/to/file
  • 为组添加/修改权限 (-m)

    1
    setfacl -m g:developers:rw /path/to/file
  • 设置默认 ACL (-d)
    默认 ACL 只对目录有效。设置后,在该目录下创建的新文件或子目录会自动继承此默认 ACL。

    1
    2
    # 为目录设置默认 ACL,让新文件自动给 bob 用户读权限
    setfacl -d -m u:bob:r /path/to/dir
  • 移除一个特定的 ACL 条目 (-x)

    1
    setfacl -x u:bob /path/to/file
  • 移除所有扩展 ACL 条目 (-b)
    此命令会移除所有扩展的 ACL 条目,只保留基本的用户、组和其他权限。

    1
    setfacl -b /path/to/file

注意事项

  • ls -l 中的 +
    当一个文件或目录设置了 ACL 后,ls -l 命令显示的权限末尾会有一个 + 号,提示您该文件有扩展的 ACL 权限。

    1
    -rwxr--r--+ 1 alice alice 0 Nov 15 10:30 my_file.txt
  • 文件删除权限
    能否删除一个文件,取决于对该文件所在的父目录是否具有写(w)和执行(x)权限。对文件本身的写权限(w)只允许修改文件内容,与能否删除该文件无关。

Linux 优化系统性能

Linux 系统在默认安装后已经经过了良好的调整,但仍可以根据系统性能和应用程序要求进行一些调整。

什么是 tuned?

  • tuned 的发音是 “tune-d”
  • Tune 用于系统调优,d 代表守护进程
  • 它是一个 systemd 服务,用于调整 Linux 系统性能
  • tuned 软件包的名称是 tuned
  • tuned 服务附带预定义的配置文件和设置
  • 根据选择的配置文件,tuned 服务会自动调整系统以获得最佳性能。例如,如果您正在下载大文件,tuned 将调整网络,或者如果检测到高存储读/写,它将调整 IO 设置
  • tuned 守护进程在服务启动时或选择新的调优配置文件时应用系统设置。

tuned 配置文件

Tuned profile Purpose
balanced 适用于需要在节能和性能之间取得平衡的系统
desktop 源自 balanced 配置文件。提供更快的交互式应用程序响应
throughput-performance 调整系统以实现最大吞吐量
latency-performance 适用于需要低延迟且以功耗为代价的服务器系统
network-latency 源自 latency-performance 配置文件。它启用其他网络调整参数以提供低网络延迟
network-throughput 源自 throughput-performance 配置文件。应用其他网络调整参数以实现最大网络吞吐量
powersave 调整系统以实现最大节能
oracle 针对基于吞吐量性能配置文件的 Oracle 数据库负载进行了优化
virtual-guest 如果在虚拟机上运行,则调整系统以获得最大性能
virtual-host 如果作为虚拟机的主机,则调整系统以获得最大性能

tuned 命令

  • 检查是否已安装 tuned 软件包
    • rpm -qa | grep tuned
  • 如果尚未安装,请安装 tuned 软件包
    • yum install tuned
  • 检查 tuned 服务状态
    • systemctl status|enable|start tuned
    • systemctl enable tuned (在启动时启用)
      VirtualBoxVM_uR9da9NXI9.png
  • 用于更改 tuned 守护进程设置的命令
    • tuned-adm
  • 检查哪个配置文件处于活动状态
    • tuned-adm active 当你想知道系统当前正应用哪一套优化规则时,使用此命令。
  • 列出可用的配置文件
    • tuned-adm list 这会显示一个列表,包含像 balanced, powersave, throughput-performance 等所有可用的预设配置文件,方便您从中选择。
      VirtualBoxVM_6XzVHGPiKq.png
  • 更改为所需的配置文件
    • tuned-adm profile profile-name 切换到指定的性能配置文件。
    • 例如: tuned-adm profile virtual-guest 会将系统优化设置为最适合虚拟机客户机的模式。
  • 检查 tuned 的建议
    • tuned-adm recommend 让 tuned 根据它对您当前系统硬件和状态的分析,推荐一个最合适的配置文件。
  • 关闭 tuned 设置守护进程
    • tuned-adm off 关闭 tuned 的动态调优功能。tuned 将停止监控系统并停止应用任何优化规则。系统参数会恢复到 tuned 干预之前的状态。如果想完全禁用,除了 off 之外,还应该用 systemctl disable –now tuned 来停止并禁用该服务。
  • 通过 Web 控制台更改配置文件
    • 登录到 https://192.168.1.x:9090 (记不记得这是之前我们介绍过的那个Cockpit)
    • Overview -> Configuration -> Performance profile

nice/renice

  • 保持系统微调的另一种方法是通过 nicerenice 命令确定进程的优先级
  • 如果服务器有 1 个 CPU,那么它一次只能执行 1 个计算/进程,而其他进程必须等待(先进先出)
  • 使用 nicerenice 命令,我们可以使系统优先处理某些进程
  • 此优先级可以设置在 40 个不同的级别
  • nice 级别值的范围从 -20(最高优先级)到 19(最低优先级),默认情况下,进程继承其父进程的 nice 级别,通常为 0。

检查进程优先级

  • 检查进程优先级
    • top
  • Ni 值是就是Nice值,是用户空间和优先级,PR 是 Linux 内核使用的进程的实际优先级。在 Linux 系统中,优先级范围是 0 到 139,其中 0 到 99 用于实时,100 到 139 用于用户
    VirtualBoxVM_eh0IlmMQxw.png
  • 也可以通过 ps 命令以及正确的选项查看进程优先级
    • $ ps axo pid,comm,nice,cls --sort=-nice
      VirtualBoxVM_HgLhq1XXrO.png

设置/更改进程优先级

  • 设置进程优先级
    • nice -n # process-name
    • 例如 nice -n -15 top
  • 更改进程优先级
    • renice -n # process-name
    • 例如 renice -n 12 PID

Linux 计划未来任务

Crontab:重复性任务调度

crontab 是 “cron table” 的缩写,它允许用户根据预设的时间表重复执行命令或脚本。这是在固定时间(例如每天、每周、每月)自动执行维护任务、备份或其他常规操作的理想选择。

主要命令

您可以使用 crontab 命令管理您的定时任务:

  • crontab -e:编辑当前用户的 crontab 文件。如果是第一次运行,系统可能会提示您选择一个文本编辑器。
  • crontab -l:列出当前用户的所有 cron jobs。
  • crontab -r(请谨慎使用) 删除当前用户的所有 cron 任务。
  • crontab -i:在删除前进行提示,通常与 -r 结合使用 (crontab -ri) 以增加安全性。

Crontab 语法

crontab 文件中的每一行都代表一个任务,并遵循以下格式:

1
分 时 日 月 周 命令
  • 分 (Minute): 0 - 59
  • 时 (Hour): 0 - 23
  • 日 (Day of Month): 1 - 31
  • 月 (Month): 1 - 12 (或使用 JAN, FEB, MAR 等)
  • 周 (Day of Week): 0 - 7 (0 和 7 都代表星期日,或使用 SUN, MON, TUE 等)
  • 命令 (Command): 您希望执行的命令或脚本的绝对路径。

特殊字符

  • * (星号): 代表所有可能的值。例如,在“小时”字段中表示“每小时”。
  • , (逗号): 用于指定一个列表。例如,1,15,30 在“分钟”字段中表示在第1、15和30分钟执行。
  • - (连字符): 用于指定一个范围。例如,1-5 在“周”字段中表示从星期一到星期五。
  • / (斜杠): 用于指定步长。例如,*/10 在“分钟”字段中表示“每10分钟”。

使用样例

  1. 每天凌晨2点执行备份脚本:

    1
    0 2 * * * /home/user/scripts/backup.sh
  2. 每小时的第15分钟和第45分钟执行一次检查:

    1
    15,45 * * * * /home/user/scripts/check.sh
  3. 在每个工作日(周一至周五)的下午5点发送报告:

    1
    0 17 * * 1-5 /home/user/scripts/send_report.sh
  4. 每10分钟执行一次监控脚本:

    1
    */10 * * * * /home/user/scripts/monitor.sh
  5. 每月的第一天上午9点清理临时文件:

    1
    0 9 1 * * /home/user/scripts/clean_tmp.sh

重要提示: cron 在一个最小化的环境中运行,这意味着您在 .bashrc.profile 中设置的环境变量可能不会被加载。因此,在您的脚本中,强烈建议始终使用命令和文件的绝对路径(例如,使用 /bin/rm 而不是 rm)。

VirtualBoxVM_0ou3cuoUMj.png

现在的RHEL10已经有了删除自动备份的功能…

VirtualBoxVM_gKiHXfV81F.png


at:一次性任务调度

at 命令用于安排一个命令或脚本在未来的某个特定时间点执行一次。这对于不需要重复的、一次性的任务非常有用。

在使用 at 之前,请确保 atd 服务正在运行。您可以使用 sudo systemctl status atd 来检查其状态。

主要命令

  • at [时间]:开始一个交互式的 at 会话,在 at> 提示符下输入您想执行的命令。按 Ctrl+D 保存并退出。
  • atqat -l:列出当前用户所有待处理的 at 任务。
  • atrm [任务编号]at -d [任务编号]:删除一个已安排的 at 任务。
  • at -c [任务编号]:查看指定任务的具体内容。
  • at -f [文件] [时间]:从指定文件中读取命令并在指定时间执行。

时间格式

at 命令在时间格式上非常灵活:

  • 绝对时间: HH:MM (例如 14:30), HH:MM AM/PM (例如 02:30 PM)。
  • 关键字: now, midnight (午夜), noon (中午), teatime (下午4点)。
  • 相对时间: now + N minutes/hours/days/weeks (例如 now + 1 hour)。
  • 日期: today (今天), tomorrow (明天), 或具体的日期如 Jan 31, 2025-12-25

使用样例

  1. 10分钟后重启服务器:

    1
    echo "sudo reboot" | at now + 10 minutes
  2. 明天下午3点发送一个提醒:
    (进入交互模式)

    1
    at 3pm tomorrow

    然后输入:

    1
    2
    at> echo "记得参加会议" | wall
    at> (按 Ctrl+D 结束)

    wall 命令会将消息广播给所有登录的用户。

  3. 在2025年12月31日的23:59执行一个脚本:

    1
    at -f /home/user/scripts/end_of_year.sh 23:59 12/31/2025
  4. 查看并删除一个任务:
    首先,列出所有任务:

    1
    2
    3
    atq
    # 假设输出显示任务号为 4
    # 4 Fri Nov 14 15:00:00 2025 a user

    然后,删除这个任务:

    1
    atrm 4

Linux Shell入门

Linux shell 脚本是系统管理员用来自动执行日常重复性任务的强大工具。

Shell简介

  • 什么是 Shell?
    • 它就像一个容器
    • 用户和内核/操作系统之间的接口
    • CLI 是一个 Shell
  • 查找您的 Shell
    • echo $0
    • 可用的 Shell “cat /etc/shells
      VirtualBoxVM_KGa19AcOH9.png
    • 那些用户们的 Shell?/etc/passwd (如果这个文件里面的内容是什么你忘记了,那你就应该要复习了)
  • Windows GUI 是一个 shell
  • Linux KDE GUI 是一个 shell
  • Linux sh、bash 等都是 shell

Shell脚本

  • 什么是 Shell 脚本?
    • shell 脚本是一个可执行文件,其中包含按顺序执行的多个 shell 命令。该文件可以包含:
    • Shell (#!/bin/bash)
    • 注释 (# comments)
    • 命令 (echo, cp, grep 等)
    • 语句 (if, while, for 等)
  • Shell 脚本应具有可执行权限(例如 -rwxr-xr-x
  • Shell 脚本可以从绝对路径调用(例如 /home/userdir/script.bash
  • 如果从当前位置调用,则为 ./script.bash

VirtualBoxVM_8ZjB94MngO.png

这个例子就是想要告诉你,你需要赋予该脚本文件可执行权限。

我们再写一个别的试试看?

VirtualBoxVM_g3SNULXNQv.png

Shell 变量例

VirtualBoxVM_dXJ0I2osJZ.png

Shell 获取用户输出

VirtualBoxVM_jujQamtBu9.png

VirtualBoxVM_iD4y7sPlQ4.png

shell是空格敏感的,建议定义变量的时候等号左右两边不要有任何空格。

Shell 脚本 - 基本脚本

  • 使用 echo 输出到屏幕
  • 创建任务
    • 告诉您的 id、当前位置、您的文件/目录、系统信息
    • 创建文件或目录
    • 输出到文件 “>
  • 通过脚本过滤/文本处理器 (cut, awk, grep, sort, uniq, wc)

if-then 脚本

  • If then 语句
    • If this happens = do this
    • Otherwise = do that

VirtualBoxVM_Szp4KJ0pdP.png

我们再随便写一个别的例子:

VirtualBoxVM_wrrs9ox1sX.png

For-Loop 脚本

  • For 循环
    • Keep running until specified number of variable
    • e.g: variable = 10 then run the script 10 times
    • OR
    • variable = green, blue, red (then run the script 3 times for each color.

VirtualBoxVM_AHARnsN3BW.png

VirtualBoxVM_eJNjG6LWnW.png

grep/egrep - 文本处理器命令

  • 什么是 grep?
    • grep 命令代表“全局正则表达式打印”,它逐行处理文本并打印与指定模式匹配的任何行
  • grep --versiongrep --help = 检查版本或帮助
  • grep keyword file = 从文件中搜索关键字
  • grep -c keyword file = 搜索关键字并计数
  • grep -i KEYword file = 搜索关键字忽略大小写
  • grep -n keyword file = 显示匹配的行及其行号
  • grep -v keyword file = 显示除关键字外的所有内容
  • grep keyword file | awk '{print $1}' = 搜索关键字然后只给出第一个字段
  • ls -l | grep Desktop = 这个你肯定知道什么意思
  • egrep -i "keyword|keyword2" file = 搜索 2 个关键字。

VirtualBoxVM_Ib6tN0ffoT.png

你可以将这些选项组合使用,请问你-vi选项是什么意思呢?

Linux 分析服务器和获取支持

  • 当您的 Linux Redhat 服务器出现问题时,您将需要使用 topfreedfdu 等监控命令。系统管理员还应查看 /var/log 目录中的系统日志,然后联系 Redhat 技术支持以获取更多帮助。
  • Redhat 使系统管理员可以更轻松地使用名为 Cockpit 的基于 Web 的应用程序来管理和分析服务器。
  • 要从 Redhat 获得支持,系统管理员可以在 Linux 系统上以 root 用户身份运行 sosreport 实用程序或在较新版本中运行 “sos report”,该实用程序将收集日志和配置文件,然后将它们传输到 Redhat 支持服务器。现在使用 Cockpit 应用程序,可以在基于 Web 的门户网站上生成报告。

获取Redhat为你提供的case id之后,你就可以向他们上传你的日志了。
VirtualBoxVM_fsOVCMhvnk.png

  • Cockpit 基于 Web 的界面除了可以从 Redhat 进行监控和获得支持外,还提供了许多其他功能。

Cockpit

  • Cockpit 是由 Red Hat 赞助的服务器管理工具,专注于提供现代化且用户友好的界面来管理和维护服务器。
  • Cockpit 是一个易于使用、集成、一目了然且开放的基于 Web 的服务器界面。
  • 该应用程序可在大多数 Linux 发行版中使用,例如 CentOS、Redhat、Ubuntu 和 Fedora。
  • 它在 Redhat 8 中默认安装,在版本 7 中是可选的。
  • 它可以通过一个非常易于访问的 Web 连接来监控系统资源、添加或删除帐户、监控系统使用情况、关闭系统以及执行其他一些任务。

安装、配置和管理 Cockpit

  • 检查网络连接

    • ping www.google.com
  • 以 root 用户身份安装 cockpit 软件包

    • yum/dnf install cockpit -y (适用于 RH 或 CentOS)
      VirtualBoxVM_5VW4spMjjM.png
      我这里是已经安装过了
    • apt-get install cockpit (适用于 Ubuntu)
  • 启动并启用该服务

    • systemctl start|enable cockpit
  • 检查服务状态

    • systemctl status cockpit
      VirtualBoxVM_Dj0Ywb5QmM.png
  • 访问 Web 界面

    • https://127.0.0.1:9090
      VirtualBoxVM_30QJMtTHJY.png
      VirtualBoxVM_WAKF9NJP02.png

    这里用的是127.0.0.1的地址,如果你想要开放到其他地方,那你就需要先用ip addr,记下那个ipv4地址,并且通过防火墙开放9090端口,这之后同一局域网下的其他主机就能访问该界面了。

    1
    2
    3
    4
    5
    # Add the cockpit service to the firewall rules (this opens port 9090)
    firewall-cmd --add-service=cockpit --permanent

    # Reload the firewall to apply the changes
    firewall-cmd --reload

    firefox_7AJBMHshJX.png

    接下来就请你自己探索一下这个东西吧,虽然是一个非常好的东西,但是这不代表你可以忘记那些我们之前使用的命令。

后记

到这里,我们已经完成了RH124的所有内容,接下来我们将进入RH134课程。

Linux 访问文件系统

  • 文件系统是一种结构化的方式,用于存储所有文件和目录。

  • 要访问这些文件,我们需要使用导航工具。

  • 以下是用于访问 Linux 文件系统的基本工具或命令:

    • ls:列出目录内容

      • ls 命令用于显示指定目录中的文件和子目录。如果不指定目录,则显示当前目录的内容。
      • 基础用法示例
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        # 列出当前目录的内容
        ls

        # 列出/home目录的内容
        ls /home

        # 以长格式(long format)列出内容,显示权限、所有者、大小和修改日期等详细信息
        ls -l

        # 列出所有文件,包括隐藏文件(以.开头的文件)
        ls -a
    • cd:更改目录

      • cd (Change Directory) 命令用于从一个目录切换到另一个目录。
      • 基础用法示例
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        # 切换到 /var/log 目录
        cd /var/log

        # 切换到上一级目录
        cd ..

        # 快速返回当前用户的主目录
        cd ~
        # 或者直接使用 cd
        cd
    • pwd:显示当前工作目录

      • pwd (Print Working Directory) 命令用于显示您当前所在的完整目录路径。
      • 基础用法示例
        1
        2
        # 打印出当前工作目录的绝对路径
        pwd
    • df:报告文件系统磁盘空间使用情况

      • df (Disk Free) 命令用于显示文件系统的总空间、已用空间、可用空间和挂载点。
      • 基础用法示例
        1
        2
        3
        4
        5
        # 显示所有已挂载文件系统的空间使用情况
        df

        # 以人类可读的格式(例如 KB, MB, GB)显示,更易于阅读
        df -h
    • du:估算文件空间使用情况

      • du (Disk Usage) 命令用于估算文件和目录占用的磁盘空间大小。
      • 基础用法示例
        1
        2
        3
        4
        5
        6
        7
        8
        # 显示当前目录下每个子目录占用的空间
        du

        # 以人类可读的格式显示当前目录的总大小
        du -sh .

        # 以人类可读的格式显示/home目录下所有文件和目录的大小
        du -h /home
    • fdisk:操作磁盘分区表

      • fdisk 是一个强大的命令行工具,用于查看、创建和管理磁盘分区。此命令通常需要管理员权限。
      • 基础用法示例
        1
        2
        # 列出所有磁盘及其分区表(需要root或sudo权限)
        sudo fdisk -l
  • 绝对路径和相对路径

    • 在 Linux 中,路径是定位文件或目录的方式。
    • 绝对路径:路径总是从根目录 / 开始。它是一个完整的、明确的路径,无论您当前在哪个目录下,它都指向同一个位置。例如:/home/user/documents/file.txt
    • 相对路径:路径是相对于您当前的“工作目录”而言的。它不以 / 开头。例如,如果您在 /home/user 目录下,那么 documents/file.txt 就是一个相对路径。
  • 特殊目录符号

    • ~ (波浪号/Tilde):代表当前用户的主目录。例如,如果您的用户名是 alex,那么 ~ 就等同于 /home/alex
    • . (单个点):代表当前目录。
    • .. (两个点):代表上一级(父)目录。
0%