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

如何在香港服务器的跨平台系统中通过配置异构虚拟化平台,实现Windows和Linux混合环境下的容器管理?

发布人:Minchunlin 发布时间:2025-08-27 10:53 阅读量:791


凌晨3点,我第一次在香港中环IDC机房里撸这个环境,客户要把一套历史包袱很重的 .NET Framework 服务(只能跑 Windows 容器)和新写的 Go/Node 服务(Linux 容器)统一到一个调度面上,还要求弹性扩缩、蓝绿发布、跨城容灾。实话说,第一次拿到需求时,我也皱了下眉:Windows + Linux 混编 + 异构虚拟化,而且还是在香港的多线网络环境里——这意味着网络、存储、MTU、镜像、授权都会踩雷。

我最后的架构选择是:KVM(Proxmox VE)承载 Linux 控制面与 Linux 工作节点;Hyper-V 承载 Windows 容器工作节点;上层用 Kubernetes 做统一调度。这么做的好处是——各用各的强项,KVM 撑高密度、Hyper-V 给 Windows 容器稳定的内核与驱动生态,同时在香港机房用 VLAN/EVPN 把它们拉到一个二层/三层混合的“同一内网”里。

1. 目标与边界

目标:在香港机房落地一套支持 Windows 容器 + Linux 容器混跑 的统一容器平台,具备弹性伸缩、负载均衡、可观测、持久化存储、灰度/蓝绿。

边界与前提:

  • Windows 容器要求 Windows Server 2019/2022 Datacenter(建议 2022,吻合 LTSC/镜像兼容)。
  • Linux 节点建议 Ubuntu 22.04 / Rocky 9(内核与 containerd 生态稳)。
  • 注:如果你必须用 CentOS 7,我在文末附了兼容提示(内核老、部分 CNI/CSI 版本需要降级)。
  • 使用 Kubernetes(kubeadm)+ Calico(Win&Lin 都有成熟支持),Win 节点仅做工作节点,控制面全部在 Linux。
  • 底层虚拟化异构:Proxmox VE (KVM) + Hyper-V。

2. 物理与网络拓扑(香港机房版)

2.1 机房与硬件清单

角色 型号/规格 CPU 内存 系统盘/数据盘 网口 备注
Host-A(KVM/Proxmox) Dell R740 2×Xeon Silver 4210R 256GB 2×1.92TB NVMe(ZFS镜像) 2×10GbE + 2×1GbE 承载 K8s 控制面 & Linux Worker
Host-B(Hyper-V) HPE DL360 Gen10 2×Xeon Silver 4214 256GB 2×1.92TB NVMe(RAID1) 2×10GbE + 2×1GbE 承载 Windows Worker
ToR 交换机 10G L3 Switch(支 VLAN/QinQ/MLAG) - - - 24×10GbE SFP+ 与机房上联双归,BFD/VRRP

我这边把 10GbE 做了 MLAG,管理/业务/存储用不同 VLAN。香港机房常见多线(PCCW/HKT/CTG/CN2),跨大陆回国线路会影响外网拉镜像速度,尽量在本地做镜像缓存/Registry proxy。

2.2 网络与 IP 规划

网络 用途 VLAN 网段 MTU
mgmt 主机/虚机/带外管理 10 10.10.10.0/24 1500
storage 分布式存储/备份 20 10.20.20.0/24 9000(如链路支持)
k8s-node K8s 节点互联 30 10.30.30.0/24 1500
k8s-pod (overlay) Pod Overlay(Calico VXLAN) - 172.16.0.0/16(示例) 1450(推荐)
k8s-svc Service VIP/LoadBalancer 40 10.40.40.0/24 1500

关键坑:VXLAN/Overlay 会吃掉 MTU,Calico 默认 MTU 一般要手动改到 1450 左右,否则 Win<->Lin 跨节点 Pod 可能间歇包丢。

3. 虚拟化层搭建(异构)

3.1 在 Host-A 安装 Proxmox VE(KVM)

选择 ZFS Mirror(2×NVMe),开 ashift=12、compression=lz4。

为 K8s 控制面与 Linux Worker 准备 VM 模板(Cloud-Init):

  • vCPU:4/8,内存:832GB(按负载),磁盘:系统 80120GB + 数据盘(可选)。
  • 网卡:virtio,挂到 vmbr30(k8s-node VLAN)+ vmbr10(mgmt VLAN)。

桥接示例(/etc/network/interfaces):

auto vmbr10
iface vmbr10 inet static
    address 10.10.10.11/24
    bridge-ports eno1.10
    bridge-stp off
    bridge-fd 0

auto vmbr30
iface vmbr30 inet manual
    bridge-ports eno1.30
    bridge-stp off
    bridge-fd 0

3.2 在 Host-B 安装 Windows Server 2022(Hyper-V)

角色与功能:启用 Hyper-V、Failover Clustering(可选)。

创建外部 vSwitch 绑定到 10GbE,启用 VLAN 30(k8s-node),并为 Windows Worker VM 打上该 VLAN。

关闭会与 Overlay/CNI 冲突的 NIC 特性(按需):

# 典型:禁用 Large Send Offload/Checksum Offload(视网卡驱动)
Get-NetAdapterAdvancedProperty -Name "Ethernet 10G" | ft
Set-NetAdapterAdvancedProperty -Name "Ethernet 10G" -DisplayName "Large Send Offload v2 (IPv4)" -DisplayValue "Disabled"
Set-NetAdapterAdvancedProperty -Name "Ethernet 10G" -DisplayName "Large Send Offload v2 (IPv6)" -DisplayValue "Disabled"

在 Hyper-V 上创建 Windows Server 2022 Datacenter 虚机若干(作为 K8s Windows Worker),内存 16~32GB,系统盘 100GB,挂 VLAN 30。

4. 操作系统与容器运行时

4.1 Linux(Ubuntu 22.04/Rocky 9)节点准备

# 关闭 swap
swapoff -a && sed -ri 's/.*swap.*/#&/' /etc/fstab

# 内核/转发
cat >> /etc/sysctl.d/99-k8s.conf <<EOF
net.ipv4.ip_forward=1
net.bridge.bridge-nf-call-iptables=1
net.ipv4.neigh.default.gc_thresh1=4096
net.ipv4.neigh.default.gc_thresh2=8192
net.ipv4.neigh.default.gc_thresh3=16384
EOF
sysctl --system

# containerd
apt-get update && apt-get install -y containerd
containerd config default | tee /etc/containerd/config.toml
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
systemctl enable --now containerd

4.2 Windows Server 2022(Windows Worker)准备

# 容器与必要组件
Install-WindowsFeature -Name containers
# 安装 containerd
Invoke-WebRequest https://github.com/containerd/containerd/releases/download/v1.7.18/containerd-1.7.18-windows-amd64.tar.gz -OutFile c:\containerd.tgz
# 解压到 C:\containerd,并注册服务(略)

# kubelet/kubeadm/kubectl 版本与控制面一致
# 设置 Windows pause 镜像(匹配 LTSC2022)
[Environment]::SetEnvironmentVariable("KUBELET_EXTRA_ARGS", '--config=C:\k\kubelet.conf --pod-infra-container-image=mcr.microsoft.com/oss/kubernetes/pause:3.9-windows-amd64', 'Machine')
# 时间同步(Windows 容器/证书对时间敏感)
w32tm /config /manualpeerlist:"time.google.com time.windows.com" /syncfromflags:manual /reliable:yes /update
w32tm /resync

关键坑:Windows 的 pause 镜像必须与宿主版本匹配(如 LTSC2022)。不匹配会导致 Pod 一直 ContainerCreating。

5. 部署 Kubernetes(kubeadm)

5.1 初始化控制面(Linux)

kubeadm init \
  --apiserver-advertise-address=10.30.30.11 \
  --pod-network-cidr=172.16.0.0/16 \
  --service-cidr=10.96.0.0/12 \
  --kubernetes-version=v1.29.6

配置 kubeconfig、打 Calico(Linux+Windows 组合包,把 MTU 调成 1450):

# values 片段(示例)
# calico.yaml 中搜索 veth_mtu 或 FELIX MTU,改为 1450
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.3/manifests/tigera-operator.yaml
# 自定义安装文件里:
# - calicoNetwork.mtu: 1450
kubectl apply -f custom-calico-installation.yaml

注意:Calico for Windows 需要额外清单(calico-windows),并且 Linux 端的 MTU 要与 Windows 配套。

5.2 加入 Linux Worker

kubeadm token create --print-join-command
# 在 Linux Worker 上执行 join 命令

5.3 加入 Windows Worker

在 Windows 节点上:

# 下载 Calico Windows 组件(示意)
# 配置 HNS 网络由 Calico 接管(安装脚本里会做)
# 执行 kubeadm join(Windows 支持作 worker)
kubeadm join 10.30.30.11:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash>

校验节点:

kubectl get nodes -o wide
# 你会看到 os=windows 的 worker 出现,Ready 之后就 OK

6. 存储:Linux 优先 + Windows 通过 SMB CSI

在混合场景里,我的实践是Linux 节点装 Longhorn/Ceph 等去承载数据盘,Windows Pod 用 SMB CSI 访问一个高可用 SMB 共享(由 Linux/NAS 提供)。

6.1 部署 SMB CSI(示例)

StorageClass(smb-sc.yaml):

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: smb-sc
provisioner: smb.csi.k8s.io
parameters:
  source: "//10.20.20.50/k8sdata"   # SMB 服务地址
  csi.storage.k8s.io/node-stage-secret-name: "smb-creds"
  csi.storage.k8s.io/node-stage-secret-namespace: "kube-system"
  dirMode: "0777"
  fileMode: "0777"
mountOptions:
  - dir_mode=0777
  - file_mode=0777
  - vers=3.0
reclaimPolicy: Retain
allowVolumeExpansion: true
volumeBindingMode: Immediate

Secret(凭据):

apiVersion: v1
kind: Secret
metadata:
  name: smb-creds
  namespace: kube-system
type: Opaque
data:
  username: <base64>
  password: <base64>

PVC(示例):

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: win-pvc
spec:
  accessModes: [ "ReadWriteMany" ]
  storageClassName: smb-sc
  resources:
    requests:
      storage: 50Gi

7. Ingress 与服务暴露

Nginx Ingress 跑在 Linux 节点,负责 80/443。

Windows 服务通常以 ClusterIP 暴露,由 Ingress 转发到后端(service 里选择器区分 os)。

需要直达 Windows 的场景,可用 NodePort 或 hostNetwork(慎用)。

8. 应用调度与选择器(Windows/Linux 匹配)

Windows .NET 应用(Deployment 示例):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-legacy-win
spec:
  replicas: 2
  selector:
    matchLabels: app: web-legacy-win
  template:
    metadata:
      labels:
        app: web-legacy-win
    spec:
      nodeSelector:
        kubernetes.io/os: windows
      tolerations:
      - key: "os"
        operator: "Equal"
        value: "windows"
        effect: "NoSchedule"
      containers:
      - name: web
        image: mcr.microsoft.com/dotnet/framework/aspnet:4.8-windowsservercore-ltsc2022
        ports:
        - containerPort: 80
        volumeMounts:
        - name: data
          mountPath: "C:\\data"
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: win-pvc

Linux 服务(Deployment 示例):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-linux
spec:
  replicas: 3
  selector:
    matchLabels:
      app: api-linux
  template:
    metadata:
      labels:
        app: api-linux
    spec:
      nodeSelector:
        kubernetes.io/os: linux
      containers:
      - name: api
        image: ghcr.io/org/api:1.0.0
        ports:
        - containerPort: 8080

通过 kubernetes.io/os 精准投递;必要时可结合 NodeAffinity/污点容忍做更细颗粒调度。

9. 可观测:指标、日志、分布式追踪

Metrics:Prometheus + Grafana;Linux 装 node_exporter;Windows 装 windows_exporter。

日志:Fluent Bit DaemonSet,Windows 侧使用 windows 适配的采集器路径。

Tracing:OpenTelemetry Collector,服务内打点,接到 Tempo/Jaeger。

10. 性能与连通性验证(实测样例)

测试项 工具 路径 结果(示例)
Pod↔Pod RTT ping/psping WinPod→LinPod(跨宿主) 0.35~0.55 ms
Overlay 吞吐 iperf3 LinPod→WinPod(VXLAN) 6.8~8.5 Gbps
PVC(SMB)顺序读 diskspd / fio WinPod 读 SMB 750~900 MB/s(10G 直挂)
镜像拉取 crictl/ctr Harbor(本地缓存) 1.2~1.8 GB/s

没有本地镜像仓库时,从公网拉 Windows 基础镜像很慢,在香港多线场景尤其明显。强烈建议在机房内部署 Harbor/Registry mirror。

11. 线上常见坑与解决

MTU 不一致导致连接时断时续

症状:Win↔Lin 跨节点 HTTP/GRPC 偶发超时。

解决:Calico 安装时把 MTU 设 1450;确认 Hyper-V vSwitch、物理口 MTU=1500 或 9000 一致;必要时 --vxlan-mtu=1450。

Windows pause 镜像/内核版本不匹配

症状:Pod 卡 ContainerCreating。

解决:使用 mcr.microsoft.com/oss/kubernetes/pause:<version>-windows-amd64 与 LTSC 匹配;K8s 版本与 kubelet/ kube-proxy、containerd 对齐。

时间漂移导致证书/鉴权失败

症状:Kubelet 与 API Server 认证失败、TLS 报错。

解决:Linux 配 chrony,Windows 配 w32time,对齐到同一上游。

Hyper-V 网卡高级特性与 Overlay 冲突

现象:吞吐异常、丢包。

解决:按网卡驱动禁用 LSO/Checksum Offload/VMQ(逐项验证)。

SMB 权限/文件锁

现象:Windows Pod 写入失败或锁定。

解决:SMB 服务端设 durable handles 与合适的 oplocks;K8s 端 ReadWriteMany 正确;必要时区分读写共享。

镜像体积过大,发布慢

解决:多阶段构建、减小 Windows 基础镜像层;在 Harbor 开启压缩;CI 环节预热缓存。

CentOS 7 兼容性提醒

K8s 新版本对内核要求更高,CentOS 7 EOL,建议 Rocky 9 / Ubuntu 22.04。如果必须 C7:

使用较低版本 K8s(如 1.23~1.25)、Calico 对应旧版;containerd 选择稳定旧版。

长期看,不建议新项目继续压在 C7。

12. 灰度/蓝绿与自动化

发布:Argo Rollouts / Flagger,先在 Linux 服务试点,再推广到 Windows 服务(注意探针与 gMSA/权限)。

自动伸缩:HPA + 自定义指标(QPS/RT/队列长度),Windows Pod 的探针与资源限额要更保守一点。

备份:Velero + Restic;Windows 卷(SMB)用存储侧快照。

13. 授权与合规(一定别忽略)

Windows Datacenter 授权包含容器权利(数量不受限),Standard 版本限制较多。

激活方式(KMS/AVMA)在香港机房要提前打通,避免大规模部署后逐台补。

14. 成本/容量规划(样例表)

资源 基线 峰值 建议冗余
vCPU 64 96 N+1(Fail 1 主机)
内存 256GB 384GB 25% 预留给系统/IO 缓冲
存储 8TB 可用 12TB 可用 双份副本 + 异地离线备份
带宽 2×10GbE 2×10GbE MLAG + 链路聚合

15. 小结(可复用的“落地清单”)

  • 异构虚拟化:Proxmox(KVM)跑 Linux 控制面 + Linux Worker;Hyper-V 跑 Windows Worker。
  • 网络:VLAN 分区 + Calico VXLAN,MTU=1450;机房内置 Harbor。
  • 运行时:containerd 统一;Windows pause 镜像与 LTSC 匹配。
  • 存储:Linux 节点本地/分布式盘;Windows 用 SMB CSI 做 RWX。
  • 可观测:Prometheus/Grafana + windows_exporter;Fluent Bit 统一日志。
  • 发布:Argo/Flagger;先 Linux 后 Windows,逐步推进。
  • 授权:Windows Datacenter 优先;KMS/AVMA 提前打通。

尾声:天光微亮,机房冷气仍旧无情

那天清晨五点,Grafana 的趋势线终于稳定下来,Win 与 Lin 的 Pod 互访 RTT 压在 0.5ms 左右,镜像从 Harbor 拉取像本地复制一样顺滑。站在机柜前,我把最后一张变更单拍照归档,心里踏实了——不是因为搞出什么“黑魔法”,而是因为它可复制、可维护、可交接。

后来这套做法又在另外两个香港机房复制了一遍,唯一的区别只是 VLAN 号和上联的运营商。复杂系统的关键,是把边界划清、把坑踩实、把流程固化。这样,无论你是刚入行的新手,还是带队的老兵,都能按这份手册把异构虚拟化 + Win/Linux 混合容器管理稳稳地落下去。

附:命令/配置速查(可直接粘贴用)

  • kubeadm init/join 样例(如上)
  • Calico Installation(记得改 MTU=1450)
  • Windows pause 镜像:mcr.microsoft.com/oss/kubernetes/pause:3.9-windows-amd64(匹配 LTSC2022)
  • SMB CSI:storageclass + secret + pvc 三件套(如上)
  • Node 选择器:kubernetes.io/os: windows / linux
  • 日志与指标:windows_exporter / node_exporter / Fluent Bit
目录结构
全文