跳转到内容

容器还是虚拟机:先做这个判断 ​

PVE 上开一个客户机,第一个决定就是 VM 还是 CT。这个选择后面很难改(不是不能,是要重新装一遍),值得先想清楚。

一个事实推导出一切 ​

LXC 容器和宿主机共享同一个 Linux 内核;虚拟机跑自己的内核。

所有差别都从这一条来:

text
虚拟机                          LXC 容器
┌──────────────┐               ┌──────────────┐
│  应用         │               │  应用         │
│  发行版用户态  │               │  发行版用户态  │
│  ★ 自己的内核 │               └──────┬───────┘
│  虚拟硬件      │                      │ 直接系统调用
└──────┬───────┘                      │
       │ QEMU/KVM                     │
┌──────┴──────────────────────────────┴───────┐
│              宿主机内核 (PVE)                 │
└─────────────────────────────────────────────┘
维度虚拟机LXC 容器
内存开销客户机内核 + 系统,起步 512 MB–1 GB只有用户态进程,可以只有几十 MB
启动时间十几秒到一分钟一两秒
能跑什么任何 x86 系统:Windows、BSD、任何 Linux只能是 Linux,且内核由宿主机决定
隔离性强,边界是 CPU 虚拟化弱一些,边界是内核的命名空间和 cgroup
内存分配分了就占(除非用气球)按需占用,只用多少算多少
直通设备支持 PCI 直通不支持 PCI 直通,只能映射设备节点
加载内核模块可以不可以(用的是宿主机内核)
迁移支持在线迁移只能离线迁移(需重启)

什么时候必须用虚拟机 ​

这几种情况没有选择:

  • 要跑 Windows、BSD 或任何非 Linux 系统。
  • 要做 PCI 设备直通(显卡、HBA 卡、网卡整卡)。NAS 虚拟机和转码虚拟机通常属于这类。
  • 客户机需要自己的内核版本或内核模块,比如某些 VPN、某些存储方案。
  • 需要强隔离:跑不信任的代码、给别人用的环境、有合规要求。
  • 需要在线迁移:集群里不能中断的服务。
  • 客户机是整机镜像形态的发行版,比如 Home Assistant OS、OpenWrt 的某些构建。

什么时候容器更合适 ​

  • 长期运行的轻量服务:反向代理、DNS、监控采集、备份代理、内网小工具。
  • 数量多:十个容器的内存开销可能还不如一台虚拟机。
  • 要频繁重建:容器创建只要几秒。
  • 需要和宿主机共享大目录:bind mount 比虚拟机里走网络共享高效得多。

容器的隔离性到底有多弱 ​

这是最需要说清楚的一点。

非特权容器(PVE 的默认)里的 root,映射到宿主机上是一个普通的高 UID 用户(通常从 100000 开始)。即使容器里的进程拿到 root,它在宿主机上也没有特权。这个隔离是可靠的。

特权容器里的 root,就是宿主机的 root(UID 0)。PVE 用一些机制(AppArmor、seccomp、能力集裁剪)限制它,但——

特权容器不应被当作安全边界

Linux 内核的容器逃逸漏洞时有发现。非特权容器还有 UID 映射这道墙兜着,特权容器一旦被突破,攻击者直接拿到宿主机 root。

原则:任何会接受外部输入、或者跑你没完整审查过的代码的服务,不要放在特权容器里。 这类服务要么用非特权容器,要么用虚拟机。

详细的取舍见特权与非特权容器。

常见的判断题 ​

Docker 应该跑在哪 ​

推荐:一台虚拟机,里面装 Docker。

在 LXC 里跑 Docker 技术上可行,但要处理嵌套容器的一堆权限问题(存储驱动、cgroup、AppArmor),在非特权容器里尤其麻烦。用虚拟机的好处是:Docker 跑在一个正常的 Linux 上,所有网上的教程都能直接用,出问题也好查。

代价是多一层,大约 1–2 GB 内存。多数情况下这个代价值得。官方文档的立场、技术上怎么开启、以及完整的代价清单见在 LXC 里跑 Docker:能不能、代价是什么。

数据库 ​

看规模。小的内网服务数据库,容器完全够用。需要调内核参数、需要大页内存、或者对 IO 有严格要求的,用虚拟机。

NAS / 文件共享 ​

用虚拟机。 因为通常要直通 HBA 卡或整盘,而容器做不到 PCI 直通。

如果只是想共享宿主机上的一个目录,容器 + bind mount + Samba 也可以,但权限映射(尤其非特权容器)需要额外配置。

软路由 ​

用虚拟机。 需要直通网卡、需要自己的内核和网络栈。

选错了怎么办 ​

没有「一键转换」。实际做法是重新创建:

  • 容器改虚拟机:建虚拟机装系统,把数据(bind mount 的目录、数据库导出)搬过去。
  • 虚拟机改容器:同理。

所以数据和配置尽量放在可以单独搬走的地方(独立的挂载点、可导出的格式),这会让将来的迁移容易得多。

检查结果 ​

拿你的客户机清单,逐个标上 VM 或 CT,并写一句理由。理由不能是「大家都这么做」,要能对应上面某一条。

标完之后算一遍内存:虚拟机按分配值算,容器按预估实际用量算。总和加上给 PVE 的 2 GB(用 ZFS 再加 ARC 的量),看看你的内存够不够。

延伸阅读 ​

Proxmox VE 非官方中文使用指南,与 Proxmox Server Solutions GmbH 无隶属关系。