# 银河麒麟 + KVM + WebVirtCloud 虚拟机内存不足8G原因与解决方法

非常好的问题，这种情况在 **银河麒麟 + KVM + WebVirtCloud** 环境里非常常见。你配置虚拟机为 **4 核 8 GB 内存**，但虚拟机内系统只显示 **6.5 GB 左右**，可能由以下几种原因造成👇

---

## 🧩 一、宿主机层面：内存超分配或 NUMA 限制

### 🔹 1. 宿主机可用内存不足

如果宿主机剩余可分配内存小于 8 GB，`libvirt` 会自动削减虚拟机内存上限。

👉 检查宿主机实际内存：

```bash
free -m

```

若宿主机内存使用已接近上限（例如总 16 GB、已被多台 VM 占用），则虚拟机可能只分到部分物理内存。

---

### 🔹 2. NUMA 分区未正确分配

某些 CPU 平台或 BIOS 启用 NUMA（非统一内存访问），虚拟机若被绑定到单个 NUMA 节点，可能只能访问节点局部内存。

👉 检查宿主机 NUMA 拓扑：

```bash
numactl --hardware

```

👉 查看虚拟机 NUMA 绑定情况：

```bash
virsh dumpxml vmname | grep -A5 numa

```

若看到 `<numatune>` 或 `<vcpu placement='static'>` 一类的限制，可以删掉或修改为动态。

---

## 🧩 二、虚拟机配置层面（Libvirt/QEMU）

查看虚拟机定义文件：

```bash
virsh dumpxml vmname | grep -A5 memory

```

可能会看到：

```xml
<memory unit='KiB'>8388608</memory>
<currentMemory unit='KiB'>6815744</currentMemory>

```

💡 **关键区别：**

- `memory` 表示最大分配内存（8 GB）
- `currentMemory` 表示当前生效内存（6.5 GB）

🛠️ 解决方法：  
修改 XML 或使用命令同步：

```bash
virsh setmem vmname 8G --config
virsh setmaxmem vmname 8G --config

```

然后重启虚拟机：

```bash
virsh destroy vmname
virsh start vmname

```

---

## 🧩 三、模板或镜像层面

如果你使用的是 **WebVirtCloud 模板镜像（内置系统模板）**：

- 某些模板镜像里预设了 cloud-init 或 virt-sysprep 的限制，自动下调虚拟内存；
- 特别是从 qcow2 模板克隆出来时，`currentMemory` 通常被固定为镜像生成时的值。

👉 你可以用以下命令验证：

```bash
grep -A5 "<memory" /etc/libvirt/qemu/*.xml | grep -B1 currentMemory

```

如发现模板都只配置 `6815744 KiB`（≈ 6.5 GB），需要更新模板 XML。

---

## 🧩 四、虚拟机内部系统

确认不是系统层限制：

```bash
dmesg | grep -i memory

```

如果看到类似：

```
Memory limited to 6G due to ACPI or BIOS setting

```

说明虚拟 BIOS (OVMF/SeaBIOS) 或 grub 配置限制了内存。

检查：

```bash
cat /proc/cmdline

```

若存在 `mem=6G`，删除此参数并更新 grub：

```bash
vi /etc/default/grub
grub2-mkconfig -o /boot/grub2/grub.cfg

```

---

## ✅ 综合建议（推荐修复顺序）

1. **检查虚拟机 XML 配置：**
    
    ```bash
    virsh dumpxml vmname | grep -A5 memory
    
    ```
    
    若 `currentMemory` &lt; `memory` → 按上面方法调整。
2. **确认宿主机资源是否足够**（`free -m`）。
3. **重新启动虚拟机后再查看：**
    
    ```bash
    free -mh
    
    ```
4. 如果仍不对，可清理模板继承：
    
    ```bash
    virsh undefine vmname
    virsh define /path/to/vmname.xml
    
    ```

---

如果你愿意，我可以帮你写一个 **自动检测+修复虚拟机内存配置的小脚本**（一键同步 currentMemory 和 memory），以便后续新建虚拟机不再出现这种情况。是否帮你生成？

非常好，你提供的关键信息说明问题**不在宿主机资源或 libvirt 配置层面**。  
我们来逐步分析你的情况👇

---

## ✅ 一、已确认情况

<table id="bkmrk-%E9%A1%B9%E7%9B%AE-%E7%8A%B6%E6%80%81-%E5%AE%BF%E4%B8%BB%E6%9C%BA%E5%86%85%E5%AD%98-62-gib-%E5%8F%AF"><thead><tr><th>项目</th><th>状态</th></tr></thead><tbody><tr><td>宿主机内存</td><td>62 GiB 可用，非常充足</td></tr><tr><td>虚拟机定义</td><td>`<memory>` 与 `<currentMemory>` 都是 **8 GiB (8388608 KiB)**</td></tr><tr><td>CPU 配置</td><td>4 核</td></tr><tr><td>NUMA</td><td>没定义（正常）</td></tr><tr><td>实际虚拟机内内存</td><td>6.5 GiB 左右</td></tr></tbody></table>

👉 说明：  
宿主机和 libvirt XML 都是正确的，虚拟机内部显示 6.5 GiB，**极可能是虚拟机系统内部（guest OS）限制了内存识别**。

---

## 🧩 二、在虚拟机内部进一步检查

请进入虚拟机内部执行以下命令排查：

### 1️⃣ 检查内核参数是否限制内存

```bash
cat /proc/cmdline

```

如果输出中包含：

```
mem=6G

```

说明 grub 启动参数限制了内存识别。

🔧 解决：  
编辑 `/etc/default/grub`，去掉 `mem=` 参数，例如：

```bash
GRUB_CMDLINE_LINUX=""

```

然后更新 grub 配置并重启：

```bash
grub2-mkconfig -o /boot/grub2/grub.cfg
reboot

```

---

### 2️⃣ 检查系统是否识别全部内存

```bash
dmesg | grep -i memory

```

关注是否出现：

```
Memory limited to 6G due to ACPI or BIOS setting

```

或

```
usable memory = 6815744k

```

如果出现类似日志，说明虚拟 BIOS 报告的内存有限。

---

## 🧩 三、检查虚拟机 BIOS（QEMU 机器类型）

你虚拟机的定义中是：

```xml
<type arch='x86_64' machine='pc-q35-8.2'>hvm</type>

```

在某些银河麒麟 V11（基于 RHEL8 内核）环境中，  
Q35 机型 + 某些 BIOS 版本（SeaBIOS/OVMF）会导致内存映射 bug，  
导致 guest 系统只能识别 6.x GB。

🔧 **解决办法：改成传统 i440fx 机型。**

执行：

```bash
virsh edit rulr-1

```

找到：

```xml
<type arch='x86_64' machine='pc-q35-8.2'>hvm</type>

```

改为：

```xml
<type arch='x86_64' machine='pc-i440fx-8.2'>hvm</type>

```

保存退出，然后重启虚拟机：

```bash
virsh destroy rulr-1
virsh start rulr-1

```

之后进入系统再执行：

```bash
free -mh

```

通常就会显示 8 GiB 了。

---

## 🧩 四、确认虚拟机使用的是标准 BIOS 而非 OVMF（UEFI）

部分模板在 WebVirtCloud 中默认启用了 OVMF (UEFI) 固件，  
而部分旧内核（尤其是银河麒麟桌面内核）在 UEFI 模式下存在 ACPI table truncation bug。

👉 检查方式：

```bash
virsh dumpxml rulr-1 | grep loader

```

如果你看到：

```xml
<loader readonly='yes' type='pflash'>/usr/share/OVMF/OVMF_CODE.fd</loader>

```

说明使用的是 OVMF。

🔧 改为传统 BIOS 启动：  
在 XML 文件中删除 `<loader>` 和 `<nvram>` 段落，重启虚拟机。

---

## 🧩 五、建议最终检查项

如果以上修改后仍显示 6.x GB：

1. 尝试换一个 Linux 镜像（如 CentOS 8/Ubuntu 20.04）验证是否识别 8 GB；
2. 如果识别正常，说明是 **银河麒麟 guest 内核 bug**；
3. 可尝试升级内核或应用官方补丁（`yum update kernel`）。

---

## ✅ 总结

<table id="bkmrk-%E5%8F%AF%E8%83%BD%E5%8E%9F%E5%9B%A0-%E6%A3%80%E6%9F%A5%E9%A1%B9-%E4%BF%AE%E5%A4%8D%E5%BB%BA%E8%AE%AE-guest-"><thead><tr><th>可能原因</th><th>检查项</th><th>修复建议</th></tr></thead><tbody><tr><td>Guest grub 参数限制</td><td>`/proc/cmdline` 有 `mem=`</td><td>删除参数、重建 grub</td></tr><tr><td>BIOS 报告内存错误</td><td>`dmesg` 中有 ACPI 提示</td><td>改为 i440fx 机型</td></tr><tr><td>UEFI/OVMF 映射 bug</td><td>XML 中含 `<loader>`</td><td>删除 loader 段，改用传统 BIOS</td></tr><tr><td>银河麒麟内核 bug</td><td>特定版本</td><td>更新内核或换标准机型</td></tr></tbody></table>

---

非常好，这两段输出信息已经能说明问题所在。我们来仔细分析👇

---

## ✅ 一、关键日志分析

从你的 `dmesg` 输出中有两行非常重要：

```
[    0.013838] kexec_core: Reserving 256MB of low memory at 1776MB for crashkernel (System low RAM: 2047MB)
[    0.013839] Reserving 1024MB of memory at 9200MB for crashkernel (System RAM: 8191MB)

```

这表明：

- 系统识别到了 **8 GB 内存（8191MB）**；
- 但是因为启用了 **`crashkernel=1024M,high`**，有 1 GB 内存被保留；
- 再加上一些 BIOS/显存保留区，你最终看到的 “可用内存” 大约就是 6.5 GB 左右。

也就是说：

> **虚拟机的内存没问题，只是被 crashkernel（内核崩溃转储保留区）占用了。**

---

## 🧩 二、为什么会这样？

银河麒麟（Kylin V10/V11）默认启用了 **kdump 崩溃转储机制**，  
在 grub 启动参数中会自动加上：

```
crashkernel=1024M,high

```

这会强制预留 1 GB 的内存供 kdump 使用。

---

## 🛠 三、解决办法（释放这 1 GB 内存）

如果你只是实验或测试环境，不需要启用内核转储功能，可以直接关闭这一项。

### 1️⃣ 编辑 grub 配置

```bash
vi /etc/default/grub

```

找到这行：

```
GRUB_CMDLINE_LINUX="... crashkernel=1024M,high ..."

```

将 `crashkernel=1024M,high` 删除或注释掉：

```
GRUB_CMDLINE_LINUX="ro rhgb quiet audit=0"

```

保存退出。

---

### 2️⃣ 重新生成 grub 配置

如果是 BIOS 启动：

```bash
grub2-mkconfig -o /boot/grub2/grub.cfg

```

如果是 UEFI 启动：

```bash
grub2-mkconfig -o /boot/efi/EFI/kylin/grub.cfg

```

---

### 3️⃣ 重启系统

```bash
reboot

```

然后再次查看内存：

```bash
free -mh

```

应该能看到大约 **7.5 ~ 7.8 GiB** 的可用内存。

---

## ✅ 四、补充建议

- 如果你仍想保留 crashkernel，可以适当减小保留内存，例如：
    
    ```bash
    crashkernel=256M,high
    
    ```
    
    这样只占用 256 MB，不影响 kdump 功能。
- 若是批量模板虚拟机，可以在母盘模板中修改 `/etc/default/grub` 后重新制作镜像。

---

### 🔍 总结

<table id="bkmrk-%E9%97%AE%E9%A2%98%E6%A0%B9%E5%9B%A0-%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88-%E9%93%B6%E6%B2%B3%E9%BA%92%E9%BA%9F%E9%BB%98%E8%AE%A4%E5%90%AF%E7%94%A8-c"><thead><tr><th>问题根因</th><th>解决方案</th></tr></thead><tbody><tr><td>银河麒麟默认启用 crashkernel=1024M 保留区，导致内存少 1 GB+</td><td>删除或减小 crashkernel 参数后更新 grub 并重启</td></tr></tbody></table>

---

是否希望我帮你写一个脚本，一键自动检测并修复（删除 crashkernel、重建 grub、提示是否重启）？