ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

虚拟机与容器统一管理:KubeVirt和Proxmox VE落地实践

虚拟机与容器统一管理:KubeVirt和Proxmox VE落地实践 干过运维的人应该都有过这种经历机房/云环境里一边是VMware或者KVM撑起来的虚拟机集群另一边是Docker/Kubernetes撑起来的容器集群两套平台各管各的互相不通气。日常部署一个业务可能要同时在两个控制台之间来回切一会儿在vCenter里调整VM资源一会儿又在K8s里改Pod副本数出了故障还要判断到底是哪一侧的网络策略把请求拦了。今天我就把“VM容器两套平台怎么合并成一套架构统一管理”这件我踩了不少坑才折腾明白的事从头到尾讲透包括选型思路、部署参数、排障过程全是可以直接抄作业的实操经验适合正在被虚拟机与容器双子星折磨的中小团队运维。1. 先算一笔账VM和容器两套平台背后运维白白赔进去多少时间1.1 入口不同、监控不同、备份不同三座大山很多团队一开始并没有意识到“两套平台”是问题因为物理机时代不也这样吗但等你真正把业务跑起来会发现“运维负担”不是体现在某个单点上而是体现在每一个细小的日常动作里。先说管理入口。虚拟机这边运维每天打开的无非是vCenter、Proxmox或者OpenStack的控制台容器那边要么是Docker命令行要么是Kubernetes的Dashboard。这两个入口的操作逻辑完全不一样虚拟机的开关机、克隆、快照讲究的是“先有磁盘后有系统”容器的扩容、滚动更新讲究的是“先有镜像后有Pod”。运维人员来回切换时大脑需要不停重载两套上下文这种认知切换带来的疲劳感是实实在在的。再说监控体系。虚拟机的CPU、内存、磁盘IO、网络流量在传统监控工具比如Zabbix里都有成熟的模板但容器的核心监控指标是Pod的调度状态、镜像拉取耗时、容器重启次数、Service的QPS这些东西更适合用Prometheus那套生态。于是运维通常要维护两套监控系统告警规则各写各的出故障时经常出现“虚拟机层面显示CPU跑满容器层面只看到少量Pod在重启”这种对不上的情况。最麻烦的是备份。虚拟机的备份策略是“整机快照 磁盘文件复制”容器的备份策略是“镜像仓库同步 PVC数据卷快照”两套流程完全独立。我见过一个团队因为改了一次备份计划只改了VM侧的容器侧的数据卷三个月没人备份后来数据库挂了才在恢复演练时发现容器侧根本没有可用的备份副本。这种“双层平台 双倍清单”的维护工作才是压垮运维的最后一根稻草。1.2 技能栈撕裂团队沟通成本才是大头硬件和软件的割裂还能靠工具弥补但人的技能栈分裂是最难解决的。一个团队如果既要管VM又要管容器基本上会被迫分成了两拨人一拨懂KVM/VMware另一拨懂Docker/K8s。这两拨人平时各干各的还好一到业务要跨平台联动时就麻烦了。举例来说某个业务的前端服务跑在K8s里数据库跑在虚拟机里。前端要访问数据库时网络策略要两边同时放行K8s团队说“我加了一条NetworkPolicy”VM团队说“我加了一条安全组规则”结果还是不通。两边一排查最后发现K8s里Pod访问的地址走的是NAT转换后的IP而虚拟机侧的安全组只放行了原始IP两边因为对网络链路理解的差异硬是排查了两个小时。招人就更难了。市场上懂VMware的人很多懂K8s的人也很多但能同时把两套东西玩明白、还能在故障时快速定位问题边界的人少之又少。要么花高价招全栈运维要么把团队拆成两组无论哪种对企业来说都是额外的成本。我自己带团队这几年最大的感受是与其逼着每个组员同时学两套技术栈不如从架构层面把两套东西收敛成一套让团队只需要维护一套控制面学习成本瞬间就降下来了。2. 统一管理的核心逻辑不是把VM塞进容器而是让控制面管住两种负载2.1 到底统一什么才算“一套架构”很多人一听“统一架构”第一反应是“把虚拟机全部容器化”。这个想法很危险。不是说容器化不好而是现实中还有大量跑着Windows Server的老业务、需要直通GPU的推理服务、依赖固定内网IP的遗留系统——这些负载强行容器化改造成本极高还会引入更多不可控因素。真正的“统一架构”不是让所有负载都长成一个样而是让所有负载的管理方式、监控口径、备份策略、网络配置入口都收敛到同一个控制面。打个比方传统VM是“一栋楼里的一套房”容器是“一个临时房间”。你要的不是把所有房子都拆成临时房间而是让物业公司用同一套管理系统既能登记长期住房也能管理临时入住——这就是控制面统一的意思。落到具体实现上统一管理至少要覆盖四件事统一调度VM和容器都能被同一种编排机制创建、启停、迁移而不是各用各的命令行。统一网络两种负载共享同一个虚拟网络平面IP分配、DNS解析、防火墙策略都在一个入口维护。统一储存虚拟机磁盘和容器数据卷都能挂到同一个存储后端上备份恢复用同一套策略。统一监控不管负载是VM还是Pod都能用同一套监控系统采集指标、出告警。2.2 两条主流落地路径KubeVirt 与 Proxmox VE我实际调研和落地过的方案里最靠谱的是下面两条路。它们代表两种完全不同的思路选择哪条取决于你的团队底子。第一条路是以Kubernetes为控制面的KubeVirt方案。KubeVirt是K8s社区做的一个项目它把传统虚拟机抽象成K8s里的一种自定义资源叫VirtualMachine。这样一来K8s既可以是容器调度平台也可以当虚拟机调度平台。你在K8s里用一条yaml就能定义一台VM的CPU、内存、磁盘用kubectl就能操作虚拟机的启停和迁移。这条路适合本来就在用K8s、团队着Linux命令行的团队学习曲线最平滑因为容器和VM都在同一个kubectl体系里管理。第二条路是以Proxmox VE为核心的一体化平台。PVE是一个基于Debian的虚拟化平台它原生同时支持KVM虚拟机和LXC容器而且这两种负载共享同一个Web管理界面、同一个存储池、同一个网络模型。这个方案更像“一套经过专门设计的整体底座”它的LXC容器虽然和Docker容器不是一种东西但很多传统应用完全可以用LXC来跑配合Web界面管理对不习惯K8s的团队更友好。两条路的对比如下对比维度KubeVirtK8s底座Proxmox VE容器运行时Docker Pod标准K8s容器LXC系统容器也可嵌套DockerVM管理方式kubectl / yaml完全声明式Web控制台 / API点选命令混合学习门槛需要熟悉K8s概念熟悉虚拟化、有Linux基础即可适合场景云原生改造较多、团队已有K8s传统IDC搬迁、中小规模、面板化运维备份体系用Velero备份VM和PV用vzdump统一备份VM和CT我个人的建议是如果你团队已经在用K8s就选KubeVirt因为“统一”的目标本质上就是把VM卷进K8s这套已经跑通的控制面如果你团队还在用传统虚拟化选Proxmox VE会让迁移成本低很多。两条路我都实际部署过下面逐步拆解具体怎么落地。3. 实操落地一条路径去管VM和容器怎么做3.1 路径一以Kubernetes为控制面KubeVirt接管VMKubeVirt的思路我再用通俗的话讲一遍K8s是个大管家以前它只管着集装箱容器现在你想让它顺便管一下整栋房子虚拟机那就在K8s里装一个“管家插件”这个插件知道怎么处理房子类型的工作单——这就是KubeVirt的Operator机制。我的落地步骤是这样走的按顺序执行基本不会有坑第一步准备一套K8s集群。版本建议1.27以上我这次用的是kubeadm部署的三节点集群Pod网段设的是10.244.0.0/16Service网段是10.96.0.0/16网络插件选的是Calico。这里有个关键参数KubeVirt对集群的硬件虚拟化支持有要求如果是物理机就没问题如果K8s节点本身是VM比如在公有云里那么云厂商的裸金属型实例必须开启嵌套虚拟化否则KubeVirt创建出来的VM只有小概率能启动成功。验证方法egrep -c (vmx|svm) /proc/cpuinfo计数结果大于0说明有虚拟化扩展。如果结果为0继续往下走没有意义。第二步部署KubeVirt Operator。把官方仓库里的两个yaml依次apply就行kubectl create -f https://github.com/kubevirt/kubevirt/releases/download/v1.2.0/kubevirt-operator.yaml kubectl create -f https://github.com/kubevirt/kubevirt/releases/download/v1.2.0/kubevirt-cr.yaml等待所有KubeVirt组件变成Running状态kubectl -n kubevirt get pods第三步安装virtctl命令行工具。KubeVirt没给kubectl增加额外子命令而是单独提供了一个virtctl用来做虚拟机的启动、停止、VNC连接、迁移等操作。下载并放到/usr/local/bin下curl -L -o virtctl https://github.com/kubevirt/kubevirt/releases/download/v1.2.0/virtctl-v1.2.0-linux-amd64 chmod x virtctl mv virtctl /usr/local/bin/第四步用yaml定义第一台虚拟机。这里很重要的一点是KubeVirt的VM定义把“VM的规格”和“VM的实例”分开了类似Deployment和Pod的关系。我常用的最小定义长这样apiVersion: kubevirt.io/v1 kind: VirtualMachine metadata: name: win-server-01 spec: running: true template: spec: domain: cpu: cores: 2 memory: request: 4Gi devices: disks: - name: systemdisk disk: bus: virtio interfaces: - name: network-a bridge: {} volumes: - name: systemdisk containerDisk: image: kubevirt/cirros-container-disk-demo:v1.2.0 networks: - name: network-a pod: {}创建后用virtctl console win-server-01就能像连VNC一样登入虚拟机。一旦跑通这套链路后续再有新的VM需求就通过同样的yaml模板去套再也不用去单独维护一套虚拟化控制台了。实际部署后的经验KubeVirt的默认网络是Pod网络也就是VM先从K8s集群内部拿到一个Pod IP。如果VM要对集群外提供服务就得用Bridge接口加Multus多网络插件把VM桥接到节点物理网络或者一个独立的VLAN网段上。我建议在一开始规划网络插件时就把Multus装好不然后面再补等于要把所有集群节点的CNI配置重新改一遍。3.2 路径二以Proxmox VE为底座KVM和LXC统一调度如果你走PVE这条路操作会直观很多因为PVE本身就是一个“合二为一”的产品。我落地是最新版PVE 8基于Debian 12内核自带KVM模块也自带了LXC的完整支持。安装过程我只说几个容易忽略的细节。PVE的安装包在官网下载ISO用U盘或IPMI挂载镜像启动安装时它会自动创建LVM存储和vmbr0这个Linux Bridge。装完后先别急建议把PVE的软件源换掉——默认是企业订阅源不付费的话apt update会报错# 打开 /etc/apt/sources.list.d/pve-enterprise.list # 将下行注释掉 # deb https://enterprise.proxmox.com/debian/pve bookworm pve-enterprise # 添加社区源 deb http://download.proxmox.com/debian/pve bookworm pve-no-subscription否则后续连模板都下载不了。创建LXC容器和创建VM的方式很像但有几个参数需要关注。创建LXC容器时系统模板要先下载PVE Web界面里“本地存储local→内容→模板”里可以选官方模板源也可以用pveam update命令行刷新模板列表。我习惯在模板里勾选“启动时自动启动”配合PVE的HA功能宿主机重启后容器能自动恢复。在创建容器的界面上需要注意这几个参数主机名容器名称同时会作为容器内主机名。资源“核心”数建议一开始就按业务峰值算好LXC调CPU比VM轻量但不能像VM那样随意热插拔。网络参数默认会接在vmbr0上分配一个局域网IP就可以。如果想要容器和外部隔离可以加一个vmbr1作为内部管理网。Root密码LXC容器默认没有密码这步不设置创建成功后无法登录只能重置。在Web界面创建一台VM的步骤大家应该不陌生选好ISO镜像、分配CPU内存磁盘、网络选vmbr0即可。VM的CPU类型建议选host这样虚拟机性能最接近宿主机性能损耗最小代价是VM不能随便迁移到CPU型号不同的宿主机这个取舍要看你的集群是否混用不同代际的CPU型号。PVE真正让运维省力的地方在于备份策略。Web里“数据中心→备份”里可以创建一个统一的备份任务比如每天凌晨2点对所有VM和所有LXC容器做增量备份备份存储可以选同一个NFS共享盘恢复时也走同一个“备份存储”入口。我用了这个之后再也不用分别给虚拟机和容器维护两套备份脚本了这个变化直接节省了每周半天的人工时间。3.3 一套监控、一套备份从细节里把时间省回来很多时候“统一管理”的实惠不是体现在创建资源的操作上而是体现在日常运维的重复动作里。我落地统一架构后重点做了下面两件看着不起眼、但实际耗时占比最高的事统一的监控面板。PVE这边我直接让Prometheus通过PVE的API采集宿主机的CPU、内存、磁盘、网络指标同时用node_exporter采集LXC容器和VM内部的指标K8s那边本来就是Prometheus的天下这样两种负载的指标都汇到同一个Grafana面板里一个页面看全部。告警规则我也收拢了比如“CPU持续90%超过10分钟”这条规则同时作用于VM和容器不用在Zabbix和Prometheus里各写一遍。统一的备份调度。PVE用自带的vzdump统一跑VM和LXC的备份KubeVirt这边我用Velero做K8s的集群资源备份再配合存储层的快照功能批量备份PVC。虽然两个方案底层工具不同但我在排障手册里把“今天备份了吗看哪些地方”写成了同一个入口——每天早上先看统一备份页面确认所有备份任务绿色通过即可。一句话总结这两个细节统一架构带来的不只是“技术上的合并”更是“运维动作的合并”。凡是每天、每周要重复做的维护操作能在一个入口完成才是真正减负。4. 真实上线前必须排掉的雷网络、存储、性能三件事4.1 网络互通问题VM和容器之间的“最后一公里”不管是KubeVirt还是PVE最常让我头疼的坑都出在网络上。容器网络天生是“软件定义”的VM网络可能走虚拟网桥也可能走物理网卡当两种负载要在同一个网段里互联时最容易出现的问题是广播风暴和IP冲突。PVE里的典型场景给LXC容器分配了和虚拟机同一个网段的IP把两者都挂在vmbr0上理论上应该全网互通。但实际中发现容器ping不通VM检查两边防火墙都是放行的。排查下来发现LXC容器的网卡类型默认是veth在某些内核版本下vmbr0上的MAC地址表学习出现异常导致VM回包时找不到容器的MAC地址。最简单的解法是把LXC容器网卡的hwaddr改成宿主机网卡的MAC或给容器单独建一个vmbr1网桥通过网关做路由转发。KubeVirt里的经典坑在VM里看到的路由表里默认网关指向了Pod网段的网关地址而这个地址走的是tun0隧道或者Calico的Overlay网络导致VM发起外部通信时性能骤降、延迟不稳定。我排查后的结论是KubeVirt的Pod网络对VM来说应该只做管理面真正跑业务流量必须走Multus挂载的辅助网卡把VM直接桥到节点物理网络。4.2 存储选型和迁移别让磁盘拖慢整个架构统一架构的下一步其实是存储统一。PVE默认给虚拟机和LXC容器都提供LVM存储但LVM是本地盘的没法做热迁移。我接手的一个项目一开始VM和容器都跑在本地盘上HA功能完全没法用因为迁移本质上是把磁盘文件复制到另一台机器本地盘复制慢到离谱。我后来把存储换成了共享存储的方案用两个节点跑Ceph RBDPVE里把Ceph做成一个独立的存储池VM和LXC的磁盘都放到这里。这样才真正实现了“漂移”能力——宿主机宕机后虚拟机/容器可以自动在另一台节点恢复。这个改造原理不复杂但参数调起来确实费了一番功夫Ceph的副本数我设为3默认也是3对于两节点一个仲裁节点的小集群刚好够用。PG数量按“每OSD 100个PG”来配比如3个OSD就设300个PG左右。RBD的image feature建议只用layering和exclusive-lock老内核上如果开了object-map会有性能问题。KubeVirt侧的存储同理。PVC直接用StorageClass来建底层接的也是Ceph RBD。这里有个实用的经验给VM用的PVC的存储类reclaimPolicy要设成Retain因为VM是有状态的如果PVC被删了VM的磁盘数据就全没了容器用的PVC则可以用默认的Delete。4.3 性能验证与硬件虚拟化检测别以为开箱就能用别等到生产跑起来才发现性能不对。KubeVirt和KVM虚拟机本质上依赖CPU硬件虚拟化我遇到过一个朋友的项目他在公有云的VM里搭了K8s集群再装KubeVirt结果创建的VM启动不到两分钟就自动重启检查日志看到vmx指令执行失败。原因是云厂商的VM默认关闭了嵌套虚拟化。解决办法是选支持“嵌套虚化”的云主机规格或者在BIOS里开启对应选项。即便是在物理机上不同CPU型号对虚拟化性能的影响也很大。同一台物理机上跑KVM虚拟机CPU模式选host和选qemu64的性能差距可以在20%以上。部署前我习惯用UnixBench做一轮快速压测对CPU密集型的业务务必确认VM的CPU模式是host或者至少是qemu64以上避免出现“都是KVM性能却差一大截”的问题。5. 我的个人经验放下“一步到位”的执念最后聊几句我在几次落地之后沉淀下的体会。第一个体会是不要一开始就追求“全公司所有业务全部迁到统一架构”。这种大目标听着热血但执行起来必然翻车。正确的姿势是先找一个非核心业务比如某个内部监控系统或者日志收集服务把它以一个VM的形态迁到新平台同时把一个简单的Web服务以容器的形态放到同一套平台里先把“一套架构下同时跑VM和容器”这条链路跑通把备份、监控、网络调好取得团队的信任后再逐步扩大范围。这个渐进过程看着慢但踩坑的边际成本是递减的越到后面越顺利。第二个体会是统一的是架构不是技术术语。上了统一平台之后团队还是要同时接触虚拟化和容器知识但重要的是大家不需要再记两套控制台里的专属操作了。kubectl能管VMPVE界面能管LXC这给了团队一个“common ground”大家讨论问题时至少能站在同一个工具箱旁边说话而不是各自抱着两种技术栈互不兼容。第三个也是我最想说的批量化运维习惯要提前养成。统一架构最大的红利其实是“用一套模板管所有机器”。我强烈建议PVE里的LXC容器、KubeVirt里的VirtualMachine以及普通K8s里的Deployment全部通过Git仓库管理配置文件把IP分配、CPU内存配额、磁盘大小、备份策略全部作为配置参数写进去。这样团队成员改配置都走统一的MR流程运维记录自动落在Git历史里比以往靠人脑记“这台VM配了多少内存、那个容器分了多少IP”要靠谱太多。这也是我从这次改造中得到的最值得分享的实战经验希望你们少走弯路。
返回列表