君衍
- 一、本篇缘由
- 二、问题研究
- 1、dmidecode
- 2、dmesg | grep -i memory
- 三、kdump
- 四、解决方案
- 1、卸载kdump-tools
- 2、清理依赖包
- 3、修改配置文件
- 4、重新生成配置文件
- 5、重启服务器
- 6、再次查看
一、本篇缘由
本篇由于最近买了云服务器,之前基本在本地使用VMware进行虚拟化来部署一些靶场,现在研究安全产品进行测试,所以准备部署在云服务器。之后一直没看内存,直到安装一些服务之后,看到内存之后1771MB。
所以即使厂家拿1G当1000MB,那也不应该只有1771MB,2G的内存,拿二进制算也是2048MB,一点误差能理解,但是这差的有点多。
这里记录下自己的解决方式以及内存不足量的原因。经过自己研究以及查阅资料,原因是kdump
导致的。
可以看到上图使用free命令查看内存大小会发现比2G小很多。
二、问题研究
1、dmidecode
dmidecode
是一个Linux/Unix系统上的命令行工具,用于获取关于计算机硬件相关信息的详细报告。它通过读取系统中的 DMI(Desktop Management Interface
,桌面管理接口)信息,可以提供关于硬件组件(如处理器、内存、主板、BIOS等)的详细信息。
使用 dmidecode
命令可以获取的信息包括:
- 系统的硬件组件类型和详细规格
- 处理器的型号、速度、核心数等信息
- 内存模块的容量、类型、速度等信息
- 主板的制造商、型号、版本号等信息
- BIOS 的制造商、版本号、发布日期等信息
- 系统中各硬件设备的序列号和其他标识信息
这里使用dmidecode命令查看底层硬件信息:
root@hcss-ecs-3adb:~# dmidecode
# dmidecode 3.3
Getting SMBIOS data from sysfs.
SMBIOS 2.8 present.
9 structures occupying 491 bytes.
Table at 0x000F6860.
# 这部分提供了虚拟机的 BIOS 信息,包括厂商、版本号、发布日期
Handle 0x0000, DMI type 0, 24 bytes
BIOS Information
Vendor: SeaBIOS
Version: rel-1.10.2-0-g5f4c7b1-20230409_040737-szxrtosci10000
Release Date: 04/01/2014
Address: 0xE8000
Runtime Size: 96 kB
ROM Size: 64 kB
Characteristics:
BIOS characteristics not supported
Targeted content distribution is supported
BIOS Revision: 0.0
# 这部分包含了系统的一般信息,如制造商、产品名称、版本号、序列号、UUID
Handle 0x0100, DMI type 1, 27 bytes
System Information
Manufacturer: OpenStack Foundation
Product Name: OpenStack Nova
Version: 13.2.1-20240426143905_3138e2a
Serial Number: d92cff69-5f58-4ef8-bd0a-5b3718bc3ba8
UUID: d92cff69-5f58-4ef8-bd0a-5b3718bc3ba8
Wake-up Type: Power Switch
SKU Number: Not Specified
Family: Virtual Machine
# 这部分描述了系统机箱(虚拟机的情况下一般是模拟的),包括类型、版本号和资产标签
Handle 0x0300, DMI type 3, 22 bytes
Chassis Information
Manufacturer: Not Specified
Type: Other
Lock: Not Present
Version: pc-i440fx-2.8
Serial Number: Not Specified
Asset Tag: HUAWEICLOUD
Boot-up State: Safe
Power Supply State: Safe
Thermal State: Safe
Security Status: Unknown
OEM Information: 0x00000000
Height: Unspecified
Number Of Power Cords: Unspecified
Contained Elements: 0
SKU Number: Not Specified
# 这部分提供了处理器的信息,包括制造商、型号、速度、核心数
Handle 0x0400, DMI type 4, 42 bytes
Processor Information
Socket Designation: CPU 0
Type: Central Processor
Family: Other
Manufacturer: QEMU
ID: 57 06 05 00 FF FB 8B 0F
Version: pc-i440fx-2.8
Voltage: Unknown
External Clock: Unknown
Max Speed: 2000 MHz
Current Speed: 2000 MHz
Status: Populated, Enabled
Upgrade: Other
L1 Cache Handle: Not Provided
L2 Cache Handle: Not Provided
L3 Cache Handle: Not Provided
Serial Number: Not Specified
Asset Tag: Not Specified
Part Number: Not Specified
Core Count: 1
Core Enabled: 1
Thread Count: 2
Characteristics: None
# 描述了物理内存数组的信息,包括其位置和最大容量
Handle 0x1000, DMI type 16, 23 bytes
Physical Memory Array
Location: Other
Use: System Memory
Error Correction Type: Multi-bit ECC
Maximum Capacity: 2 GB
Error Information Handle: Not Provided
Number Of Devices: 1
# 这部分提供了内存设备的详细信息,如大小、类型、制造商
Handle 0x1100, DMI type 17, 40 bytes
Memory Device
Array Handle: 0x1000
Error Information Handle: Not Provided
Total Width: Unknown
Data Width: Unknown
Size: 2 GB
Form Factor: DIMM
Set: None
Locator: DIMM 0
Bank Locator: Not Specified
Type: RAM
Type Detail: Other
Speed: Unknown
Manufacturer: QEMU
Serial Number: Not Specified
Asset Tag: Not Specified
Part Number: Not Specified
Rank: Unknown
Configured Memory Speed: Unknown
Minimum Voltage: Unknown
Maximum Voltage: Unknown
Configured Voltage: Unknown
# 描述了内存数组映射地址的信息
Handle 0x1300, DMI type 19, 31 bytes
Memory Array Mapped Address
Starting Address: 0x00000000000
Ending Address: 0x0007FFFFFFF
Range Size: 2 GB
Physical Array Handle: 0x1000
Partition Width: 1
# 提供了系统引导信息,显示系统引导状态正常,未检测到错误
Handle 0x2000, DMI type 32, 11 bytes
System Boot Information
Status: No errors detected
Handle 0x7F00, DMI type 127, 4 bytes
End Of Table
以上可以看到没有问题,提供的是2G的内存,但是,这部分内存不包括OS内核基本数据结构消耗以及内核预留内存。
所以这里没什么问题,下面我们查看内核的预留内存。
2、dmesg | grep -i memory
dmesg | grep -i memory
是一个在Linux系统中用来查找与内存相关的信息的命令。具体地说,它会从系统日志 (dmesg
输出) 中筛选出包含 “memory
” 关键词的行,并将它们显示在终端上。
这个命令可以用来快速检查系统引导时内核启动阶段所记录的内存相关信息,例如内存检测、内存模块的初始化状态、内存大小的报告等。
这里可以看到为为 crashkernel
预留了 192M 的内存,接着我们可以通过查阅官方文档:
(这里虽然我使用Ubuntu,但是红帽都是Linux,还是可以参考下的)
为
kdump
的内存保留在系统引导过程中发生。内存大小是在系统的 Grand Unified Bootloader (GRUB)配置中设定的。内存大小取决于配置文件中指定的crashkernel=
选项的值以及系统物理内存的大小。
您可以使用多种方式定义crashkernel=
选项。您可以指定crashkernel=
值或配置auto
选项。crashkernel=auto
参数根据系统中的物理内存总量自动保留内存。配置后,内核将自动为捕获内核保留适当数量的所需内存。这有助于防止内存不足(OOM)错误。
所以可以确定,华为云提供的镜像,默认开启了kdump
服务。当 Linux
内核出现了故障时 kdump
会协助产生一个 dump
文件,记录下此时的内存运行参数等信息,便于用户后续对内核问题的定位分析。可以看到crashkernel
预留的内存就是因为这个原因。
这里简单说下,之后我们对kdump服务进行详细了解。kdump服务对于低配的VPS,就变成了鸡肋,这种低配服务器1G,2G面前,本身内存不够,所以没有必要启用kdump,开启的话可能也会导致内存不足之后服务崩溃等等奇奇怪怪的问题。
三、kdump
红帽对于kdump的讲解:官方文档
kdump
是一个提供崩溃转储机制,并生成一个转储文件的服务,称为崩溃转储或 vmcore
文件。vmcore
文件包含系统内存的内容,有助于分析和故障排除。kdump
使用 kexec
系统调用引导到第二个内核,这是一个不需要重启的 捕获内核,然后捕获崩溃内核内存的内容,并将其保存到一个文件中。第二个内核位于系统内存的保留部分。
当系统出现故障时,内核崩溃转储是唯一可用的信息。因此,在关键任务环境中操作
kdump
非常重要。红帽建议在常规内核更新周期中定期更新和测试kexec-tools
。这在安装新内核功能时尤为重要。
其实kdump是一个系统崩溃时收集信息的工具,所以对于一般研究练习,没有必要开启。
四、解决方案
两种方式,一种关闭kdump服务,第二种直接卸载,我使用第二种方式,直接将其卸载,避免再出问题。
需要注意都需要root权限
1、卸载kdump-tools
apt purge kdump-tools
2、清理依赖包
apt autoremove
3、修改配置文件
vim /etc/default/grub
将其中的crashkernel=xxx
字段全部删除:
GRUB_DEFAULT=0
GRUB_TIMEOUT_STYLE=menu
GRUB_TIMEOUT=10
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT=""
GRUB_CMDLINE_LINUX="net.ifnames=0 consoleblank=600 console=tty0 console=ttyS0,115200n8 noibrs crashkernel=0M"
这里将默认直接删完,同时其实也可以将下面的启动参数也删了,也可以直接设置0M。
这里稍加解读下,以上是GRUB的配置项,用于设置 Linux 系统的启动选项。
- GRUB_DEFAULT=0:
- 指定默认启动的操作系统条目的索引。这里设置为 0 表示默认启动第一个条目(通常是第一个内核)。
- GRUB_TIMEOUT_STYLE=menu:
- 设置 GRUB 的超时样式为菜单模式,即在启动时如果超时时间到了,会显示一个启动菜单供用户选择。
- GRUB_TIMEOUT=10:
- 设置 GRUB 的超时时间为 10 秒。如果用户没有选择操作系统,系统将会在超过这个时间后启动默认的操作系统。
- GRUB_DISTRIBUTOR=
lsb_release -i -s 2> /dev/null || echo Debian
:- 指定 GRUB 菜单中的发行版信息。这里使用
lsb_release
命令来获取发行版信息,如果获取失败(通过重定向错误输出到/dev/null
),则默认显示为 “Debian”。
- 指定 GRUB 菜单中的发行版信息。这里使用
- GRUB_CMDLINE_LINUX_DEFAULT=“”:
- 设置 Linux 内核的默认启动参数。这里是空字符串,表示没有额外的默认参数。
- GRUB_CMDLINE_LINUX=“net.ifnames=0 consoleblank=600 console=tty0 console=ttyS0,115200n8 noibrs crashkernel=0M”:
- 设置 Linux 内核的启动参数。
- net.ifnames=0: 禁用预测可预见的接口命名,使用传统的网络接口命名方式。
- consoleblank=600: 设置控制台空闲超时时间为 600 秒,如果超过这个时间没有键盘输入,控制台屏幕会自动关闭。
- console=tty0: 设置第一个虚拟控制台为标准输入输出设备。
- console=ttyS0,115200n8: 将串行端口
ttyS0
配置为控制台,波特率为 115200,数据位为 8 位,无校验位。 - noibrs: 禁用 Indirect Branch Restricted Speculation (IBRS),这是一种 CPU 漏洞 (Spectre Variant 2) 的缓解措施。
- crashkernel=0M: 禁用内核崩溃转储区域,指定为 0M 表示不分配内存用于崩溃转储。
- 设置 Linux 内核的启动参数。
这里需要注意,两个都需要更改:
4、重新生成配置文件
update-grub2
5、重启服务器
reboot
这里一定需要注意重新启动。
6、再次查看
free -m
dmesg | grep -i memory
可以看到这里可用内存已经从1771变为了1963,同时预留内存可以看到已经没有了,(比之前多了192M)。
希望可以帮助到各位。