外观
创建第一个容器
容器创建比虚拟机简单——没有 BIOS、没有磁盘总线、不用装系统。从下载模板到能用,通常不超过两分钟。
第一步:下载模板
容器不用 ISO,用的是模板:一个打包好的最小化发行版根文件系统。
节点 → local → CT Templates → Templates,会弹出可用模板列表。
列表是空的?先更新索引
在宿主机 shell 执行:
sh
pveam update然后看有哪些可用:
sh
pveam available --section system列表分几类:
| Section | 内容 |
|---|---|
system | 各发行版的最小化基础模板(Debian、Ubuntu、Alpine、Rocky 等) |
turnkeylinux | TurnKey Linux 预装应用的模板 |
新手建议从 Debian 或 Ubuntu 的基础模板开始,干净可控。
第三方模板要看来源
TurnKey 之外的模板、或者网上找的 .tar.zst 文件,本质上是一整个根文件系统。来源不明的模板里可以塞任何东西。只用官方源里的模板,或者自己构建。
也可以命令行下载:
sh
pveam download local debian-12-standard_12.x-x_amd64.tar.zst第二步:创建容器
点右上角 Create CT。
General
| 字段 | 说明 |
|---|---|
| CT ID | 容器编号,和虚拟机共用一套编号空间 |
| Hostname | 容器主机名,会写进容器里 |
| Unprivileged container | 保持勾选(默认),见特权与非特权 |
| Nesting | 需要在容器里跑嵌套容器(如 Docker)时勾选 |
| Password / SSH public key | 容器的 root 凭据 |
不要为了省事取消 Unprivileged
「教程说取消勾选比较方便」——方便的代价是容器里的 root 等于宿主机 root。默认的非特权模式适用于绝大多数场景,遇到权限问题应该去解决权限映射,而不是降级成特权容器。
Template
选 local 存储和刚下载的模板。
Disks
| 字段 | 说明 |
|---|---|
| Storage | local-lvm 或你的 ZFS 池 |
| Disk size | 8 GB 对多数轻量服务够用,可以扩大 |
容器磁盘的扩容比虚拟机简单
容器根文件系统扩容在 Web UI 的 Resources → Root Disk → Volume Action → Resize 里,通常在线就能完成,不用进容器调整分区。缩小依然不支持。
CPU
Cores 填 1–2 起步。
容器的 CPU 限制是软的
容器的 Cores 是 cgroup 限制,不是独占。容器空闲时不占用任何 CPU,需要时可以用到分配的量。和虚拟机的 vCPU 语义不完全一样。
Memory
| 字段 | 说明 |
|---|---|
| Memory | 上限。容器实际只占用它用到的部分 |
| Swap | 一般设成和内存相同或 0 |
这是容器最划算的地方:给一个反向代理容器分 512 MB,它跑起来可能只实际占用 40 MB,剩下的宿主机可以给别人用。虚拟机做不到这一点(除非用气球,而且效果有限)。
Network
| 字段 | 说明 |
|---|---|
| Name | 容器内的网卡名,默认 eth0 |
| Bridge | vmbr0 |
| IPv4 | 选 DHCP,或填静态地址(要带 CIDR,如 192.168.1.50/24) |
| Gateway | 填静态 IP 时必填 |
DNS
留空表示继承宿主机的 DNS 配置,多数情况这样就好。
Confirm
确认后创建。几秒钟就完成了。
第三步:启动并进入
点容器 → Start,然后有三种进入方式:
Web UI 控制台:点 Console,直接是 shell,不需要登录(PVE 已经在容器命名空间里)。
宿主机命令行(最方便):
sh
pct enter <ctid>直接进入容器的 shell,不需要密码,不走 SSH。
SSH:容器里的 SSH 服务默认可能没装。基础模板通常很精简:
sh
# 在容器内部执行
apt update
apt install -y openssh-server第四步:基础配置
进入容器后,它就是一个正常的 Debian:
sh
# 在容器内部执行
apt update && apt full-upgrade -y
# 装点基本工具
apt install -y curl vim ca-certificates容器不需要 qemu-guest-agent
那是虚拟机的东西。PVE 通过 pct 直接和容器命名空间交互,本来就能看到容器的 IP 和状态。
常用 pct 命令
sh
# 列出所有容器
pct list
# 状态
pct status <ctid>
# 启停
pct start <ctid>
pct shutdown <ctid>
pct stop <ctid> # 强制,相当于拔电
# 进入 shell
pct enter <ctid>
# 在容器里执行一条命令(不进去)
pct exec <ctid> -- apt update
# 看配置
pct config <ctid>
# 从宿主机往容器里拷文件
pct push <ctid> /本地路径 /容器内路径
pct pull <ctid> /容器内路径 /本地路径配置文件在 /etc/pve/lxc/<ctid>.conf:
sh
cat /etc/pve/lxc/101.conf典型内容:
text
arch: amd64
cores: 2
features: nesting=1
hostname: proxy
memory: 512
net0: name=eth0,bridge=vmbr0,hwaddr=BC:24:11:xx:xx:xx,ip=dhcp,type=veth
ostype: debian
rootfs: local-lvm:vm-101-disk-0,size=8G
swap: 512
unprivileged: 1unprivileged: 1 这一行确认了它是非特权容器。
给容器挂载宿主机目录
容器最常见的需求:访问宿主机上的一个大目录(比如媒体库)。
sh
pct set <ctid> -mp0 /宿主机路径,mp=/容器内路径例如:
sh
pct set 101 -mp0 /mnt/data/media,mp=/media非特权容器的挂载点有权限问题
非特权容器里的 root(UID 0)在宿主机上是 UID 100000。所以容器看到的宿主机目录,属主会显示成 nobody,写入会被拒绝。
解决方向有几种(调整宿主机目录属主、配置 UID 映射、用 ACL),各有取舍,属于特权与非特权容器和进阶内容。不要为了绕开这个问题就改用特权容器。
检查结果
pct list里容器状态是running。- Web UI 的 Summary 能看到容器的 IP 和内存占用。
pct enter <ctid>能进去,里面ping得通外网。pct config <ctid>里有unprivileged: 1。- 对比一下:容器的实际内存占用 vs 你给虚拟机分配的量。
常见问题
容器起不来,报 cgroup 相关错误。 通常是模板和宿主机内核的 cgroup 版本不匹配(老模板 + 新内核)。换用较新的模板。
容器里 systemctl 报错。 精简模板可能没跑完整的 systemd。基础的 debian-*-standard 模板是有的。
容器 DNS 解析不了。 检查 容器 → DNS 设置,或者容器里的 /etc/resolv.conf。非特权容器里这个文件由 PVE 管理,改了会被覆盖,要在 Web UI 里改。
想给容器用显卡(比如硬件转码)。 容器不能做 PCI 直通,但可以把设备节点(/dev/dri/*)映射进去。这在非特权容器里需要处理权限,属于进阶内容。