作者一言
已实测全流程安装Windows Server 2016, 发现不满足需求后卸载并重装为Windows Server 2019的完整过程,使用AI润色了一下文章XD,请放心食用。
-
若想安装更高或更低的Server版本,可以自行测试,截止文章发表时间,最高可安装Server 2025版本(不推荐,卡顿。作者打算跑OpenCode,发现最低支持Windows 2019, 所以后来才重装的)
-
个人主观测试4G内存下系统流畅程度:Windows Server 2012 = 2016 > 2019 > 2022 >> 2025(卡爆了)。 大于8G内存的机子实际上2019也很流畅了。并且2012及以下已经不支持很多软件了(如 Minecraft 基岩版服务端),甚至到目前2026年,2016也逐渐开始不兼容软件了(如OpenCode, Bun),所以2019是当前最具性价比的选择
-
但具体选择什么系统要看业务需求,像如果只要跑 GTA SAMP 服务端,那装windows server 2008甚至2003都行哈哈哈
Ubuntu KVM 部署 Windows Server 2016 完整实战指南 (避坑终极版)
这份指南将从零开始,手把手教您在 Ubuntu 物理机上,使用 KVM 虚拟化技术部署一台可供外部直接访问的 Windows Server 2016 虚拟机。跟着步骤执行,即可绕过所有经典陷阱,一路绿灯。
一、全新安装
阶段零:准备纯净版镜像与驱动
在开始安装之前,需要将 Windows 安装镜像和 KVM 驱动镜像准备好,并存放在 KVM 的专属目录中。
-
创建并进入工作目录(KVM 默认镜像存放路径):
mkdir -p /var/lib/libvirt/images/ cd /var/lib/libvirt/images/ -
下载 KVM 虚拟化驱动盘 (
virtio-win.iso):
直接在 Ubuntu 终端拉取 Red Hat 官方稳定版驱动。wget https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso -O /var/lib/libvirt/images/virtio-win.iso -
准备 Windows Server 2016 纯净版镜像 (
win2016.iso):-
获取镜像:推荐从 msdn.itellyou.cn 下载官方纯净版镜像(x64 架构,标准版或数据中心版均可)。
-
上传镜像:将下载好的文件重命名为
win2016.iso,并通过scp、sftp或rsync等工具上传到 Ubuntu 服务器的/var/lib/libvirt/images/目录下。 -
补充:或直接去官网下评估版:这个最快而且可以直接wget/curl下载到Linux下
Windows Server 2016 | Microsoft Evaluation Center
Windows Server 2019 | Microsoft Evaluation Center
Windows Server 2022 | Microsoft Evaluation Center
Windows Server 2025 | Microsoft Evaluation Center
更多版本直接去必应、百度、谷歌等引擎搜,进去随便填一些信息就可以到上面这些链接的页面。然后先选简体中文版本点击下载,在chrome或者edge这些浏览器可以在下载管理右键正在下载的项复制链接。或者可以用idm、ndm、迅雷等下载工具,可以直接获链接(这种链接一般是有时效的,复制了就要尽快使用) -
2019版评估版转正式版命令(在最后一步完成后,管理员启动Powershell执行)。其它版本自行百度搜寻
dism /online /set-edition:ServerDatacenter /productkey:WMDGN-G9PQG-XVVXX-R3X43-63DFG /accepteula -
阶段一:权限处理与虚拟机创建
-
经典大坑 1:权限拒绝 (Permission denied)
KVM 底层运行在libvirt-qemu用户下,必须确保镜像文件对此用户可读。# 赋予镜像文件读取权限 chmod 644 /var/lib/libvirt/images/win2016.iso chmod 644 /var/lib/libvirt/images/virtio-win.iso -
执行安装命令(以下配置为 16核/16GB内存示例,请根据实际情况调整):
virt-install \ --name WinServer2016 \ # 虚拟机名称 --ram 16384 \ # 内存大小 (MB) --vcpus 16 \ # CPU 核心数 --cpu host-passthrough \ # CPU 模式,直通宿主机 CPU 特性 --os-variant win2k16 \ # 操作系统变体,优化配置 --disk path=/var/lib/libvirt/images/win2016.qcow2,size=200,format=qcow2,bus=virtio,cache=none,io=native \ # 系统盘 --cdrom /var/lib/libvirt/images/win2016.iso \ # 挂载安装镜像 --disk path=/var/lib/libvirt/images/virtio-win.iso,device=cdrom \ # 挂载驱动镜像 --network network=default,model=virtio \ # 网络配置,使用默认 NAT 网络,virtio 模型 --graphics vnc,listen=0.0.0.0,port=5900 \ # 开启 VNC 用于安装,监听所有接口 --noautoconsole # 不自动打开控制台 -
放行 VNC 临时安装端口:
ufw allow 5900/tcp
阶段二:图形化安装与加载驱动
使用 RealVNC Viewer 或任何支持 VNC 协议的客户端,连接 物理机公网IP:5900 进入 Windows 安装界面。
-
经典大坑 2:选错版本变黑框- 在选择操作系统版本时,必须选择带有 “(桌面体验) / (Desktop Experience)” 字样的版本(例如:
Windows Server 2016 Datacenter (Desktop Experience))。
- 在选择操作系统版本时,必须选择带有 “(桌面体验) / (Desktop Experience)” 字样的版本(例如:
-
经典大坑 3:找不到硬盘- 安装进行到“您想将 Windows 安装在哪里?”这一步时,列表为空是正常的,因为系统不认识虚拟硬盘。
- 解决方法:
- 点击左下角的 “加载驱动程序” → “浏览”。
- 展开
virtio-win光盘,依次进入目录:viostor→2k16→amd64。 - 点击“确定”,选择并安装 “Red Hat VirtIO SCSI controller”。
- 驱动程序加载成功后,200GB 的硬盘就会自动出现,选中它,点击“下一步”继续安装。
阶段三:初始化、密码避坑与网卡修复
系统安装完成后会自动重启,进入最后的设置阶段。
重启陷阱:KVM 初次重启后自动关机
在安装进度条跑完后,Windows 安装程序会执行第一次重启。但 KVM 虚拟机有个常见特性:初次装完系统触发重启时,往往不会真正地 “重新启动” ,而是直接变成 “关机” 状态。
既然关机了,VNC 屏幕自然就断开连接了。别慌,只需两步即可解决。
第一步:查看虚拟机当前状态
在 Ubuntu 终端执行以下命令,检查虚拟机是否已变成关机状态:
virsh list --all
预期输出示例:
Id Name State
---------------------------------
- WinServer2016 shut off
如果看到 shut off,说明正是我们预料的情况。
第二步:手动重新开机
确认状态为关机后,直接执行启动命令:
virsh start WinServer2016
成功提示:
Domain 'WinServer2016' started
此时虚拟机已成功开机,并会自动从硬盘启动,继续完成 Windows 剩余的配置流程。
验证结果
回到 RealVNC Viewer,重新连接 IP:5900,你应该能看到 Windows 正在 “准备设备” 的转圈画面了。
故障排除完成
-
经典大坑 4:VNC 键盘映射错位(终极杀手)- 首次设置 Administrator 密码时,由于 VNC 客户端与虚拟机的键盘布局可能不一致,你输入的密码(特别是特殊符号)会被系统错误识别,导致后续无法登录。
- 绝杀方案:
- 进入桌面后,右键点击左下角“开始”徽标,选择 “命令提示符(管理员)”。
- 执行以下明文重置命令(建议先设置一个纯字母数字的简单密码以便登录,之后再修改复杂密码):
net user Administrator 你的新密码
-
安装网卡驱动(修复网络红叉):
- 右键点击左下角“开始”徽标,选择 “设备管理器”。
- 找到带有黄色感叹号的 “以太网控制器”,右键点击并选择 “更新驱动程序”。
- 选择 “浏览我的计算机以查找驱动程序”。
- 选择浏览位置为
virtio-win光盘(或者精确到NetKVM\2k16\amd64目录),点击“下一步”完成安装。 - 安装完成后,任务栏右下角的网络红叉就会消失,网络成功接通。
阶段四:网络配置与 Socat 端口转发
虚拟机默认使用 NAT 网络,拥有一个内网 IP(如 192.168.122.x)。我们需要通过端口转发,让外部网络能够直接访问虚拟机内的服务。
-
配置 Windows 虚拟机内部
- 获取内网 IP:按
Win + R键,输入cmd打开命令行,运行ipconfig,记录下IPv4 地址(假设为192.168.122.103)。 - 更改计算机名(可选):按
Win + R键,输入sysdm.cpl打开系统属性。在“计算机名”选项卡中,将随机名称改为易记的名称(如WIN-SERVER)。 - 开启远程桌面:在“远程”选项卡中,勾选 “允许远程连接到此计算机”,并务必取消勾选下方的 “仅允许运行使用网络级别身份验证的远程桌面的计算机连接(建议)”。
- 重启虚拟机使设置生效。
- 获取内网 IP:按
-
配置 Ubuntu 物理机(转发端)
-
安装 Socat 工具:
apt update apt install socat -y -
打通 RDP 远程桌面通道(将宿主机的
33899端口转发到虚拟机的3389端口):# 放行宿主机防火墙端口 ufw allow 33899/tcp # 使用 nohup 启动 socat 转发,使其在后台持久运行 # 格式:socat TCP4-LISTEN:宿主机端口,reuseaddr,fork TCP4:虚拟机IP:虚拟机端口 nohup socat TCP4-LISTEN:33899,reuseaddr,fork TCP4:192.168.122.103:3389 >/dev/null 2>&1 &后续连接:在本地电脑打开远程桌面连接 (mstsc),输入
物理机公网IP:33899,账号填计算机名\Administrator和之前重置的密码,即可丝滑连入。 -
打通业务端口(以 TCP
27015和 UDP7777为例):# 转发 TCP 业务端口 ufw allow 27015/tcp nohup socat TCP4-LISTEN:27015,reuseaddr,fork TCP4:192.168.122.103:27015 >/dev/null 2>&1 & # 转发 UDP 业务端口 ufw allow 7777/udp nohup socat UDP4-LISTEN:7777,reuseaddr,fork UDP4:192.168.122.103:7777 >/dev/null 2>&1 &
-
-
经典大坑 5:别忘了 Windows 内部防火墙
完成物理机的端口转发后,必须进入 Windows Server 虚拟机内部:- 打开 “高级安全 Windows Defender 防火墙”。
- 点击左侧的 “入站规则”,然后点击右侧的 “新建规则”。
- 根据向导,手动放行对应的业务端口(如
27015/7777)。否则,外部流量即使到达了虚拟机,也会被 Windows 系统防火墙拦截。
至此,您的 Windows Server 2016 虚拟机已在 Ubuntu KVM 上完美运行,并且可以通过网络畅通无阻地访问了。
二、卸载重装
KVM 虚拟化部署手记:Windows Server 2019 从零到一
阶段零:破而后立 —— 彻底销毁旧虚拟机
在创建新环境前,必须将占用的硬盘空间和后台端口彻底释放,做到斩草除根。
# 1. 拔掉电源并销毁档案
virsh destroy WinServer2016 # 强制关机
virsh undefine WinServer2016 # 删除虚拟机配置档案
# 2. 粉碎虚拟硬盘文件(释放空间的核心)
rm -f /var/lib/libvirt/images/win2016.qcow2
# 3. 清理残留的后台转发进程
pkill socat # 一键杀掉之前挂载的所有 socat 端口转发进程
(如果你还有其他不能杀的 socat 进程,可以先用 ps aux | grep socat 查出 PID,然后再用 kill -9 PID 单独杀)。
阶段一:运筹帷幄 —— 硬件分配的底层哲学
在合租服务器上分配资源,既要保证 Windows 编译时的极致性能,又要守住物理机不崩溃的底线。
| 资源类型 | 分配方案 | 底层原理 |
|---|---|---|
| 内存 (RAM) | 24 GB(甜点配置) | VirtIO Balloon(内存气球)机制:闲置时底层 Ubuntu 回收内存,编译时瞬间膨胀到 24 GB 上限 |
| 硬盘 (Disk) | 300 GB(动态上限) | QCOW2 精简制备 (Thin Provisioning):按实际使用量占用物理空间,用多少占多少 |
| 核心 (vCPU) | 16 核(黄金比例) | 必须预留保命空间:给底层 Ubuntu 留至少 4 个核心处理网络和 I/O 调度,避免满载死锁 |
阶段二:粮草先行 —— 准备纯净镜像
将核心镜像放到 KVM 公用目录下,并务必赋予读取权限,否则会报 Permission denied。
# 1. 拉取 KVM 官方驱动盘
wget https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso -O /var/lib/libvirt/images/virtio-win.iso
# 2. 准备系统盘与赋权
# 从 msdn.itellyou.cn 下载 Windows Server 2019 纯净版镜像
# 重命名为 win2019.iso 并通过 SFTP 上传到同一目录
chmod 644 /var/lib/libvirt/images/win2019.iso
chmod 644 /var/lib/libvirt/images/virtio-win.iso
阶段三:开天辟地 —— 一键创建虚拟机
在 Ubuntu 终端执行以下命令,启动 2019 安装向导,并临时放行 VNC 端口:
virt-install \
--name WinServer2019 \
--ram 24576 \
--vcpus 16 \
--cpu host-passthrough \
--os-variant win2k19 \
--disk path=/var/lib/libvirt/images/win2019.qcow2,size=300,format=qcow2,bus=virtio,cache=none,io=native \
--cdrom /var/lib/libvirt/images/win2019.iso \
--disk path=/var/lib/libvirt/images/virtio-win.iso,device=cdrom \
--network network=default,model=virtio \
--graphics vnc,listen=0.0.0.0,port=5900 \
--noautoconsole
# 放行防火墙
ufw allow 5900/tcp
阶段四:步步惊心 —— 图形化安装的三大“天坑”
使用 RealVNC Viewer 连接 物理机公网IP:5900 进入安装画面。请务必躲开以下三个雷区:
黑框天坑
选择版本时,必须选择带有 “(桌面体验) / (Desktop Experience)” 字样的版本。
硬盘失踪坑
到选择安装位置时列表为空。
- 点击 “加载驱动程序” → “浏览”
- 展开
virtio-win光驱 → 依次进入viostor\2k19\amd64 - 加载 Red Hat 驱动后即可看到 300 GB 硬盘
VNC 键盘错位坑(终极杀手)
首次开机设置密码时,VNC 极易把特殊符号打错(如 # 打成 3)。
破局方法:
- 首次设置:使用绝对不带特殊符号的纯字母数字密码
- 双保险:进桌面后,右键开始菜单打开 “命令提示符(管理员)”,敲入:
明文强制重置一次!net user Administrator 新密码
小贴士:进桌面后别忘了去 “设备管理器”,右键带有黄色感叹号的 “以太网控制器”,浏览光驱目录更新网卡驱动,接通网络。
阶段五:暗渡陈仓 —— 突破内网打通 RDP 与业务端口
虚拟机拿到 192.168.122.x 的内网 IP,需要在内部开门,在外部修路。
第一步:Windows 内部配置(被控端)
-
改名顺应习惯
Win + R输入sysdm.cpl→ “计算机名” 改成易记名前缀 → 重启 -
解除 NLA 封印
“远程” 选项卡 → 勾选 “允许远程连接”
绝对取消勾选 “仅允许运行使用网络级别身份验证(NLA)…”
这样后续可用你的易记名\Administrator直接丝滑登录
第二步:Ubuntu 物理机转发(转发端)
回到物理机终端,使用 socat 把物理机的端口映射给虚拟机(假设虚拟机 IP 为 192.168.122.103):
打通 RDP 远程桌面通道(TCP 3389)
# 放行防火墙
ufw allow 33899/tcp
# 启动转发(后台运行)
nohup socat TCP4-LISTEN:33899,reuseaddr,fork TCP4:192.168.122.103:3389 >/dev/null 2>&1 &
此时,可用本地电脑的 mstsc 连接 物理机IP:33899,享受极致高清的远程桌面,并可以关掉 VNC 了。
打通后续业务端口(示例)
# 转发 TCP 端口(如 27015)
ufw allow 27015/tcp
nohup socat TCP4-LISTEN:27015,reuseaddr,fork TCP4:192.168.122.103:27015 >/dev/null 2>&1 &
# 转发 UDP 端口(如 7777)
ufw allow 7777/udp
nohup socat UDP4-LISTEN:7777,reuseaddr,fork UDP4:192.168.122.103:7777 >/dev/null 2>&1 &
终极提醒
外部端口打通后,千万别忘了进入 Windows 内部的 “高级安全 Windows Defender 防火墙”,新建入站规则把这些端口放行,否则一切白搭!