宿主机环境:
windows service 2025 数据中心版

虚拟机:ubuntu 22.04

注:
1、测试过ubuntu 24.04,但是微软官方的WSL2-Linux-Kernel暂未支持到24.04,折腾失败,用22.04可正常使用

2、暂时略过怎么安装Hyper-V的过程,网上资料很多

踩坑点:

1、Hyper-V安装Linux虚拟机,需要关闭设置=>安全=>启用安全启动
2、windows service配置直通后,可能会出现虚拟机无法启动的情况
3、出现错误:/sbin/ldconfig.real: /usr/lib/wsl/lib/libcuda.so.1 is not a symbolic link,需要重新生成软连接,正文会详细讲解

步骤

1. 在 Windows 上添加 GPU 分区到虚拟机

使用管理员权限打开 PowerShell,执行下面命令。将 <vmname> 替换为 Hyper-V 虚拟机的名字。

Set-VM -VMName <vmname> -GuestControlledCacheTypes $true -LowMemoryMappedIoSpace 1GB -HighMemoryMappedIoSpace 32GB
Add-VMGpuPartitionAdapter -VMName <vmname>

执行完上面的命令后,可以在你的虚拟机执行下面的命令查看设备,如果能正确看到有设备列出,说明 GPU 分区已经添加成功了。

sudo lspci -v

2. 安装 dxgkrnl 驱动

参考 Ubuntu 21.04 VM with GPU acceleration under Hyper-V…?

创建一个脚本文件,例如 driver.sh,内容如下:

#!/bin/bash -e
BRANCH=linux-msft-wsl-5.10.y

if [ "$EUID" -ne 0 ]; then
    echo "Swithing to root..."
    exec sudo $0 "$@"
fi

apt-get install -y git dkms

git clone -b $BRANCH --depth=1 https://github.com/microsoft/WSL2-Linux-Kernel
cd WSL2-Linux-Kernel
VERSION=$(git rev-parse --short HEAD)

cp -r drivers/hv/dxgkrnl /usr/src/dxgkrnl-$VERSION
mkdir -p /usr/src/dxgkrnl-$VERSION/inc/{uapi/misc,linux}
cp include/uapi/misc/d3dkmthk.h /usr/src/dxgkrnl-$VERSION/inc/uapi/misc/d3dkmthk.h
cp include/linux/hyperv.h /usr/src/dxgkrnl-$VERSION/inc/linux/hyperv_dxgkrnl.h
sed -i 's/\$(CONFIG_DXGKRNL)/m/' /usr/src/dxgkrnl-$VERSION/Makefile
sed -i 's#linux/hyperv.h#linux/hyperv_dxgkrnl.h#' /usr/src/dxgkrnl-$VERSION/dxgmodule.c
echo "EXTRA_CFLAGS=-I\$(PWD)/inc" >> /usr/src/dxgkrnl-$VERSION/Makefile

cat > /usr/src/dxgkrnl-$VERSION/dkms.conf <<EOF
PACKAGE_NAME="dxgkrnl"
PACKAGE_VERSION="$VERSION"
BUILT_MODULE_NAME="dxgkrnl"
DEST_MODULE_LOCATION="/kernel/drivers/hv/dxgkrnl/"
AUTOINSTALL="yes"
EOF

dkms add dxgkrnl/$VERSION
dkms build dxgkrnl/$VERSION
dkms install dxgkrnl/$VERSION

注意:BRANCH 的值根据你的系统进行替换,可以执行 uname -a 查看具体需要替换的版本。

然后执行下面的命令安装驱动:

bash driver.sh

3. 从宿主机中拷贝 GPU 驱动到虚拟机

这里主要有两部分的驱动需要拷贝:

  1. 将宿主机中 xxx/Windows/System32/lxss/lib/* 的文件拷贝到虚拟机中的 /usr/lib/wsl/lib/
  2. 将宿主机中 xxx/Windows/System32/DriverStore/FileRepository/nvmdsi.inf_amd64_* 的目录拷贝到虚拟机中的 /usr/lib/wsl/drivers/

这是正常的copy的方式,当然,如果你本机已经安装了wsl,可以直接copy wsl的/usr/lib/wsl/直接到虚拟机中的/usr/lib/wsl/

copy完成后修改驱动的权限:

chmod -R 0555 /usr/lib/wsl

4. 配置动态链接库搜索路径并更新

直接copy过来的libcuda.so.1软链接是不能使用的,需要删除重新生成软连接

sudo rm /usr/lib/wsl/lib/libcuda.so.1
sudo ln -s libcuda.so /usr/lib/wsl/lib/libcuda.so.1

之后配置动态链接库搜索路径并更新

echo "/usr/lib/wsl/lib" > /etc/ld.so.conf.d/ld.wsl.conf
ldconfig

5. 重启虚拟机

【重启,到这没报错就重启虚拟机】
重启后执行下面的命令,查看能否正常输出:

ls -l /dev/dxg
/usr/lib/wsl/lib/nvidia-smi

如果输出正常的话,说明 GPU 直通成功了。(也可以将 nvidia-smi 直接软连接到 /usr/bin/ 目录下,这样就可以直接输入 nvidia-smi 执行)




参考资料:

https://blog.vogelcs.com/2024/05/21/Windows%E4%B8%8B%E7%9B%B4%E9%80%9AGPU%E8%AE%BE%E5%A4%87%E5%88%B0Hyper-V%E7%9A%84Ubuntu%E8%99%9A%E6%8B%9F%E6%9C%BA/

【hyper-v虚拟机安装ubuntu,免费开源linux桌面操作系统,详细安装教程】 https://www.bilibili.com/video/BV1QG411e7pn/?share_source=copy_web&vd_source=a8cb3aa675ec9bad747e8b96437b52da

【虚拟机打游戏,Hyper-V使用独立显卡教程】 https://www.bilibili.com/video/BV1o84y1y7i3/?share_source=copy_web&vd_source=a8cb3aa675ec9bad747e8b96437b52da

MessageChannel API允许我们创建一个新的消息通道,并通过它的两个MessagePort属性发送数据。

但是在拷贝包含function的对象时候会报错,提示无法copy

示例代码:

function copy(e) {
    const { port1, port2 } = new MessageChannel()
    port1.postMessage(e)
    return new Promise((resolve, reject) => {
        port2.onmessage = (event) => {
            resolve(event.data)
        }
    })
}

const test =  async function (params) {
    const a = {
        a: 1,
        b: 2,
    }
    const b = await copy(a)
    a.a = 5
    console.log(a, b);
}
test()

服务器资源

数量:3
CPU:2
内存:4

具体信息如下表:
| 系统类型 | IP地址 | 节点角色 | CPU | Memory | Hostname |
| :------: | :--------: | :-------: | :-----: | :---------: | :-----: |
| centos-7.5 | 192.168.31.92 | master | 2h | 4G | node-1 |
| centos-7.5 | 192.168.31.93 | master | 2h | 4G | node-2 |
| centos-7.5 | 192.168.31.94 | worker | 2h | 4G | node-3 |

- 阅读剩余部分 -

系统:Ubuntu 20.04.4 LTS

软件:dnsmasq

安装dnsmasq

apt install dnsmasq -y

操作dnsmasq的常用命令


service dnsmasq status # 查看状态
service dnsmasq stop # 停止
service dnsmasq restart # 重启
service dnsmasq start # 启动

关闭systemd-resolve

因为systemd-resolve服务会占用53端口,如果我们的DNS服务要绑定到0.0.0.0上,就会有冲突。

systemctl stop systemd-resolved # 关闭systemd-resolve

systemctl disable systemd-resolved  # 也可以用mask完全屏蔽

修改配置

安装好dnsmasq之后,默认的配置在/etc/dnsmasq.conf

创建一个目录,用来放自定义的dnsmasq配置文件

mkdir /data/dnsmasq

创建上级DNS配置文件

touch /data/dnsmasq/resolv.conf

内容如下

nameserver 119.29.29.29
nameserver 114.114.114.114
nameserver 8.8.8.8

创建dnsmasq.d目录,用来存放自定义的配置

mkdir /data/dnsmasq/dnsmasq.d

创建自定义hosts文件

touch /data/dnsmasq/dnsmasq.hosts

之后修改配置文件

# 端口,默认53
port=53


# 上级DNS配置
resolv-file=/data/dnsmasq/resolv.conf

# 开启严格顺序,这样查询上级DNS会从上到下依次查询
strict-order

# 修改监听配置,0.0.0.0允许任何IP访问
listen-address=0.0.0.0

# 自定义host
addn-hosts=/data/dnsmasq/dnsmasq.hosts

# 指向自定义配置目录
conf-dir=/data/dnsmasq/dnsmasq.d,*.conf

创建解析

解析说明:

# SRV 记录
#srv-host=<_service>.<_prot>.[<domain>],[<target>[,<port>[,<priority>[,<weight>]]]]
# A, AAAA 和 PTR 记录 
#host-record=<name>[,<name>....],[<IPv4-address>],[<IPv6-address>][,<TTL>]
# TXT 记录
#txt-record=<name>[[,<text>],<text>]
# PTR 记录 
#ptr-record=<name>[,<target>]
#naptr-record=<name>,<order>,<preference>,<flags>,<service>,<regexp>[,<replacement>]
# CNAME 别名记录
#cname=<cname>,<target>[,<TTL>]

比如说我现在需要把test.ibfpig.com通过A记录解析到本地的127.0.0.1

创建一个conf文件,比如ibfpig_com.conf

内容如下:

host-record=test.ibfpig.com,127.0.0.1

比如说我现在需要把*.ibfpig.top这样的泛域名解析到192.168.1.1

就可以追加内容如下:


address=/.ibfpig.top/192.168.1.1


修改配置文件后需要重启服务

步骤

  1. 将云服务挂载为本地磁盘
  2. 创建备份磁盘
  3. 指定时间机器的磁盘为备份磁盘

将云服务挂载为本地磁盘

将云服务挂载为本地磁盘的方案有很多,目前有很多的第三方工具都支持,比如Mountain Duck、S3fs、Goofys,这里选择juicefs,uicefs为对象存储的元数据提供了缓存,能极大的优化对挂载磁盘的list,get等操作。

  1. 注册并登陆juicefs

  2. 创建文件系统,因为我有很多其他的云服务都使用的腾讯云,所以我这里选择的是腾讯云的COS,小伙伴们可以根据自己的需求选择对应的服务

iShot2021-08-31 17.03.35.png

  1. 根据指引,挂载到Mac上

这里可以参考juicefs官网的提示,使用两行命令来操作

WechatIMG414.png

但是这里有个前提条件,就是Mac必须先安装osxfuse,非m1的电脑的安装过程我印象中下载之后直接安装就可以了,m1的系统里需要安装4.1以上的版本,这里可以直接去官网下载安装。

安装好之后,在系统的偏好设置=》安全性与隐私这里会有提示要安装一个什么扩展,点左下角的小锁之后点击安装扩展,之后会有个弹窗提示进入恢复系统,然后提示你点击关机。

关机之后,非m1的系统是cmd+R 进入恢复系统,m1是长按开机键进入恢复系统。进入恢复系统后,选取实用工具->启动安全性实用工具。具体流程可以参考在M1 Macbook上使用SSHFS挂载SFTP协议文件系统

安装好之后就可以继续操作挂载磁盘了。

两行命令中的第一行是下载juicefs,并给予juicefs权限,这里我选择直接克隆juicefs的github代码来编译,因为go1.17之后的版本支持arm系统了,所以我选择了直接编译。

自己克隆+编译的方式很简单:

git clone https://github.com/juicedata/juicefs.git ~/juicefs

cd ~/juicefs

make

chmod +x ./juicefs

之后就会在目录里发现一个juicefs的可执行文件,我们在接下来就进行挂载

cd ~/juicefs

sudo ./juicefs mount xxxxxxxxxxx /jfs 

这里的第二行的命令和juicefs文档上的第二行命令保持一致就可以了,如果需要把这个磁盘挂载到其他目录,可以修改/jfs为其他目录的路径

之后根据提示,输入云服务的相关凭证即可。

在访达中按下快捷键cmd+shift+c就能看到挂载的所有磁盘了。

进入到刚刚挂载的磁盘中,继续创建备份磁盘。

创建备份磁盘

cd /jfs
hdiutil create -size 1t -type SPARSEBUNDLE -fs "HFS+J" "Time Machine.sparsebundle"

这里的1t就是备份磁盘的大小,Time Machine.sparsebundle是文件的名称。

执行完成之后就能看到这个镜像文件了,之后双击打开即可。

iShot2021-08-31 17.37.39.png

之后右键上图红圈位置,可以给磁盘改名字,我这里就叫time

指定时间机器的磁盘为备份磁盘

我们可以进入/Volumes/Time中看一下,如果上一步挂载好了,这里会也会显示出来。

之后执行命令

sudo tmutil setdestination /Volumes/Time

搞定,然后打开系统偏好设置的世界机器看一下吧~

iShot2021-08-31 17.41.20.png

至此,在云服务上备份Mac就搞定了,但是相比于直接那个硬盘来备份,还是有些缺陷的

优缺点

优点:

  1. 不需要单独购买硬盘,不用担心硬盘损坏
  2. 不需要随身携带一个硬盘,有网就能用

缺点:

  1. 必须有稳定的网络才可以
  2. 在网络差的情况下,如果挂载了磁盘,会导致访达卡顿
  3. 需要持续为云服务付费
  4. 如果我电脑崩了,我需要在我电脑上再挂载一次之后才能恢复……

所以,基于以上的优缺点,我想了想,还是买了一块移动硬盘……然后移动硬盘和云服务备份同时使用。

参考文章:

https://kane.mx/posts/2019/using-s3-as-device-for-mac-time-machine-backup/

https://www.wannaexpresso.com/2021/03/12/m1-macbook-sshfs/