分类 kvm虚拟机 下的文章

出现 (initramfs) 提示符,说明内核已经成功加载并启动,但无法找到或挂载根文件系统(Root File System)。这通常是因为虚拟磁盘的设备名称发生改变(例如原先是 sda,现在在 KVM 中变成了 vda),或者引导参数中的 UUID 与实际不符。可以通过以下步骤在当前界面排查并定位问题:1.1. 检查内核是否识别到虚拟磁盘:查看块设备。在 (initramfs) 提示符下输入以下命令,查看系统当前挂载了哪些磁盘:Plaintextcat /proc/partitions
验证成功: 终端会列出设备列表,检查里面是否有 vda、sda 及其对应的主分区(如 vda1、sda1)。2.2. 获取正确的分区及文件系统信息:检查分区 UUID。输入以下命令查看磁盘的详细格式和 UUID:Plaintextblkid
验证成功: 能够看到类似于 /dev/vda1: UUID="..." BLOCK_SIZE="..." TYPE="ext4" 的输出信息。

既然 blkid 已经能够识别到 vda 及其分区,说明内核和驱动已经正常工作。之所以卡在 (initramfs) 界面,通常是因为系统找不到对应的根分区 UUID,或者文件系统由于异常关机导致损坏需要修复。1.1. 退出 initramfs 查看真实报错:获取崩溃日志。在 (initramfs) 提示符下输入:Plaintextexit
验证成功: 屏幕会向上滚动并打印出导致系统无法正常挂载根目录的具体错误日志(例如提示某个 UUID 不存在、超时或文件系统损坏)。2.2. 执行文件系统检查与修复:修复文件系统。如果刚才的报错提示文件系统损坏或未正常卸载,请对你的根分区(假设 blkid 显示根分区为 /dev/vda1,请按实际情况调整)执行强制修复:Plaintextfsck -y /dev/vda1
验证成功: fsck 运行结束并提示文件系统已清理修复(Clean / blocks fixed)。

将r730上的kvm虚拟机迁移到r710服务器上避坑:

一号坑:

Machine Type(机器类型)不兼容:
原系统的机器类型可能是特定定制的(例如 pc-i440fx-rhel7.x.x)。Ubuntu 24.04 的 QEMU 无法识别这种类型。

修改方法: 找到 标签下的 ,将其修改为 Ubuntu 支持的通用类型,例如默认的 pc 或者较新的 q35。我的改为了:pc-i440fx-2.12

降低 CPU 模型以适配老旧的 R710
R710 的 CPU 架构较老(Westmere 架构),需要将 CPU 模型改为兼容模式(如 Westmere 或 Penryn),删掉那些新 CPU 特性要求:

XML

<model fallback='allow'>Westmere</model>

二号坑

Emulator(模拟器)路径变更:
不同系统的 QEMU 执行文件路径可能不同(例如某些系统是 /usr/libexec/qemu-kvm)。

修改方法: 确保 标签的值为 Ubuntu 的正确路径,通常是 /usr/bin/qemu-system-x86_64。
修正虚拟磁盘路径
找到 这一段,将 修正为你当前在 Ubuntu 上存放该 .qcow2 文件的真实绝对路径(例如你之前提到的 /home/qianlong/kvm/vdisks/kali2026.1kvm8901.qcow2):

XML

<disk type='file' device='disk'>
  <driver name='qemu' type='qcow2'/>
  <source file='/home/qianlong/kvm/vdisks/kali2026.1kvm8901.qcow2'/>
  <target dev='vda' bus='virtio'/>
  <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
</disk>

三号坑

Ubuntu 特有的 AppArmor 安全策略
这是迁移到 Ubuntu 时最容易踩坑的地方。Ubuntu 默认使用 AppArmor 保护系统。如果你的虚拟机磁盘镜像(如 .qcow2)放在了非默认路径(默认是 /var/lib/libvirt/images/,如果你挂载到了自定义的数据盘如 /data/vms/),AppArmor 会直接拦截 QEMU 的读取请求,日志里会显示 Permission denied。

排查方式: 运行 dmesg | grep -i apparmor | grep DENIED,看看是否有针对你虚拟机镜像路径的拦截记录。

解决方式: 你需要修改 AppArmor 的 libvirt 配置,将你的自定义目录加入白名单。编辑 /etc/apparmor.d/local/usr.lib.libvirt.virt-aa-helper,添加你的镜像路径(例如加上一行 /data/vms/** rwk,),然后重启 AppArmor 服务。
sudo systemctl reload apparmor

四号坑

镜像文件权限与属主
在 Ubuntu 24.04 上,QEMU 进程通常以 libvirt-qemu 用户(属于 kvm 用户组)运行。
迁移过来的镜像文件可能还保留着 root 或原系统特定用户的权限,导致 QEMU 无法读取。

解决方式: 手动将镜像文件的属主改过来:
保留在家目录,修改目录穿透权限
如果你必须把镜像放在这个位置(例如这块硬盘空间很大),你需要逐级赋予外来用户“进入”目录的权限(即执行权限 x),并修改镜像文件的属主。

逐级开放目录的进入权限(o+x):
注意,这会让系统上其他用户也能通过已知路径访问你的家目录文件,请确保安全。

Bash
chmod o+x /home/qianlong
chmod o+x /home/qianlong/kvm
chmod o+x /home/qianlong/kvm/vdisks
将镜像文件的属主改为 QEMU 进程账户:

Bash
sudo chown libvirt-qemu:kvm /home/qianlong/kvm/vdisks/kali2026.1kvm8901.qcow2

五号坑

网络接口 (Bridge/NAT) 缺失
检查 XML 中的 部分。
如果你的虚拟机原来使用的是桥接网络(如 并指定了 br0),那么在新的 Ubuntu 24.04 宿主机上,必须提前配置好同名的网桥。如果宿主机的网桥不存在,虚拟机在初始化网卡设备时就会直接报错退出。

六号坑

在 KVM 虚拟化中,经常会使用模板克隆来节省空间。你的 kali2026.1kvm8901.qcow2 并不是一个包含完整系统数据的独立镜像,而是一个增量镜像(Differential Image)。

它在底层强烈依赖于一个基础模板文件:/home/disk/nvme1/kvm/vdisks/kali2026.1_template.raw。
在迁移到这台新的宿主机时,底层的 QEMU 进程按照这个写死的旧路径去寻找基础模板,但没有找到。这通常是因为该文件没有被拷贝过来,或者新服务器的目录结构不同(例如缺少 nvme1 这个挂载点)。

解决方法
你需要找到那个基础模板文件,并修正 .qcow2 文件中的路径指向。

步骤 1:定位基础模板文件
请先在当前的 Ubuntu 系统中找到 kali2026.1_template.raw 文件。假设你已经将它和现在的 .qcow2 文件放在了同一个目录下,即 /home/qianlong/kvm/vdisks/。

步骤 2:重置基础镜像路径(Rebase)
使用 qemu-img rebase 命令来修改 .qcow2 内部记录的基础镜像路径:

Bash

请将 -b 后面的路径替换为模板文件在你当前系统上的真实绝对路径

qemu-img rebase -u -b /home/qianlong/kvm/vdisks/kali2026.1_template.raw -F raw /home/qianlong/kvm/vdisks/kali2026.1kvm8901.qcow2
提示:-u 参数表示不安全模式(Unsafe mode),它的作用是强行改写路径指针而不去校验旧路径的数据,由于你的旧路径已经不存在了,必须加上这个参数。

步骤 3:验证路径修改
运行以下命令检查镜像信息:

Bash
qemu-img info /home/qianlong/kvm/vdisks/kali2026.1kvm8901.qcow2
在输出的内容中,确认 backing file 这一项已经成功变更为你刚刚设置的新路径。

步骤 4:赋予基础镜像权限
因为虚拟机启动时不仅需要读取 .qcow2,还需要读取底层的 .raw 模板。请确保 libvirt-qemu 账户对基础模板文件同样具有权限:

Bash
sudo chown libvirt-qemu:kvm /home/qianlong/kvm/vdisks/kali2026.1_template.raw
sudo chown libvirt-qemu:kvm /home/qianlong/kvm/vdisks/kali2026.1kvm8901.qcow2

七号坑:既然修改完配置后,虚拟机依然提示 No bootable device(找不到引导设备)

既然修改完配置后,虚拟机依然提示 No bootable device(找不到引导设备),说明虚拟机的虚拟硬盘(即那条增量链)虽然能被 QEMU 打开,但系统在里面依然找不到有效的引导扇区(MBR/GPT)或内核。

1、可以通过以下步骤排查磁盘镜像的实际状态:1.1. 查看 qcow2 镜像状态:检查镜像基本信息。在宿主机终端运行以下命令,检查该虚拟磁盘的大小和格式:Bashqemu-img info /home/qianlong/kvm/vdisks/kali2026.1kvm8901.qcow2
验证成功: 终端正常输出镜像的虚拟大小、实际占用空间及文件格式。

2.检查底层模板文件自分区表:验证 raw 模板完整性。运行以下命令直接检查 .raw 模板的分区结构,看看它在 R710 上是否能被正常读取:Bashsudo fdisk -l /home/qianlong/kvm/vdisks/kali2026.1_template.raw
验证成功: 终端能够正常打印出类似 Linux 分区(如 /dev/loopXp1 或分区表详情)即说明模板完好;若报错则说明该文件在跨服务器拷贝时损坏或不完整。

3.检查模板镜像元数据:核对虚拟大小。运行以下命令查看 .raw 文件的基本属性:Bashqemu-img info /home/qianlong/kvm/vdisks/kali2026.1_template.raw

问题的原因已经找到了:从 qemu-img info 的输出可以看出,这个文件的后缀虽然叫 .raw,但它实际的文件格式是 qcow2。

因为 fdisk 只能直接读取纯 Raw 格式的绝对物理偏移,无法解析 qcow2 内部的封装结构,所以刚才直接用 fdisk 无法正确读取分区。

4、 修正文件后缀名避免误导:规范化命名(可选)。为了避免以后混淆,建议将模板文件的后缀名从 .raw 改为 .qcow2:Bashmv /home/qianlong/kvm/vdisks/kali2026.1_template.raw /home/qianlong/kvm/vdisks/kali2026.1_template.qcow2
(注意:改名后,需要同步修改子镜像 kali2026.1kvm8901.qcow2 内部的 backing file 指向路径,或者重新指定底层模板)。验证成功: 再次运行 qemu-img info 确认基础链条指向正常。

5、重新更新重置基础镜像路径(Rebase)
qemu-img rebase -u -b /home/qianlong/kvm/vdisks/kali2026.1_template.qcow2 -F qcow2 /home/qianlong/kvm/vdisks/kali2026.1kvm8901.qcow2

6、赋予基础镜像权限
因为虚拟机启动时不仅需要读取 .qcow2,还需要读取底层的 .raw 模板。请确保 libvirt-qemu 账户对基础模板文件同样具有权限:

Bash
sudo chown libvirt-qemu:kvm /home/qianlong/kvm/vdisks/kali2026.1_template.qcow2
sudo chown libvirt-qemu:kvm /home/qianlong/kvm/vdisks/kali2026.1kvm8901.qcow2
重新启动虚拟机,可以启动了

具体我的操作修改项如下:

1、virsh edit kali2026.1kvm8902
修改内容如下:

<domain type='kvm'>
  <name>kali2026.1kvm8901</name>
  <uuid>921fd605-7601-4052-87bd-7ada46849e74</uuid>
  <memory unit='KiB'>4194304</memory>
  <currentMemory unit='KiB'>4194304</currentMemory>
  <vcpu placement='static'>4</vcpu>
  <os>
    **<type arch='x86_64' machine='pc-i440fx-2.12'>hvm</type>**
    <boot dev='hd'/>
    <boot dev='cdrom'/>
  </os>
  <features>
    <acpi/>
    <apic/>
  </features>
  <cpu mode='custom' match='exact' check='partial'>
    **<model fallback='allow'>Westmere</model>**
  </cpu>
  <clock offset='utc'>
    <timer name='rtc' tickpolicy='catchup'/>
    <timer name='pit' tickpolicy='delay'/>
    <timer name='hpet' present='no'/>
  </clock>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>destroy</on_crash>
  <pm>
    <suspend-to-mem enabled='no'/>
    <suspend-to-disk enabled='no'/>
  </pm>
  <devices>
    **<emulator>/usr/bin/qemu-system-x86_64</emulator>**
    <disk type='file' device='disk'>
      <driver name='qemu' type='qcow2'/>
      **<source file='/home/qianlong/kvm/vdisks/kali2026.1kvm8901.qcow2'/>**
      <target dev='vda' bus='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
    </disk>
    <disk type='file' device='cdrom'>
      <driver name='qemu' type='raw'/>
      <target dev='hda' bus='ide'/>
      <readonly/>
      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
    </disk>
     <controller type='usb' index='0' model='ich9-ehci1'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x7'/>
    </controller>
    <controller type='usb' index='0' model='ich9-uhci1'>
      <master startport='0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0' >
    </controller>
    <controller type='usb' index='0' model='ich9-uhci2'>
      <master startport='2'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x1'/>
    </controller>
    <controller type='usb' index='0' model='ich9-uhci3'>
      <master startport='4'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x2'/>
    </controller>
    <controller type='pci' index='0' model='pci-root'/>
    <controller type='ide' index='0'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
    </controller>
    <interface type='bridge'>
      <mac address='52:54:00:28:45:98'/>
      **<source bridge='br0'/>**
      <model type='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>
    <serial type='pty'>
      <target type='isa-serial' port='0'>
        <model name='isa-serial'/>
      </target>
    </serial>
    <console type='pty'>
      <target type='serial' port='0'/>
    </console>
    <input type='mouse' bus='ps2'/>
    <input type='keyboard' bus='ps2'/>
    <graphics type='vnc' port='8901' autoport='no' listen='0.0.0.0'>
      <listen type='address' address='0.0.0.0'/>
    </graphics>
    <audio id='1' type='none'/>
    <video>
      <model type='qxl' ram='65536' vram='65536' vgamem='16384' heads='1' primar>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
    </video>
    <memballoon model='virtio'>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
    </memballoon>
  </devices>
</domain>

2、使kvm可以访问/home目录
编辑 /etc/apparmor.d/local/usr.lib.libvirt.virt-aa-helper,添加你的镜像路径
加上一行
/home/qianlong/kvm/vdisks/** rwk,
然后重启 AppArmor 服务。
sudo systemctl reload apparmor

3、修改镜像文件权限与属主
chmod o+x /home/qianlong
chmod o+x /home/qianlong/kvm
chmod o+x /home/qianlong/kvm/vdisks
将镜像文件的属主改为 QEMU 进程账户:

Bash
sudo chown libvirt-qemu:kvm /home/qianlong/kvm/vdisks/kali2026.1kvm8902.qcow2

4、重置基础镜像路径(Rebase)
使用 qemu-img rebase 命令来修改 .qcow2 内部记录的基础镜像路径
qemu-img rebase -u -b /home/qianlong/kvm/vdisks/kali2026.1_template.qcow2 -F qcow2 /home/qianlong/kvm/vdisks/kali2026.1kvm8902.qcow2

5、赋予基础镜像权限
因为虚拟机启动时不仅需要读取 .qcow2,还需要读取底层的 .raw 模板。请确保 libvirt-qemu 账户对基础模板文件同样具有权限:

Bash
sudo chown libvirt-qemu:kvm /home/qianlong/kvm/vdisks/kali2026.1_template.qcow2
sudo chown libvirt-qemu:kvm /home/qianlong/kvm/vdisks/kali2026.1kvm8902.qcow2

6、重启kvm虚拟机
virsh start kali2026.1kvm8902

给 KVM 虚拟机(KVM Virtual Machine)扩容,通常需要分两步走:在宿主机上扩大虚拟磁盘文件,以及在虚拟机内部扩展文件系统。根据你的磁盘管理方式(QCOW2 镜像文件或 LVM 逻辑卷),操作步骤略有不同。以下是主流的 QCOW2 镜像文件 + 虚拟机内 Linux(LVM/标准分区) 的扩容流程。第一步:在宿主机上扩容虚拟磁盘在进行任何磁盘操作前,强烈建议先关闭虚拟机并备份当前的 .qcow2 文件,以防数据丢失。1.关闭虚拟机:宿主机执行。确保虚拟机处于关闭状态:Bashvirsh shutdown <虚拟机名称>
2.查看当前磁盘信息:宿主机执行。找到虚拟机的磁盘文件路径(可以通过 virsh domblklist <虚拟机名称> 查看),然后检查其大小:Bashqemu-img info /path/to/your/vm-disk.qcow2
3.增加磁盘容量:宿主机执行。使用 qemu-img resize 命令增加空间。例如,给镜像增加 50G(也可以直接写目标总大小如 100G):Bash# 增加 50G
qemu-img resize /path/to/your/vm-disk.qcow2 +50G
第二步:在虚拟机内扩展文件系统将虚拟机开机 (virsh start <虚拟机名称>) 并通过 SSH 或控制台登录。此时虚拟机已经识别到了更大的硬盘,但分区和文件系统还没有利用这些新空间。根据虚拟机内部的磁盘布局,选择以下方案 A 或方案 B:方案 A:虚拟机内是标准常规分区(如 /dev/sda1, /dev/sda2)如果你的文件系统直接建在普通分区上,可以使用 growpart 和对应文件系统的扩容工具。安装扩容工具(以 Ubuntu/Debian 为例):Bashsudo apt-get install cloud-guest-utils
扩展分区表:假设你要扩容 /dev/sda 的第 2 个分区:Bashsudo growpart /dev/sda 2
扩展文件系统:如果是 EXT4 文件系统:Bashsudo resize2fs /dev/sda2
如果是 XFS 文件系统:Bashsudo xfs_growfs /
方案 B:虚拟机内使用了 LVM(逻辑卷管理,通常为 Linux 默认)如果你的虚拟机使用的是 LVM,扩容会更灵活,可以把新空间作为一个新分区加进卷组。用 fdisk 创建新分区:Bashsudo fdisk /dev/sda
输入 n 创建新分区(一路回车使用默认的起始和结束扇区)。输入 t 修改分区类型,选择刚才创建的分区号,类型输入 8e(Linux LVM)。输入 w 保存并退出。运行 sudo partprobe 刷新分区表(如果提示忙,可能需要重启虚拟机)。将新分区扩展到 LVM 中(假设新分区为 /dev/sda3):Bash# 1. 创建物理卷
sudo pvcreate /dev/sda3

2. 查看卷组名称(假设叫 ubuntu-vg)

sudo vgdisplay

3. 扩展卷组

sudo vgextend ubuntu-vg /dev/sda3

4. 扩展逻辑卷(将所有剩余空间都给根目录逻辑卷)

sudo lvextend -l +100%FREE /dev/ubuntu-vg/ubuntu-lv
最后,刷新文件系统:EXT4: sudo resize2fs /dev/ubuntu-vg/ubuntu-lvXFS: sudo xfs_growfs /💡 检查结果完成后,在虚拟机内部运行 df -h,你应该就能看到根目录或者目标挂载点的容量已经成功变大了。

  1. 版本选择建议
    推荐使用 Windows 10 企业版 LTSC (Long-Term Servicing Channel)。

理由: LTSC 版本极度精简,没有应用商店、Edge 浏览器、Cortana 以及频繁的功能更新。它占用资源极少,非常适合作为虚拟机运行。

硬件要求: 建议至少分配 2 核 CPU 和 4GB 内存(如果资源紧张,2GB 也能跑,但会比较吃力)。

  1. 准备工作
    在开始之前,除了 Windows 镜像,你必须下载 VirtIO 驱动。Windows 默认不识别 KVM 的半虚拟化磁盘和网卡,不加载驱动会搜不到硬盘。

Windows 10 ISO: 你的系统镜像。下载地址:https://msdn.itellyou.cn/上去找简体中文版:ed2k://|file|cn_windows_10_enterprise_ltsc_2019_x64_dvd_9c09ff24.iso|4478906368|E7C526499308841A4A6D116C857DB669|/

VirtIO Win ISO: 从 Fedora 官方存储库 下载最新的稳定版(virtio-win.iso)。https://github.com/virtio-win/virtio-win-pkg-scripts/blob/master/README.md

  1. 安装步骤
    第一步:检查并开启 KVM 模块
    确保你的 CPU 支持虚拟化并已在 BIOS 中开启:

Bash

lsmod | grep kvm

如果没有输出,尝试加载:modprobe kvm_intel (或 kvm_amd)

第二步:安装必要软件包
Bash

yum install -y qemu-kvm libvirt virt-install virt-manager
systemctl start libvirtd
systemctl enable libvirtd
第三步:创建虚拟机
你可以使用 virt-manager 图形界面(如果你有 X11 转发),或者直接使用命令行。以下是推荐的命令行创建方式:

Bash

virt-install \
--name=win10_vm \
--ram=4096 \
--vcpus=2 \
--os-type=windows \
--os-variant=win10 \
--disk path=/var/lib/libvirt/images/win10.qcow2,size=50,bus=virtio \
--network bridge=virbr0,model=virtio \
--cdrom=/path/to/windows_10_ltsc.iso \
--disk /path/to/virtio-win.iso,device=cdrom \
--graphics vnc,listen=0.0.0.0 \
--boot cdrom,hd

我的命令如下:

virt-install \
--name=win10_vm \
--ram=4096 \
--vcpus=4 \
--os-type=windows \
--os-variant=win10 \
--disk path=/home/kvm/vdisks/win10_template.qcow2,size=50,bus=virtio \
--network bridge=br1,model=virtio \
--cdrom=/home/kvm/isos/win10_ltsc.iso \
--disk /home/kvm/isos/virtio-win-0.1.285.iso,device=cdrom \
--graphics vnc,listen=0.0.0.0,port=7900 \
--boot cdrom,hd,menu=on \
--noautoconsole --autostart
关键点解释:

bus=virtio: 磁盘使用 VirtIO 模式,速度最快。

model=virtio: 网卡使用 VirtIO 模式。

这里挂载了两个光驱:一个是 Windows 安装盘,一个是驱动盘。
注意这里,如果没有找到引导光驱可以使用virsh reset win10_vm重启虚拟机,然后按esc选择引导设备。
第四步:Windows 安装过程中的驱动加载
启动虚拟机后,通过 VNC 连接。

在选择安装磁盘的界面,你会发现找不到硬盘。别担心,点击 “加载驱动程序” (Load Driver)。

浏览到 VirtIO 驱动光盘:

磁盘驱动:选择 viostor\w10\amd64。

网络驱动(可选,安装完再装也行):选择 NetKVM\w10\amd64。

加载后,硬盘就会显示出来,正常分区安装即可。

第五步:完善驱动
进入 Windows 系统后,打开“设备管理器”,你会发现还有一些带黄色感叹号的设备(如 PCI 设备、内存气球驱动)。

右键点击它们 -> 更新驱动程序 -> 指向 VirtIO 驱动光盘根目录,让它自动搜索安装即可。

  1. 性能优化小贴士
    磁盘格式:务必使用 qcow2,支持快照且节省空间。

写缓存:在 XML 配置中将 disk cache 设置为 none 或 writeback 可以显著提升磁盘 IO。

远程桌面:安装完成后,建议开启 Windows 自带的 RDP (远程桌面)。RDP 的操作体验比 VNC 流畅得多。

原因是:Docker 不吃你在 Xubuntu 里设置的终端代理环境变量。

下面我把原因 → 正确解决方案 → 最稳的国内方案一次性讲清楚。

一、为什么你设置了代理,docker pull mongo 还是失败?
关键点(一定要记住):
docker pull 走的是 Docker daemon(dockerd),不是你的 shell

也就是说:

你在终端里:

bash
复制代码
export http_proxy=...
只对 curl / apt / wget 生效

对 docker pull 完全无效

因为:

docker pull → 请求是 dockerd 进程发出的

dockerd 不继承你的终端环境变量

所以在国内就会出现:

curl 能访问外网

docker pull 一直 timeout / connection reset

二、方案一(推荐):配置 Docker daemon 走代理 ✅
这是官方正确做法。

1️⃣ 创建 Docker systemd 代理目录
bash
复制代码
sudo mkdir -p /etc/systemd/system/docker.service.d
2️⃣ 写入代理配置
假设你的代理是:

cpp
复制代码
http://127.0.0.1:7890
创建文件:

bash
复制代码
sudo nano /etc/systemd/system/docker.service.d/http-proxy.conf
内容如下(按你真实代理改):

ini
复制代码
[Service]
Environment="HTTP_PROXY=http://127.0.0.1:7890"
Environment="HTTPS_PROXY=http://127.0.0.1:7890"
Environment="NO_PROXY=localhost,127.0.0.1"
保存退出。

3️⃣ 重新加载并重启 Docker
bash
复制代码
sudo systemctl daemon-reexec
sudo systemctl daemon-reload
sudo systemctl restart docker
4️⃣ 验证 Docker 是否真的吃到了代理
bash
复制代码
docker info | grep -i proxy
如果看到类似:

javascript
复制代码
HTTP Proxy: http://127.0.0.1:7890
HTTPS Proxy: http://127.0.0.1:7890
✅ 说明配置成功

5️⃣ 再次拉取 MongoDB
bash
复制代码
docker pull mongo:7.0
👉 这一步在国内 90% 情况可以成功

三、方案二(国内最稳):直接用国内 Docker 镜像源 🚀(强烈推荐)
即使你有代理,我也强烈建议你加国内镜像源,更快、更稳。

1️⃣ 编辑 Docker daemon 配置
bash
复制代码
sudo nano /etc/docker/daemon.json
填入(可全部复制):

json
复制代码
{
"registry-mirrors": [

"https://dockerproxy.com",
"https://mirror.ccs.tencentyun.com",
"https://hub-mirror.c.163.com"

]
}
2️⃣ 重启 Docker
bash
复制代码
sudo systemctl restart docker
3️⃣ 拉取 MongoDB(不需要代理也能成功)
bash
复制代码
docker pull mongo:7.0
✅ 这是国内成功率最高方案

四、推荐你用的最终组合方案(最稳)
✅ Docker daemon 代理 + 国内镜像源

代理:应对非镜像流量

镜像源:极快、极稳