本文将介绍 Debian KVM 环境下安装 MacOS 虚拟机. 安装过程将用最基础的系统环境安装, 并将完全不使用 virt-manager 组件.

  1. 为什么不使用 virt-manager 组件

    只是因为本人完全不熟悉 Python, 且用 virsh 生成和管理的 xml 配置完全没法用用人眼去阅读, 作为爱眼人士在此也提醒大家要保护好眼睛, 远离那些杂乱的文字. 很多人可能认为 KVM 一定需要 virsh 命令才能使用, 这也完全是个误区. 也许 virsh 在大型项目上能更好的管理虚拟机配置, 但对于入门和了解 QEMU-KVM机制 却也为很多人造成了很多困扰和门槛.

  2. 项目地址: OSX-KVM

安装所需要的工具和依赖库 🔗︎

1
2
apt-get install -y qemu git wget libguestfs-tools build-essential
# libguestfs-tools 用于 kholia/OSX-KVM项目 制作 MacOS 的安装镜像


下载 kholia/OSX-KVM项目 的源码 🔗︎

下载前请确保当前目录的可用空间大于 10GB

1
2
3
mkdir -p /opt
cd /opt
git clone --depth 1 https://github.com/kholia/OSX-KVM.git


获取苹果系统安装镜像 🔗︎

使用 kholia/OSX-KVM 项目 的 ./fetch-macOS-v2.py 脚本获取苹果系统安装镜像.

将使用 wget 或 curl 工具进行下载, 请在执行前确认是否已安装这2个工具之一.

  1. 执行脚本, 并选择你所需要的镜像进行下载
1
2
3
cd OSX-KVM
mkdir -p $PWD/workdir-fetch-macOS
./fetch-macOS-v2.py --action download -o $PWD/workdir-fetch-macOS

镜像列表的排列顺序不一定按新旧版本号排列,

请认真选择好填入你需要的序号,并回车.

脚本将会按照你的选择, 下载对应的镜像, 并命名为 BaseSystem.dmg .


  1. 查看下载完成的镜像大小, 一般大小在400MB+.
1
2
du -sh BaseSystem.dmg
# 476M    BaseSystem.dmg


  1. 把安装镜像转换为磁盘格式.
1
2
3
4
qemu-img convert BaseSystem.dmg -O raw BaseSystem.img
du -sh BaseSystem.img
# 1.3G    BaseSystem.img
# 转换完成后, 变大了不少


  1. 创建 MacOS 虚拟机将使用的磁盘.

    根据./OpenCore-Boot-CD.sh./OpenCore-Boot.sh 脚本里的需求, 我们必须命名为 mac_hdd_ng.img . 如下命令将创建一个 60GB 的虚拟硬盘.

1
2
3
4
qemu-img create -f qcow2 mac_hdd_ng.img 60G
du -sh mac_hdd_ng.img
# 196K    mac_hdd_ng.img
# 未安装系统的 mac_hdd_ng.img 磁盘文件很小

到此, MacOS安装镜像的准备工作均已完成.


虚拟机nat网络环境搭建(临时) 🔗︎

如果你需要使用桥接网络, 可以参考 QEMU-KVM使用macvtap桥接主机和虚拟机 进行设置, 要注意安装此苹果系统, 网卡名称必须为 tap0 .

为了不搞乱当前的系统网络设置, 我们将手动创建基于网桥的 IPv4 nat网络转发, 即使操作失误或运行出错, 重启过后也不会对我们的系统设置有任何影响.

  1. 创建和设置用于 nat的网桥 – br0 .
1
2
3
4
ip link add dev br0 type bridge
ip link set dev br0 address 02:01:02:03:04:08
ip addr add dev br0 192.168.66.1/24
ip link set dev br0 up


  1. 创建和设置用于qemu 绑定虚拟机使用的 tap网卡 – tap0 .
1
2
3
ip tuntap add dev tap0 mode tap
ip link set tap0 up promisc on
ip link set dev tap0 master br0


  1. 开启防火墙 nat 转发 .
1
2
3
4
5
# 启用内核 ip_forward
echo 1 > /proc/sys/net/ipv4/ip_forward

# 防火墙转发内网段上网
iptables -t nat -A POSTROUTING -m comment --comment "kvm-nat:192.168.66.0/24" -s 192.168.66.0/24 ! -d 192.168.66.0/24 -j MASQUERADE


  1. 搭建 dhcpd 自动给虚拟机分配IP .
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# 下载并解压源码
wget https://ftp.isc.org/isc/dhcp/4.4.2/dhcp-4.4.2.tar.gz
tar xvf dhcp-4.4.2.tar.gz
cd dhcp-4.4.2

# 配置源码工程
./configure \
	--prefix=/opt/dhcp \
	--sysconfdir=/opt/dhcp/etc/dhcp \
	--localstatedir=/var \
	--with-srv-conf-file=/opt/dhcp/etc/dhcp/dhcpd.conf \
	--with-srv-lease-file=/opt/dhcp/var/lib/dhcp/dhcpd.leases \
	--with-srv6-lease-file=/opt/dhcp/var/lib/dhcp/dhcpd6.leases \
	--with-cli-lease-file=/opt/dhcp/var/lib/dhcp/dhclient.leases \
	--with-cli6-lease-file=/opt/dhcp/var/lib/dhcp/dhclient6.leases \
	--with-srv-pid-file=/run/opt-dhcp/dhcpd.pid \
	--with-srv6-pid-file=/run/opt-dhcp/dhcpd6.pid \
	--with-cli-pid-file=/run/opt-dhcp/dhclient.pid \
	--with-cli6-pid-file=/run/opt-dhcp/dhclient6.pid \
	--with-relay-pid-file=/run/opt-dhcp/dhcrelay.pid \
	--with-relay6-pid-file=/run/opt-dhcp/dhcrelay6.pid \
	--with-libbind=no \
	--enable-dhcpv4o6 \
	--enable-paranoia \
	--enable-log-pid

# 编译
make

# 安装
make install DESTDIR=/tmp/opt-dhcp-installed
cp -RP /tmp/opt-dhcp-installed/opt /
mkdir -p /opt/dhcp/var/lib/dhcp
touch /opt/dhcp/var/lib/dhcp/dhcpd.leases

到此编译已完成, dhcp-4.4.2/ 源码目录可以删除.


编辑 vi /opt/dhcp/etc/dhcp/dhcpd.conf 使用最简单的配置方式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
option domain-name-servers 223.5.5.5, 114.114.114.114;
option subnet-mask 255.255.255.0;
option routers 192.168.66.1;

subnet 192.168.66.0 netmask 255.255.255.0 {
	range 192.168.66.50 192.168.66.100;

	## MAC地址,静态IP绑定,注释未启用
	# host macbookpro{
		# hardware ethernet 70:56:81:22:33:44;
		# fixed-address 192.168.66.2;
	# }
}


运行 dhcpd

1
2
3
mkdir -p /run/opt-dhcp
/opt/dhcp/sbin/dhcpd -4 br0
# 默认使用forking模式,后台运行了

到此, 虚拟机网络环境搭建准备工作均已完成.


安装 MacOS 操作系统 🔗︎

当你前面的准备工作全部完成后, 你总共就已完成了如下几个任务:

  • 系统安装盘 的准备
  • 虚拟机磁盘 的准备
  • nat 上网环境 的准备

那么,你就可以进一步到真正的系统安装工作了.

如果你当前虚拟机的磁盘上并未安装过系统,可执行 ./OpenCore-Boot.sh 直接启动安装, 有系统的话, 使用 ./OpenCore-Boot-CD.sh 启动安装. 此脚本适用于 Big Sur, Catalina, Mojave 和 High Sierra .

  1. 像正常安装黑苹果一样, 磁盘工具初始化磁盘 → 找到前面创建的60GB的磁盘 → 抹除 并使用 APFS.

    操作完成后关闭磁盘工具.

  2. 重新安装 MacOS 副本.

  3. 后面的过程就不累述了.


虚拟机nat网络环境固化(可选) 🔗︎

前面执行的命令若你需要固化到开机启动, 以便日后可以重复使用它们, 则需要按下面的方法去操作 systemd . 请确认你确实需要开机自运行该网络设置, 再进行操作.

  1. 新增网络设置脚本

新建文件 vi /etc/kvm-nat-duckgle.sh

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#!/bin/bash
if ! ip addr ls br0 | awk '/inet / {split($2, ary, /\//); print ary[1]}' | grep -q "192.168.66.1";then
	ip link set dev br0 down 2>/dev/null
	ip link del dev br0
	ip link add dev br0 type bridge
	ip link set dev br0 address 02:01:02:03:04:08
	ip addr add dev br0 192.168.66.1/24
	ip link set dev br0 up
fi
# 添加你将使用的tap网卡的名称, 到下面的变量里, 以空格隔开. 用于你想使用更多虚拟机到这个nat内网的情况下.
# tap0 在kholia/OSX-KVM/OpenCore-Boot-CD.sh 项目脚本里已写死, 必须填写
NAT_taps="tap0 "
for tap_nic in $NAT_taps;do
	if ! brctl show | grep -qE "br0[[:blank:]][[:blank:]]*.*${tap_nic}";then
		ip link set dev ${tap_nic} down 2>/dev/null
		ip link del dev ${tap_nic}
		ip tuntap add dev ${tap_nic} mode tap
		ip link set ${tap_nic} up promisc on
		ip link set dev ${tap_nic} master br0
	fi
done
if ! iptables-save | grep -q "kvm-nat-duckgle:";then
	iptables -t nat -A POSTROUTING -m comment --comment "kvm-nat-duckgle:192.168.66.0/24" -s 192.168.66.0/24 ! -d 192.168.66.0/24 -j MASQUERADE
fi
# 启用内核转发
sysctl -w net.ipv4.ip_forward=1
sysctl -w net.ipv4.conf.all.proxy_arp=1
sysctl -w net.ipv6.conf.all.forwarding=1

赋予可执行权限 chmod +x /etc/kvm-nat-duckgle.sh


  1. 设置开机启动

新建文件 vi /etc/systemd/system/kvm-nat-duckgle.service

1
2
3
4
5
6
7
8
[Unit]
After=network.target

[Service]
ExecStart=/etc/kvm-nat-duckgle.sh

[Install]
WantedBy=default.target


新建文件 vi /etc/systemd/system/dhcpd-duckgle.service

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
[Unit]
Wants=network-online.target
After=network-online.target kvm-nat-duckgle.service

[Service]
Type=forking
Restart=always
PIDFile=/run/opt-dhcp/dhcpd.pid
ExecStart=/opt/dhcp/sbin/dhcpd -4 br0
ExecStartPre=-/usr/bin/mkdir -p /run/opt-dhcp

[Install]
WantedBy=multi-user.target
  1. 执行使其生效

执行下面命令后, 启用这2个服务的开机自运行.

1
2
3
4
systemctl daemon-reload
systemctl enable kvm-nat-duckgle.service
systemctl enable dhcpd-duckgle.service
reboot


卸载方法 🔗︎

如果你后期需要卸载此编译软件, 可执行下列命令卸载.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# 停止服务
systemctl stop kvm-nat-duckgle.service
systemctl stop dhcpd-duckgle.service
killall dhcp

# 禁用自启动服务
systemctl disable kvm-nat-duckgle.service
systemctl disable dhcpd-duckgle.service

# 删除文件
rm -f /etc/systemd/system/dhcpd-duckgle.service
rm -f /etc/systemd/system/kvm-nat-duckgle.service

rm -rf /opt/dhcp
rm -rf /opt/kholia/OSX-KVM

# 重启
reboot