之前帮公司运维整理测试环境,用一台闲置的2U服务器搭建Proxmox VE,本来只想放几个装着后端微服务的LXC容器,后来因为UI测试需要,临时加了个Windows KVM虚拟机,结果没过几天就出了问题:容器跑压测脚本的时候,虚拟机里的浏览器打开页面要等10秒以上,卡得根本没法用,运维排查半天发现是两者在抢CPU、内存和磁盘IO,这就是容器和虚拟机在Proxmox主机混放时最常见的资源竞争问题。

一、Proxmox VE中容器与虚拟机混放的资源竞争痛点

很多人在使用Proxmox的时候,都会有“一台主机兼顾多个 workload”的需求:比如小型公司想用旧服务器同时跑后端微服务的容器、前端测试的虚拟机,或者测试环境需要同时承载LXC的轻量任务和KVM的重负载应用。但这种混放很容易导致资源争抢:CPU被单个任务占满,其他任务调度延迟;内存被超分太多,触发交换导致系统卡顿;磁盘IO被某一个大文件写入占满,其他读写操作直接排队。我之前就踩过这个坑,当时没做任何隔离,压测容器跑了10分钟,虚拟机的UI操作直接断连了,最后只能重启虚拟机才恢复。

二、隔离方案的核心思路

2.1 资源隔离的本质

说白了就是给每个容器、虚拟机“画好固定的小隔间”,谁用谁的隔间,不能随便越界拿别人的资源。Proxmox本身自带了非常实用的工具,不需要额外装任何软件,就能从CPU、内存、磁盘IO三个核心维度做硬隔离,这也是为什么这个方案适合不同基础的人上手。

2.2 关键隔离维度

最核心的是三个:CPU不能乱抢、内存不能随便超用、磁盘IO不能独吞。只要把这三个维度的规则定死,基本就能解决90%以上的资源竞争问题,接下来我会用实际的Shell命令(Proxmox的自带管理工具)演示具体操作,示例都是基于一台普通的4核8G内存的测试主机,ID为100的LXC容器(跑Go微服务)和ID为200的KVM虚拟机(跑Windows UI测试)。

三、实操隔离方案(技术栈:Shell)

3.1 CPU资源隔离

CPU是最容易被抢的资源,这里的核心是给任务绑定固定的CPU核心,设置优先级,避免跨核心调度。首先先看主机的CPU情况:

# 查看主机CPU总核心数和NUMA节点分布(NUMA是CPU的架构,跨节点访问内存会变慢,尽量绑在同一个节点)
nproc && numactl -H

我测试主机的输出是4个CPU核心,1个NUMA节点。接下来给容器和虚拟机分配核心,并且绑定到前两个核心(容器)和后两个核心(虚拟机),避免互相干扰:

# 给LXC容器100设置2个CPU核心,绑定到0、1核心,CPU优先级是1024(默认值,数值越大优先级越高,资源不够时先给高优先级的)
pct set 100 --cores 2 --cpuset 0,1 --cpuunits 1024
# 给KVM虚拟机200设置2个CPU核心(因为主机只有4核,容器已经占了2个,虚拟机再占2个,刚好),绑定到2、3核心,优先级2048(比容器高,因为是核心测试任务)
qm set 200 --smp 2 --cpuset 2-3 --cpuunits 2048

这里要注意,cpuset的核心编号不能超过主机总核心数,不然会报错;如果是NUMA节点的主机,要把容器和虚拟机绑在同一个节点的核心上,不然会导致访问内存变慢,这点我之前踩过坑,后来改了之后虚拟机的操作延迟直接降了一半。

3.2 内存资源隔离

内存隔离的核心是不能超分,而且要固定住,避免系统动态回收,或者用硬盘当虚拟内存。比如我给容器分配2G固定内存,虚拟机分配4G固定内存,剩下的2G留给Proxmox宿主机本身:

# 给LXC容器100设置2G固定内存,禁用交换(swap设0),锁定内存(locked设1,不让系统回收这个容器的内存)
pct set 100 --memory 2048 --swap 0 --locked 1
# 给KVM虚拟机200设置4G固定内存,禁用内存 balloon(动态内存调整,关闭更稳定),锁定内存
qm set 200 --memory 4096 --balloon 0 --locked 1

这里的locked参数非常重要,我之前没设,结果容器跑压测的时候,系统把虚拟机的内存回收了一部分,导致虚拟机里的浏览器直接崩溃,后来加上locked参数就再也没出现过这个问题了。

3.3 磁盘IO资源隔离

磁盘IO是最容易被忽略的争抢源,比如容器跑数据导入脚本的时候,把磁盘的IO占满,虚拟机的操作就会卡住。这里要给每个任务设置IO的上限,避免独吞:

# 给LXC容器100的根磁盘设置:读IOPS上限1000,写IOPS上限500,并行IO线程10(不要太多,避免占宿主机的CPU)
pct set 100 --mp0 local-lvm:10,io_threads=10,read_iops_sec=1000,write_iops_sec=500
# 给KVM虚拟机200的磁盘设置:读IOPS上限2000,写IOPS上限1000,并行IO线程20(因为是虚拟机,IO需求大一点)
qm set 200 --scsi0 local-lvm:20,io_threads=20,read_iops_sec=2000,write_iops_sec=1000

IOPS是每秒的读写次数,SSD的IOPS可以设高一点,机械盘的话不要超过500,不然会有冗余;如果是用ZFS存储,还要注意设置zfs的arc大小,避免缓存过多影响宿主机内存,但这个属于进阶配置,暂时不用管。

四、应用场景

这个隔离方案最适合的场景有几个:第一,小型测试环境,预算有限,不想多买服务器,用一台旧服务器同时跑容器和虚拟机,比如公司的前端测试用虚拟机,后端微服务用容器;第二,临时过渡环境,比如展会前需要快速搭建一套测试环境,用单台Proxmox主机承载多种任务,快速上线;第三,个人开发者的环境,自己的电脑装Proxmox,同时跑开发容器和虚拟机系统,兼顾效率。

五、技术优缺点

5.1 优点

第一个优点是简单,所有配置都是Proxmox自带的命令,不用学新东西,运维新手也能快速上手;第二个优点是隔离性强,从CPU、内存、IO三层做了硬隔离,不是软限制,不会出现“你说你用2G,结果偷偷用了4G”的情况;第三个优点是可控,每个任务的资源可以单独调整,比如容器是轻量任务,就把核心和内存调小,虚拟机是重负载,就调大;第四个优点是兼容性好,不管是LXC还是KVM都支持,不用切换技术栈,熟悉Proxmox的人一看就懂。

5.2 缺点

第一个缺点是资源利用率会下降,因为是固定分配,比如容器分配了2G内存,但实际只用了1G,剩下的1G不能分给虚拟机,适合 workload 固定的场景,如果经常变动资源需求,会浪费;第二个缺点是配置有门槛,虽然命令简单,但要注意核心、内存的分配不能超过主机的硬件上限,不然会报错;第三个缺点是不适合大规模集群,如果是上千台主机的集群,需要更复杂的调度工具,这个方案太基础了,只能用在单台主机的小环境。

六、注意事项

第一个注意事项是先看主机的硬件资源,配置前一定要先算清楚:CPU核心数要够,内存要留至少2G给Proxmox宿主机,磁盘要够;第二个是不要随便绑定核心,如果是NUMA架构的主机,要把同类型的任务绑在同一个NUMA节点的核心上,不然会导致性能下降;第三个是IO配置要对应磁盘类型,SSD的IOPS可以设高,机械盘不要设太高;第四个是定期检查资源使用情况,用pct status 100qm status 200看容器和虚拟机的资源使用,不够就调,浪费就减;第五个是不要开太多的超分,内存超分最多不要超过1.2倍,不然会经常触发交换,导致系统卡顿。

七、总结

在Proxmox主机上混放容器和虚拟机,资源竞争是不可避免的,但用自带的工具做固定隔离是最实用的方案,只要从CPU、内存、IO三个维度做好配置,就能很好地解决争抢问题,提高硬件利用率和服务稳定性。这个方案不需要额外成本,适合小团队、个人开发者、旧服务器复用的场景,只要注意配置的硬件上限和NUMA节点的绑定,就能避免大部分问题。