在香港服务器上,如何利用虚拟化技术实现 Windows 与 Linux 双栈运行以支撑混合应用

凌晨两点,我刚把新到的 1U 服务器上架完毕,香港运营商给的 /29 IPv4 已经通告到机柜,10G 上联链路灯常亮。业务同事的诉求很直接:一套机器,同时跑 .NET(Windows)和容器化的 Python/Node(Linux),还能抗住晚高峰,出了问题要能现场复盘。
我决定用 KVM(基于 CentOS 7 的宿主机) 做虚拟化底座,一台物理机上跑 Windows Server 2019 与 CentOS 7 两台 VM,前者承接 IIS/.NET 与部分依赖 Windows 的内部服务,后者承接 Nginx/容器编排/任务队列等。网络侧我用 Linux Bridge + SR-IOV,把一条 10G VF 直通给 Windows,保证 IIS/后端文件传输不掉链子;Linux VM 走 virtio-net + Bridge,配合 Nginx 做南北向与东西向流量汇聚。
目标与架构
目标: 在一台香港机房的独立服务器上,通过虚拟化同时稳定运行 Windows 与 Linux 两类工作负载,形成“前端接入层 + Windows 业务层 + Linux 应用层/网关层”的混合应用承载架构,并解决性能、稳定性、可观测与备份恢复等问题。
简述架构要点:
- Hypervisor:CentOS 7 + KVM(qemu-kvm / libvirt)
- 存储:NVMe LVM Thin + RAW/LV(Windows 用 RAW LV,Linux 用 QCOW2/LV)
- 网络:bond0 聚合 → br0(公网)/ br-int(内网),Windows 额外拿到一张 SR-IOV VF 直通网卡,Linux 使用 virtio-net
- 优化:HugePages、CPU 亲和、Guest Agent、磁盘 I/O 调优、时钟同步
- 安全与可观测:分区防火墙、Jump 主机、Prometheus/Telegraf、集中日志
- 备份:快照 + 冷备镜像 + 配置导出,覆盖单点恢复与跨宿主迁移
现场硬件与网络信息(示例配置)
| 项目 | 参数 |
|---|---|
| 机型 | Supermicro 1U(双 10G SFP+) |
| CPU | Intel Xeon Silver 4210R(10C/20T) |
| 内存 | 128GB DDR4 ECC |
| 系统盘 | 2 × SATA SSD 480GB(RAID1) |
| 数据盘 | 2 × NVMe U.2 1.92TB |
| 网卡 | Intel X710-DA2(支持 SR-IOV) |
| 上联 | 10G,运营商混合带宽(香港本地/国际线路) |
| 公网 | /29 IPv4(5 个可用),/64 IPv6(可选) |
| 机房 | 香港岛某机房,远程带外 IPMI 已开通 |
注:型号可替换,同类参数即可;关键是 SR-IOV 支持 与 NVMe 本地盘。
方案取舍与核心理由
为啥选 KVM + CentOS 7?
用户态与内核态可控,生态成熟;CentOS 7 在不少香港机房镜像与运维体系内仍是“兼容性最优解”。(若你更偏爱 Proxmox/ESXi,同样思路可横移。本文聚焦 CentOS 7 环境。)
Windows 为何放在 RAW LV 上?
Windows 对底层 I/O 时延比较敏感,RAW/LV + io=native,cache=none 能把性能拉满。
为何给 Windows 做 SR-IOV?
IIS/SMB/备份/数据交换常有大流量,SR-IOV 直通带来接近裸金属的吞吐与更稳定的延迟。
Linux VM 用 Bridge + virtio-net?
性价比高、灵活接多 VLAN,叠加 Nginx/Haproxy/容器网络更顺手。
一、前置准备(BIOS、RAID、内核)
1)BIOS/UEFI
开启 VT-x/VT-d(Intel IOMMU)
关闭 C-States(或保守启用),确保时钟稳定
开启 SR-IOV 支持(若有独立开关)
2)磁盘布局
系统盘(RAID1) 安装 CentOS 7(宿主机)
NVMe 用于 VM 数据:建议 LVM Thin(支持细粒度快照)、Windows VM 则创建 RAW 逻辑卷
3)内核参数(IOMMU / HugePages)
编辑 /etc/default/grub 增加(Intel 平台):
GRUB_CMDLINE_LINUX="crashkernel=auto rhgb quiet intel_iommu=on iommu=pt transparent_hugepage=never default_hugepagesz=1G hugepagesz=1G hugepages=16"
更新引导并重启:
grub2-mkconfig -o /boot/grub2/grub.cfg
reboot
4)系统角色优化
yum install -y qemu-kvm libvirt libvirt-daemon-kvm virt-install qemu-img virt-top tuned chrony bridge-utils lvm2 mdadm
systemctl enable --now libvirtd
tuned-adm profile virtual-host
systemctl enable --now chronyd
二、网络设计与落地(Bond/Bridge/VLAN/SR-IOV)
1)链路聚合(802.3ad)
/etc/sysconfig/network-scripts/ifcfg-eno1
TYPE=Ethernet
BOOTPROTO=none
NAME=eno1
DEVICE=eno1
ONBOOT=yes
MASTER=bond0
SLAVE=yes
/etc/sysconfig/network-scripts/ifcfg-eno2
TYPE=Ethernet
BOOTPROTO=none
NAME=eno2
DEVICE=eno2
ONBOOT=yes
MASTER=bond0
SLAVE=yes
/etc/sysconfig/network-scripts/ifcfg-bond0
DEVICE=bond0
TYPE=Bond
ONBOOT=yes
BOOTPROTO=none
BONDING_OPTS="mode=802.3ad miimon=100 lacp_rate=1 xmit_hash_policy=layer3+4"
2)公网桥接 br0(举例)
/etc/sysconfig/network-scripts/ifcfg-br0
TYPE=Bridge
DEVICE=br0
ONBOOT=yes
BOOTPROTO=static
IPADDR=xx.xx.xx.10
PREFIX=29
GATEWAY=xx.xx.xx.9
DELAY=0
把 bond0 挂到 br0:
在 ifcfg-bond0 里加:
BRIDGE=br0
3)内网桥接(可选)
br-int 用于 VM 互联/VLAN 隔离,这里略。
4)启用 SR-IOV(Intel X710 例)
确保内核已启用 IOMMU,加载驱动并创建 VF:
# 查看 PF 名称(如 ens2f0)
lspci | grep -i ether
# 创建 4 个 VF(重启后需固化)
echo 4 > /sys/class/net/ens2f0/device/sriov_numvfs
# 如需固化:/etc/rc.local 添加上一行并 chmod +x /etc/rc.local
绑定 VF 给 vfio-pci(以 8086:154c 为例,真实请以 lspci -nnk 查询):
modprobe vfio-pci
echo "8086 154c" > /sys/bus/pci/drivers/vfio-pci/new_id
直通时,请记录 VF 的 PCI 地址,供 libvirt XML 使用。
三、存储规划与 LVM Thin
1)PV/VG/Thin Pool
pvcreate /dev/nvme0n1 /dev/nvme1n1
vgcreate vg_kvm /dev/nvme0n1 /dev/nvme1n1
lvcreate -L 200G -n thinpoolmeta vg_kvm
lvcreate -L 1.5T -n thinpool vg_kvm
lvconvert --type thin-pool vg_kvm/thinpool --poolmetadata vg_kvm/thinpoolmeta
2)给 VM 分配卷
Windows(RAW LV,直连块设备)
lvcreate -V 200G -T vg_kvm/thinpool -n lv_win2019
Linux(QCOW2 放在 Thin 上)
qemu-img create -f qcow2 -o preallocation=metadata /var/lib/libvirt/images/centos7-app.qcow2 120G
四、创建 Linux VM(CentOS 7 应用层)
你可以用 ISO,也可以用 Kickstart/Cloud-Init。这里用 ISO 简洁演示。
virt-install \
--name app-centos7 \
--memory 16384 \
--vcpus 8 \
--cpu host-passthrough \
--disk path=/var/lib/libvirt/images/centos7-app.qcow2,format=qcow2,cache=none,io=native,bus=virtio \
--cdrom /iso/CentOS-7-x86_64-Minimal.iso \
--network bridge=br0,model=virtio \
--os-variant centos7.0 \
--graphics vnc,listen=0.0.0.0 \
--noautoconsole
进入系统后(VM 内):
yum install -y epel-release
yum install -y qemu-guest-agent net-tools chrony
systemctl enable --now qemu-guest-agent chronyd
# 时间同步:/etc/chrony.conf 增加香港池
echo "server 0.hk.pool.ntp.org iburst" >> /etc/chrony.conf
systemctl restart chronyd
五、创建 Windows VM(Windows Server 2019)
1)准备 ISO
Win2019.iso
virtio-win.iso(提供 VirtIO 存储/网卡驱动与 qemu-guest-agent MSI)
2)创建并安装
virt-install \
--name win2019 \
--memory 32768 \
--vcpus 12,sockets=1,cores=6,threads=2 \
--cpu host-passthrough \
--disk path=/dev/vg_kvm/lv_win2019,format=raw,cache=none,io=native,bus=virtio \
--cdrom /iso/Win2019.iso \
--disk path=/iso/virtio-win.iso,device=cdrom \
--network bridge=br0,model=virtio \
--os-variant win2k19 \
--graphics vnc,listen=0.0.0.0,password=StrongVNC! \
--noautoconsole
安装时找不到磁盘:在 Windows 安装界面“加载驱动”,从第二张光驱选择 viostor/vioscsi 对应版本,随后即可识别 virtio 磁盘。完成后装好 NetKVM(网卡)与 “QEMU Guest Agent”。
六、为 Windows 直通 SR-IOV VF(高吞吐)
1)确认 VF 的 PCI 地址(宿主):
# 示例输出:0000:03:10.2
lspci -nnk | grep -iA3 ether
2)编辑 Windows VM 的 XML(以 virsh edit win2019)添加:
<hostdev mode='subsystem' type='pci' managed='yes'>
<source>
<address domain='0x0000' bus='0x03' slot='0x10' function='0x2'/>
</source>
</hostdev>
3)Windows 内安装对应 VF 的 NIC 驱动(virtio 或厂商驱动),配置静态 IP。完成后,Windows 将拥有 一张 virtio 网卡(管理/备份) + 一张 SR-IOV 直通网卡(高性能业务)。
七、性能优化清单(落地即用)
CPU 模式:host-passthrough,尽可能暴露宿主指令集
HugePages:宿主启用 1G HugePages;VM XML 中添加:
<memoryBacking>
<hugepages/>
</memoryBacking>
CPU 亲和:为关键 VM 固定 vCPU 到同一 NUMA 节点,示例:
<cputune>
<vcpupin vcpu='0' cpuset='2'/>
<vcpupin vcpu='1' cpuset='3'/>
...
</cputune>
- 磁盘 I/O:cache=none, io=native;Windows 关闭磁盘写缓存策略冲突
- 网卡 Offload:遇到奇怪丢包/高延迟,可在 VM 内适度关闭 GRO/LRO/TSO 测试
- 时钟同步:宿主 chrony,Linux VM chrony,Windows 使用 w32tm 指向同一 NTP 池
- Guest Agent:确保启用,便于快照、IP/状态查询与优雅关机
八、混合应用部署范式(示例)
1)Linux VM:Nginx 作为南北向入口
yum install -y nginx
cat >/etc/nginx/conf.d/app.conf<<'EOF'
upstream dotnet_pool {
server 10.10.10.21:5000; # Windows 内 IIS 上的反代站点/应用端口
keepalive 64;
}
server {
listen 80;
server_name example.hk;
location / {
proxy_pass http://dotnet_pool;
proxy_http_version 1.1;
proxy_set_header Connection "";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
EOF
nginx -t && systemctl enable --now nginx
2)Windows VM:IIS/.NET Core 承载
通过 SR-IOV 网卡承接业务流量,IIS 站点绑定该网卡 IP
装好 ASP.NET Core Hosting Bundle / Web Deploy(视应用栈)
3)东西向通信
Linux VM 与 Windows VM 通过 br-int 或二张网卡的内网段互通
文件/日志可用 SMB/NFS(跨 OS 共享时注意权限与锁语义)
九、可观测与告警
Metrics:Prometheus + Node Exporter(Linux)、Windows Exporter(Windows)
日志:Filebeat/Fluent Bit → Elasticsearch/OpenSearch 或 Loki
链路追踪:Jaeger/Tempo(如果你的服务已接入)
系统级监控:Zabbix/Telegraf + InfluxDB + Grafana,关键指标(网卡吞吐、磁盘延迟、CPU Steal、内存 Balloon)
十、备份与快照策略
配置级:virsh dumpxml 保存到 Git(加密仓库)
磁盘级:
Linux VM:virsh snapshot-create-as 做在线快照(QCOW2/Thin)
Windows VM(RAW LV):使用 lvcreate -s 做 LVM 快照(注意一致性窗口),或关机后 dd/qemu-img 冷备
文件级:Linux 用 rsync/restic,Windows 用 VSS 感知型备份
跨机房:周更镜像 + 月度全量,异地加密存储
十一、常见坑与现场解法
1)Windows 安装时看不到磁盘
解决:加载 virtio-win.iso 中的存储驱动(viostor/vioscsi)。
2)SR-IOV VF 无法直通/直通后不识别
核对:intel_iommu=on;IOMMU 组是否干净;VF 是否已绑定 vfio-pci;Windows 内驱动版本匹配。
若机房交换机侧未开 LACP/Trunk,对应 VLAN 无法通,请与网络同事确认端口策略。
3)Bridge 丢包或延迟抖动
在 VM 内测试关闭 GRO/LRO/TSO;宿主升级网卡驱动;核查 ethtool -k 状态。
高 PPS 场景考虑在 Linux VM 侧也使用 SR-IOV。
4)LVM Thin 元数据爆满(VM 挂起)
lvs -a
lvextend -L +20G vg_kvm/thinpoolmeta
lvconvert --repair vg_kvm/thinpool
同时优化:开启 fstrim.timer,定期 fstrim -av。
5)时钟漂移
宿主与所有 VM 统一到同一 NTP 池;Windows 禁用从宿主同步,改为外部可信源。
6)在线迁移失败
直通设备(SR-IOV/GPU)会阻断热迁移——计划停机窗口 或改用 vSwitch 方案。
十二、参考性能(典型范围,供你对标)
| 场景 | 配置 | 指标范围(示例) |
|---|---|---|
| Windows VM 通过 SR-IOV | iperf3 单流 | 8.5–9.6 Gbps |
| Linux VM virtio-net + Bridge | iperf3 单流 | 4.5–7.5 Gbps |
| NVMe RAW(Windows LV) | fio 4k randread QD=32 | 250k–450k IOPS |
| QCOW2(Linux VM) | fio 4k randread QD=32 | 150k–300k IOPS |
| Nginx 反代(1 台) | 1KB 静态/长连 | 80k–150k RPS(视 CPU/内核参数而变) |
说明:这是在可比硬件/内核/驱动与“干净链路”下的常见区间,只作对标参考;你的结果会受固件、驱动、策略、MTU、队列数等强烈影响。
十三、上线与回头看:那一刻风终于停了
凌晨四点半,IIS 的日志开始有规律地滚动,Nginx 的访问曲线像一条平静的河。我把最后一个 virsh snapshot-create-as 扔进定时任务,又核对了一遍 chronyc sources 与备份目标的延时。业务群里有人说,“晚高峰 2 倍流量也没抖。”
我合上机柜门,空调风小了,风声像从很远的海面退去。
这套“Windows + Linux 双栈”的混合架构,在香港这台 1U 里,以一种可维护、可回滚、可扩展的方式安静地运转起来——这才是我想要的“稳”。
附:命令与配置速查(可直接复用)
# 核心软件
yum install -y qemu-kvm libvirt libvirt-daemon-kvm virt-install qemu-img virt-top tuned chrony bridge-utils lvm2
# 启动服务
systemctl enable --now libvirtd chronyd
tuned-adm profile virtual-host
# HugePages(开机参数已设),验证
grep -i huge /proc/meminfo
# Bond/Bridge(示例文件路径)
# /etc/sysconfig/network-scripts/ifcfg-eno1, ifcfg-eno2, ifcfg-bond0, ifcfg-br0
# SR-IOV(示例:创建 4 个 VF)
echo 4 > /sys/class/net/ens2f0/device/sriov_numvfs
modprobe vfio-pci
# LVM Thin
pvcreate /dev/nvme0n1 /dev/nvme1n1
vgcreate vg_kvm /dev/nvme0n1 /dev/nvme1n1
lvcreate -L 200G -n thinpoolmeta vg_kvm
lvcreate -L 1.5T -n thinpool vg_kvm
lvconvert --type thin-pool vg_kvm/thinpool --poolmetadata vg_kvm/thinpoolmeta
# 创建卷(Windows RAW / Linux QCOW2)
lvcreate -V 200G -T vg_kvm/thinpool -n lv_win2019
qemu-img create -f qcow2 -o preallocation=metadata /var/lib/libvirt/images/centos7-app.qcow2 120G
# Linux VM(CentOS 7)
virt-install --name app-centos7 --memory 16384 --vcpus 8 --cpu host-passthrough \
--disk path=/var/lib/libvirt/images/centos7-app.qcow2,format=qcow2,cache=none,io=native,bus=virtio \
--cdrom /iso/CentOS-7-x86_64-Minimal.iso \
--network bridge=br0,model=virtio --os-variant centos7.0 \
--graphics vnc,listen=0.0.0.0 --noautoconsole
# Windows VM(Win2019 + VirtIO 驱动盘)
virt-install --name win2019 --memory 32768 --vcpus 12 --cpu host-passthrough \
--disk path=/dev/vg_kvm/lv_win2019,format=raw,cache=none,io=native,bus=virtio \
--cdrom /iso/Win2019.iso --disk path=/iso/virtio-win.iso,device=cdrom \
--network bridge=br0,model=virtio --os-variant win2k19 \
--graphics vnc,listen=0.0.0.0,password=StrongVNC! --noautoconsole
# Windows VM XML:直通 SR-IOV VF(示例)
# virsh edit win2019,添加:
# <hostdev mode='subsystem' type='pci' managed='yes'>
# <source>
# <address domain='0x0000' bus='0x03' slot='0x10' function='0x2'/>
# </source>
# </hostdev>
# 快照(Linux QCOW2)
virsh snapshot-create-as --domain app-centos7 --name pre_release_$(date +%F) --description "pre-release"
# LVM 快照(Windows RAW;需规划一致性)
lvcreate -s -n snap_win2019_$(date +%F) -L 50G /dev/vg_kvm/lv_win2019
# 时间同步(宿主)
echo "server 0.hk.pool.ntp.org iburst" >> /etc/chrony.conf
systemctl restart chronyd
如果你打算把这套方案规模化(多台物理机、集群调度、统一网络与存储抽象),可以在 KVM 基座上引入 oVirt/OKD/Harvester/Proxmox 集群 等更高层的管理与编排;但哪怕就一台香港服务器,上述方法已经能让 Windows 与 Linux 在一台机器里,稳定、快、可维护 地“各司其职”,撑起一套不折不扣的混合应用。