上一篇 下一篇 分享链接 返回 返回顶部

如何在香港服务器中部署和使用 KVM 与 Hyper-V 联合部署虚拟机,优化混合云环境下的资源调度与高可用性?

发布人:Minchunlin 发布时间:2025-08-24 11:43 阅读量:877

凌晨 2 点,Equinix HK3 的冷通道像一台低鸣的冰箱。客户两条业务线——一条纯 Linux 的高并发 API,一条重度依赖 Windows/AD/SQL Server 的金融子系统——之前全在 Hyper-V 上跑,授权成本和性能都逼近红线。我的目标很直接:

  • 新建一套 KVM 集群承载 Linux 与容器类负载;
  • 保留/升级现有 Hyper-V 负载(AD、IIS、SQL、Office 集成等);
  • 在同一机柜内把两套虚拟化底座“并行管理、策略统一、流量同域、容灾互助”;
  • 在需要时还能和公有云(Azure 香港区、AWS ap-east-1)拉专线/隧道形成混合云。
  • 我把它命名为 “双栈底座:KVM x Hyper-V”。

一、总体架构与设计取舍

1) 为什么要双栈

成本/性能:Linux 服务在 KVM 上更易榨干硬件,Windows 负载在 Hyper-V 上更稳妥,授权/生态也更顺。

隔离与弹性:两套资源池互不牵连,事故面缩小;统一的流量与目录服务打通,让“应用高可用”不受底座差异束缚。

混合云:Hyper-V 侧原生对 Azure 友好;KVM 侧更易与开源栈(Ceph、OVS、云原生)结合。

2) 机柜与网络拓扑(简化)

ToR:双 25GbE 交换机(MLAG),上联运营商 BGP(HKIX + 国际回程),CN 方向单独策略(可选 CN2/GIA)。

Underlay:所有计算节点走 L3,MTU 9000;KVM 侧 OVS/OVN,Hyper-V 侧 vSwitch(SET)。

Overlay:KVM 侧 VXLAN(OVN),Hyper-V 侧 VLAN/路由到同域;跨栈统一在汇聚层做 VRRP VIP + BGP Anycast。

3) 存储

KVM 集群:Ceph RBD(3 副本,NVMe + SSD 日志盘),给 libvirt/Nova 做块存储。

Hyper-V 集群:Storage Spaces Direct(S2D)或 StarWind vSAN(二选一,我这次用 S2D)。

跨栈:数据库与缓存用“各自主存储 + 应用级复制”(如 MySQL MGR / SQL Always On);必要时通过 NFS/SMB Gateway 做只读共享。

二、硬件与版本参数(现场落地)

机架与主机

角色 数量 型号/CPU 内存 本地盘 网卡 备注
KVM 计算+存储一体 4 2×Xeon Silver 4410Y 512GB 2×U.2 NVMe(OSD)、2×SSD(日记)、2×SATA(系统) 2×25GbE(CX6)、1×1GbE OOB CentOS 7(客户历史镜像依赖),内核 5.4 LTS backport
Hyper-V 节点 3 2×Xeon Gold 6330 512GB 4×U.2 NVMe(S2D Pool)、2×SATA(系统) 2×25GbE(X710/XL710)、1×1GbE OOB Windows Server 2022 Datacenter Core
网络设备 2 ToR 交换机 (25G/100G 上联) MLAG,BGP 到汇聚
边界设备 2 边界路由/防火墙 Anycast VIP,BGP 到运营商/云

注:CentOS 7 已 EOL,但客户现网大量镜像/驱动绑定其用户态 ABI,我采用“加固 + 受控升级 + 最小暴露面”的方案,并配合内核回移植与内网镜像仓。新项目建议直接用 Rocky/Alma 8/9。

三、网络与 IP 规划(摘录)

VLAN 用途 MTU 网段 备注
10 业务南北向 9000 10.10.10.0/24 Anycast VIP 所在
20 存储(Ceph + S2D) 9000 10.20.20.0/24 与业务隔离,启用 PFC/ECN(可选)
30 管理/OOB 1500 10.30.30.0/24 iDRAC/iLO + 管理口
40 迁移/备份 9000 10.40.40.0/24 KVM Live Migration、Hyper-V LM、备份流
50 混合云隧道 1500 10.50.50.0/24 到 Azure/AWS 的 IPSec/ExpressRoute/DirectConnect

四、KVM 集群落地(CentOS 7)

1) BIOS & 固件要点

开启 VT-x/VT-d、SR-IOV、NUMA、Hyper-Threading;电源策略设 “Performance”。

网卡/SSD 固件统一版本,避免 SR-IOV/VMD 与内核驱动不匹配。

2) OS 基线与内核

# 关闭不必要服务,设置 tuned,打开大页
yum install -y epel-release tuned chrony qemu-kvm libvirt libvirt-daemon-kvm \
               virt-install bridge-utils openvswitch ceph-common
tuned-adm profile network-latency
echo 'vm.nr_hugepages=8192' >> /etc/sysctl.conf
sysctl -p
systemctl enable --now chronyd libvirtd openvswitch

3) OVS/OVN 网络(示例)

# LACP 聚合 + OVS br0
nmcli con add type bond ifname bond0 mode 802.3ad miimon 100
nmcli con add type ethernet ifname ens3f0 master bond0
nmcli con add type ethernet ifname ens3f1 master bond0
ovs-vsctl add-br br0
ovs-vsctl add-port br0 bond0
ip link set br0 mtu 9000 up

# 业务/存储子接口
ovs-vsctl add-port br0 vlan10 tag=10 -- set interface vlan10 type=internal
ovs-vsctl add-port br0 vlan20 tag=20 -- set interface vlan20 type=internal
ip addr add 10.10.10.11/24 dev vlan10
ip addr add 10.20.20.11/24 dev vlan20

4) Ceph(cephadm 方式,概念配置)

# 引导与加入
cephadm bootstrap --mon-ip 10.20.20.11
cephadm shell -- ceph orch host add kvm02 10.20.20.12
cephadm shell -- ceph orch host add kvm03 10.20.20.13
cephadm shell -- ceph orch host add kvm04 10.20.20.14

# OSD 布署 & 池
cephadm shell -- ceph orch apply osd --all-available-devices
ceph osd pool create kube-vm 128 128 replicated
rbd pool init kube-vm

5) 将 RBD 援引到 libvirt

# 创建 Ceph 客户端密钥,并导入 libvirt secret
ceph auth get-or-create client.libvirt mon 'allow r' osd 'allow class-read object_prefix rbd_children, allow rwx pool=kube-vm' \
    -o /etc/ceph/ceph.client.libvirt.keyring

SECRET_UUID=$(uuidgen)
cat >/tmp/ceph-secret.xml <<EOF
<secret ephemeral='no' private='no'>
  <uuid>$SECRET_UUID</uuid>
  <usage type='ceph'>
    <name>client.libvirt secret</name>
  </usage>
</secret>
EOF
virsh secret-define /tmp/ceph-secret.xml
virsh secret-set-value --secret $SECRET_UUID --base64 $(ceph auth print-key client.libvirt | base64)

6) 定义一台 KVM 虚机(RBD 盘)

<!-- /tmp/vm-kvm01.xml -->
<domain type='kvm'>
  <name>api-node-01</name>
  <memory unit='GiB'>16</memory>
  <vcpu placement='static'>8</vcpu>
  <cpu mode='host-passthrough'>
    <numa>
      <cell id='0' cpus='0-7' memory='16GiB'/>
    </numa>
  </cpu>
  <features><acpi/><apic/><vmport state='off'/></features>
  <clock offset='utc'/>
  <devices>
    <disk type='network' device='disk'>
      <driver name='qemu' type='raw' cache='none' io='native'/>
      <auth username='libvirt'>
        <secret type='ceph' uuid='REPLACE-WITH-SECRET-UUID'/>
      </auth>
      <source protocol='rbd' name='kube-vm/api-node-01'>
        <host name='10.20.20.11' port='6789'/>
        <host name='10.20.20.12' port='6789'/>
        <host name='10.20.20.13' port='6789'/>
      </source>
      <target dev='vda' bus='virtio'/>
    </disk>
    <interface type='bridge'>
      <source bridge='br0'/>
      <model type='virtio'/>
    </interface>
    <channel type='unix'>
      <target type='virtio' name='org.qemu.guest_agent.0'/>
    </channel>
    <input type='tablet' bus='usb'/>
    <graphics type='vnc' port='-1' autoport='yes'/>
  </devices>
</domain>

virsh define /tmp/vm-kvm01.xml
virsh start api-node-01

7) KVM 侧 HA

简洁方案:Pacemaker + VirtualDomain 资源(每台虚机一个资源,配合 Ceph RBD)。

大规模方案:OpenStack(Nova/Neutron/Cinder)或 Proxmox(更易上手)。

我现场给核心业务线先上 Pacemaker(足够轻)。

pcs cluster auth kvm01 kvm02 kvm03 kvm04 -u hacluster -p '***'
pcs cluster setup --name kvm-ha kvm01 kvm02 kvm03 kvm04
pcs cluster start --all
# 为虚机创建 OCF 资源(示例)
pcs resource create vm_api_node_01 VirtualDomain hypervisor="qemu:///system" \
  config="/etc/libvirt/qemu/api-node-01.xml" meta priority=100 op monitor interval=30s
pcs resource group add grp_api vm_api_node_01

五、Hyper-V 集群落地(Windows Server 2022 Datacenter Core)

1) 基线安装与角色

# 安装 Hyper-V 与 Failover Clustering
Install-WindowsFeature -Name Hyper-V, Failover-Clustering, RSAT-Clustering-PowerShell -IncludeManagementTools -Restart

2) vSwitch(SET)与 NIC Team(25G)

# 以 SET 模式创建交换机
New-VMSwitch -Name vSwitch25G -AllowManagementOS $true -NetAdapterName "NIC25G-1","NIC25G-2" -EnableEmbeddedTeaming $true
Set-VMSwitch -Name vSwitch25G -EnableIovQueuePair $true
# VLAN/MTU
Set-NetAdapterAdvancedProperty -Name "vEthernet (vSwitch25G)" -DisplayName "Jumbo Packet" -DisplayValue "9014 Bytes"

3) Failover Cluster & Live Migration

New-Cluster -Name HV-Cluster -Node HV01,HV02,HV03 -StaticAddress 10.30.30.100
# 迁移网络优先级(使用 VLAN 40)
(Get-ClusterNetwork -Cluster HV-Cluster | Where-Object {$_.Address -like "10.40.40.*"}).Role = 3
Enable-VMMigration
Set-VMMigrationNetwork -NetworkAddress 10.40.40.0/24

4) Storage Spaces Direct(S2D)

Enable-ClusterS2D
New-Volume -StoragePoolFriendlyName "S2D on HV-Cluster" -FriendlyName VM-CSV -FileSystem CSVFS_ReFS -Size 20TB

5) 创建一台 VM(生产检查点模式)

New-VM -Name fin-sql-01 -MemoryStartupBytes 24GB -Generation 2 -NewVHDPath "C:\ClusterStorage\VM-CSV\fin-sql-01.vhdx" -NewVHDSizeBytes 500GB -SwitchName vSwitch25G
Set-VM -Name fin-sql-01 -ProcessorCount 8 -StaticMemory
Set-VMProcessor fin-sql-01 -ExposeVirtualizationExtensions $false
Set-VM -Name fin-sql-01 -CheckpointType Production
Start-VM fin-sql-01

六、跨栈“联合”:网络、流量与目录

1) 统一南北向入口:Keepalived + HAProxy(BGP Anycast)

在边界两台路由器跑 VRRP(Keepalived)拿到 10.10.10.10/24 的 VIP,同时对上游跑 eBGP 宣告 /32。虚机无论在 KVM 还是 Hyper-V,流量都从就近入口进入。

Keepalived 片段(简化):

vrrp_instance VI_10 {
  state MASTER
  interface vlan10
  virtual_router_id 10
  priority 150
  advert_int 1
  virtual_ipaddress {
    10.10.10.10/24 dev vlan10
  }
  track_interface {
    vlan10
  }
}

HAProxy 后端同时指向两栈:

backend app_backend
  balance leastconn
  server kvm-api-01 10.10.10.101:8080 check
  server kvm-api-02 10.10.10.102:8080 check
  server hv-api-01  10.10.10.201:8080 check

2) 目录与证书

AD 仍在 Hyper-V 集群上,两台 DC 做多站点复制;KVM 上的 Linux 节点用 sssd/realmd 对接 AD。

证书由 AD CS/Istio(可选)统一签发,Nginx/HAProxy 统一 TLS 终结。

七、调度策略:让“该去 KVM 的去 KVM,该留 Hyper-V 的留 Hyper-V”

我没有硬上单一的“大管家”。最终采用 Terraform + Ansible + 轻量打分脚本 的组合拳:

  • Terraform 同时接 libvirt(KVM)与 Hyper-V Provider;
  • 对每个“应用单元”标注资源偏好(如 os=linux / stateful=true / license_cost_weight=3);
  • 由一个 Python/Go 的小脚本读取各集群实时余量(Prometheus/SCOM 导出)、授权成本与 IOPS 余幅,计算目标落点。

打分模型(示意)

score = α*cpu_free + β*mem_free + γ*iops_headroom - λ*license_cost + ω*affinity
  • Linux 业务:KVM 得分基础 +20;
  • Windows/SQL:Hyper-V 得分基础 +25;
  • 峰值流量在 CN:靠近边界 GIA 的节点加权 +10。

Terraform 片段(libvirt + hyperv)

注意:社区 hyperv provider 存在版本差异,以下为示意结构

# KVM(libvirt)
provider "libvirt" {
  uri = "qemu+tcp://kvm-mgr/system"
}

resource "libvirt_volume" "api_vol" {
  name = "api-node-01.img"
  pool = "rbd-kube-vm"
  size = 50 * 1024 * 1024 * 1024
}

resource "libvirt_domain" "api_node" {
  name   = "api-node-01"
  vcpu   = 8
  memory = 16384
  disk { volume_id = libvirt_volume.api_vol.id }
  network_interface { bridge = "br0" }
  cloudinit = libvirt_cloudinit_disk.api_user_data.id
}

# Hyper-V(示意)
provider "hyperv" {
  endpoint = "https://hv-mgr:5986"
  username = "DOMAIN\\tfadmin"
  password = var.hv_pass
}

resource "hyperv_virtual_machine" "fin_sql_01" {
  name                 = "fin-sql-01"
  generation           = 2
  cpu_count            = 8
  memory_startup_bytes = 25769803776 # 24GB
  vhd {
    path = "C:\\ClusterStorage\\VM-CSV\\fin-sql-01.vhdx"
    size = 536870912000
  }
  network_adaptors = [{ switch_name = "vSwitch25G" }]
}

Ansible 则负责进主机后的统一配置(无论跑在哪栈):

- hosts: all
  become: yes
  tasks:
    - name: Register to AD (Linux)
      when: ansible_os_family == "RedHat"
      yum: name=realmd,sssd,oddjob,oddjob-mkhomedir,state=present
    - name: Install Windows exporter
      when: ansible_os_family == "Windows"
      win_chocolatey: name=windows-exporter state=present

八、跨栈高可用:底座 + 应用双层

底座 HA

  • KVM:Pacemaker 迁移 + Ceph 多副本;
  • Hyper-V:Failover Cluster + Live Migration + S2D CSV;
  • 网络:ToR MLAG,BGP ECMP,上游多运营商;
  • 入口:VRRP + Anycast。

应用 HA

  • 数据库:MySQL MGR(KVM 为主)/ SQL Server Always On(Hyper-V 为主);
  • 缓存:Redis 哨兵跨栈各放一台;
  • 无状态:KVM 上多实例 + HAProxy;
  • 灾备演练:每月一次“拔盘/断链/单点断电”演练,SLA 报表沉淀。

九、监控与日志

指标 工具 备注
节点与 VM Prometheus(node_exporter、qemu_exporter)、Windows Exporter 联到统一 Grafana
存储 Ceph mgr + ceph_exporter、S2D Health IOPS/延迟/重平衡
网络 sFlow/NetFlow、OVS stats、交换机 Telemetry 丢包/拥塞/ECN
日志 Loki/ELK + Winlogbeat 审计与事件

十、性能调优要点(我真正在生产上做的)

  • CPU/NUMA:KVM 关键 VM 绑定 vCPU 到同 NUMA cell;Hyper-V 启用 vNUMA,SQL/Redis 关闭节能 C-states。
  • HugePages:KVM 大页内存显著降低 TLB miss;Hyper-V 走 Large Page(默认即可)。
  • 网卡:两侧均开启 RSS/VMQ/VMMQ;KVM virtio-net 配合多队列(queues=4~8)。
  • IO:KVM 虚盘 cache=none, io=native;Ceph 调整 osd_op_queue;Hyper-V VHDX 放 CSV ReFS,启用写聚合。
  • 时钟同步:KVM 用 chrony,Hyper-V 用 w32time + PTP;跨栈 NTP 统一上游。

十一、我踩过的坑与现场解法(精选)

  • Windows 在 KVM 上蓝屏:客户旧镜像没装 VirtIO 驱动,挂载 virtio-win ISO 后进安全模式装驱动解决;后续 Packer 统一 bake 基线。
  • libvirt RBD 密钥不起效:virsh secret-set-value 用了错误的 base64,务必 print-key | base64 -w0。
  • OVS MTU 不一致:宿主 MTU 9000,但内侧 vlan10 接口忘了同步,导致偶发丢包;统一把 br0、bond0、内部口全设 9000。
  • Hyper-V Live Migration 慢:迁移网络没绑定到 VLAN 40 的 25G,走了管理 1G;按上面的 Set-VMMigrationNetwork 修正。
  • S2D 驱动与固件:一台节点 NVMe 固件偏低,S2D 报告间歇性降速;停机升级固件,恢复。
  • Ceph 重平衡扰动业务:默认 backfill 限制太宽,业务高峰抖动;限制 osd_max_backfills 并在窗口期 reweight,问题解。
  • BGP Anycast 黑洞:上游运营商对 /32 的 MED 处理与预期不符,少量城市走远端入口;加上 local-pref 与 prepend 分流。

十二、一次完整上线:从代码到可访问

  • Packer 产出两类镜像:linux-kvm.qcow2、win-hv.vhdx(内置代理、监控与 init)。
  • Terraform 根据打分结果把 API 组的 6 台 Linux 放 KVM,把 2 台 IIS 及 2 台 SQL 放 Hyper-V。
  • Ansible 做统一初始化与注册(AD/监控/日志)。
  • HAProxy 添加后端权重,金丝雀发布 10% 流量,观测延迟与错误。
  • 扩容/降级:KVM 侧 CPU 打满时,策略把新实例下发到 Hyper-V 侧临时填峰(通过容器 in-VM 或 IIS 反向代理),晚高峰后回切。

十三、基线表格(落地所需关键参数清单)

1) KVM libvirt/OVS 固定参数

参数 推荐值 说明
CPU Mode host-passthrough 获取接近裸金属性能
HugePages 1G/2M 视场景启用
网卡队列 4~8 virtio-net 多队列
虚盘 cache/io none/native 避免双缓存
MTU 9000 端到端一致

2) Hyper-V 关键参数

参数 推荐值 说明
vSwitch SET + 25G 团队/高带宽
Live Migration 专用 VLAN 40 迁移不扰业务
Checkpoint Production 应用一致性
vNUMA 启用 高内存/多 vCPU VM
CSV ReFS on S2D 性能与可靠性

十四、安全与合规(落地动作)

  • 南北向 WAF/IPS,东西向微分段(OVS ACL/Windows ACL)。
  • 补丁:Hyper-V 月补丁分波次,KVM 侧内核/用户态走灰度;内网 YUM/NuGet/Chocolatey 仓控。
  • 备份:KVM 用 restic + RBD 快照,Hyper-V 用 VSS 与 CSV 快照;备份网络独立(VLAN 40)。
  • 审计:AD/Azure Sentinel 对接,Linux sudo 审计上送 SIEM。

十五、从“两个世界”到“一个平台”的那一刻

最后一次演练,我们拔掉了 KVM 一台节点的两条 25G,上行照样走,API 50ms 的尾延没抬太多;再把一台 Hyper-V 节点置维护,SQL 自动漂移,金融子系统的曲线平平稳稳。

我从冷通道走出来,风墙后面灯还是一盏盏地亮着。KVM 与 Hyper-V 并不是对立的世界:该省钱的省钱,该稳的稳,该快的快。

真正的“联合部署”不是为了炫技,而是让业务在不同技术栈之间自由呼吸、稳稳落地。

附:标准化脚本与清单(可直接拿走改)

1) KVM 虚机模板化(cloud-init user-data)

#cloud-config
hostname: api-node
ssh_pwauth: false
users:
  - name: devops
    ssh_authorized_keys:
      - ssh-ed25519 AAAA...
    sudo: ['ALL=(ALL) NOPASSWD:ALL']
package_update: true
packages: [chrony, qemu-guest-agent]
runcmd:
  - systemctl enable --now qemu-guest-agent

2) Hyper-V 创建带静态 IP 的 VM(示例)

$vm="iis-web-01"
New-VM -Name $vm -Generation 2 -MemoryStartupBytes 12GB -SwitchName vSwitch25G -NewVHDPath "C:\ClusterStorage\VM-CSV\$vm.vhdx" -NewVHDSizeBytes 200GB
Set-VMProcessor $vm -Count 6
# 开机后用 cloudbase-init/脚本设置 IP & 加域

3) Pacemaker 资源组(批量)

for i in {01..06}; do
  pcs resource create vm_api_$i VirtualDomain hypervisor="qemu:///system" \
    config="/etc/libvirt/qemu/api-node-$i.xml" op monitor interval=20s
  pcs resource group add grp_api vm_api_$i
done
pcs constraint order start grp_api then grp_haproxy

4) HAProxy 熔断与金丝雀

backend app_backend
  balance leastrecent
  default-server check inter 2000 rise 2 fall 3
  server kvm-01 10.10.10.101:8080 weight 100
  server hv-01  10.10.10.201:8080 weight 10  # 金丝雀 10%

最后给你三条我验证过的“硬经验”

  • 端到端一致性比参数更重要:MTU、时钟、固件、驱动,任一处不一致,排障成本指数级上涨。
  • 应用级 HA 是跨栈的关键:别指望跨虚拟化“热迁移”,要靠数据库/缓存/入口层天然多活。
  • 把“打分与落点”显式化:写成脚本/管道,让每次扩缩容和变更都有依据、可复现、可审计。

如果你也正打算在香港上“双栈底座”,把上面这套清单按你的网络与合规改改,先从一条业务线金丝雀开始跑——你会像我一样,在凌晨 2 点从冷通道走出来,知道自己搭好了一个能抗事儿的底座。

目录结构
全文