11.Proxmox 容器工具集Proxmox Container Toolkit
容器是相对完整虚拟机(VM)的轻量化方案 —— 它们直接使用主机内核 , 而不是模拟一整套操作系统 , 因此可直接访问主机资源。运行时开销很低 , 通常可忽略不计。但需注意:
- Proxmox 容器中只能运行 Linux 发行版 —— 例如 FreeBSD、 Microsoft Windows 都无法在容器内运行。
- 出于安全 , 容器运行在独立命名空间中 , 部分系统调用在容器内被禁止。
Proxmox VE 底层用 Linux Containers(LXC)。「Proxmox Container Toolkit」(pct)通过抽象复杂任务简化 LXC 的使用与管理。容器与 PVE 深度集成 —— 感知集群 , 共用虚机的网络 / 存储资源 , 可配合 PVE 防火墙与 HA 框架。
首要目标一直是 :在不引入额外开销的前提下提供 VM 的好处 —— 因此容器主要定位为 系统容器。随着 OCI 镜像支持引入 , PVE 以 技术预览 集成了 应用容器, 从 OCI 镜像创建时自动转换为 LXC 栈。对最大隔离性与在线迁移有要求时 , 仍建议把容器嵌套在 QEMU VM 中。
11.1.技术概览Technology Overview
- LXC(linuxcontainers.org)
- 集成到 PVE Web GUI
- 命令行工具
pct - 通过 PVE REST API 访问
lxcfs提供容器化/proc- 通过 cgroups 做资源隔离
- AppArmor + seccomp 提升安全
- 现代 Linux 内核
- 基于镜像(模板)的部署
- 使用 PVE 存储库
- 从主机侧配置(网络 / DNS / 存储)
11.2.受支持的发行版Supported Distributions
下列发行版模板可通过官方仓库下载 , 用 pveam 或 GUI 获取。
11.2.1.Alpine Linux
面向安全的轻量发行版(musl libc + busybox):alpinelinux.org。
11.2.2.Arch Linux
轻量灵活 , KISS 原则 , 滚动发布 :archlinux.org。
11.2.3.CentOS / AlmaLinux / Rocky Linux
CentOS / Stream:源自 RHEL 的稳定可重现平台。 AlmaLinux:与 RHEL® 及 Stream 之前的 CentOS 二进制 1:1 兼容。 Rocky:以「bug-for-bug」100% 兼容头部企业 Linux 为目标。
11.2.4.Debian
Debian 项目自由操作系统 :debian.org。
11.2.5.Devuan
不带 systemd 的 Debian 分支 , 主张「Init Freedom」。
11.2.6.Fedora
面向硬件 / 云 / 容器的创新自由开源平台。
11.2.7.Gentoo
源码编译型 Linux , 滚动发布。
11.2.8.openSUSE
系统管理员与桌面用户的选择。
11.2.9.Ubuntu
面向企业服务器、桌面、云与 IoT 的现代开源 Linux。
11.3.容器镜像Container Images
容器镜像(也称「模板」或「appliance」)是 tar 归档 , 含运行容器所需全部内容。 PVE 主要用两类 :系统容器模板(构建完整虚拟环境)和基于 OCI 的 应用容器镜像。
11.3.1.系统容器模板
PVE 自带常见发行版基础模板 , 可用 GUI 或 pveam(PVE Appliance Manager)下载 , 另提供 TurnKey Linux 模板。可用列表通过 pve-daily-update 每日更新 , 手动触发:
# pveam update
查看可用镜像:
# pveam available
按类别筛选 , 例如 system:
# pveam available --section system system alpine-3.14-default_20210623_amd64.tar.xz system archlinux-base_20210420-1_amd64.tar.gz system centos-8-default_20201210_amd64.tar.xz system debian-10-standard_10.7-1_amd64.tar.gz system fedora-34-default_20210427_amd64.tar.xz system ubuntu-20.04-standard_20.04-1_amd64.tar.gz ...
使用前先下载到某存储(不确定用 local , 集群建议共享存储):
# pveam download local debian-10.0-standard_10.0-1_amd64.tar.gz
列出已下载:
# pveam list local local:vztmpl/debian-10.0-standard_10.0-1_amd64.tar.gz 219.95MB
也可用 Web 界面下载 / 列举 / 删除容器模板。
pct 据此创建容器:
# pct create 999 local:vztmpl/debian-10.0-standard_10.0-1_amd64.tar.gz
删除镜像:
# pveam remove local:vztmpl/debian-10.0-standard_10.0-1_amd64.tar.gz
11.3.2.Open Container Initiative(OCI)镜像
PVE 也可用 OCI 镜像创建容器(系统或应用)。 应用容器目前为技术预览。 由 OCI 镜像创建的容器仍走现有 LXC 框架。
11.3.3.获取 OCI 镜像
Web 界面中 , 在某存储的容器模板视图用 Pull from OCI registry 拉取 , 或手动上传。模板就位后用 pct create 或 Web 向导创建。
11.4.容器设置Container Settings
11.4.1.通用设置
- Node:运行的物理服务器
- CT ID:本 PVE 安装内唯一的容器编号
- Hostname:容器主机名
- Resource Pool:容器与 VM 的逻辑分组
- Password:容器 root 密码
- SSH Public Key:SSH 登录 root 用的公钥
- Unprivileged container:创建时选择是否非特权
- Nesting:暴露 procfs / sysfs 允许嵌套容器(systemd 也用它隔离服务)
非特权容器
借助 user namespaces —— 容器内 root(UID 0)映射到容器外非特权用户 , 大多数安全问题(逃逸、资源滥用)影响的是普通用户而非 LXC 本身 , LXC 团队认为设计上是安全的。 新建容器的默认选项。
若容器以 systemd 作 init, systemd 版本需 ≥ 220。
特权容器
安全靠 AppArmor、 seccomp 与命名空间。 LXC 团队认为 不安全 —— 不视新逃逸为值得 CVE 的问题。特权容器只用于受信环境。
11.4.2.CPU
用 cores 限制容器可见核数(cpuset cgroup)。 pvestatd 会周期分配运行中容器到可用核 :
# pct cpusets --------------------- 102: 6 7 105: 2 3 4 5 108: 0 1 ---------------------
容器直接用主机内核 , 任务由主机 CFS 调度器调度。
cpulimit:CPU 时间上限 , 浮点 —— 可分配 2 核但限为半核:cores: 2 cpulimit: 0.5
cpuunits:内核调度器相对权重 , 越大 CPU 时间越多。默认 100(cgroup v1 为 1024)。
11.4.3.内存
memory:总内存上限(memory.limit_in_bytes)。swap:允许使用主机 swap(memory.memsw.limit_in_bytes设为 memory + swap 之和)。
11.4.4.挂载点
根挂载点用 rootfs, 另可配置至多 256 个(mp0 – mp255):
rootfs: [volume=]<volume> [,acl=<1|0>][,mountoptions=<opt;...>][,quota=<1|0>]
[,replicate=<1|0>][,ro=<1|0>][,shared=<1|0>][,size=<DiskSize>]
mp[n]: [volume=]<volume>,mp=<Path> [,acl=...][,backup=<1|0>][,mountoptions=...]
[,quota=...][,replicate=...][,ro=...][,shared=...][,size=...]
acl- 显式启 / 禁 ACL。
backup- 是否备份该挂载点(仅卷型)。
mountoptions- 额外挂载选项。
mp- 容器内路径(不得含符号链接)。
quota- 容器内用户配额(不支持 zfs subvol)。
replicate(默认 1)- 是否纳入存储复制任务。
ro- 只读。
shared(默认 0)- 标记非卷型挂载点在所有节点可用 —— 不自动共享 , 仅声明。
size- 卷大小(只读)。
volume- 挂入的卷 / 设备 / 目录。
当前三类 :存储卷型、 bind、 设备型。典型 rootfs :
rootfs: thin1:base-100-disk-1,size=8G
存储卷型
由 PVE 存储子系统管理 , 三种形态 :镜像型(ext4 raw)、 ZFS subvolume(技术上 bind, 但有管理能力可做快照 / 调大小)、目录型(size=0 时创建目录而非 raw)。语法 STORAGE_ID:SIZE_IN_GB 自动分配:
pct set 100 -mp0 thin1:10,mp=/path/in/container
在 thin1 分配 10 GB 卷 , 挂到容器内 /path/in/container。
Bind 挂载点
把主机任意目录挂入容器 —— 访问家目录、 USB 目录、 NFS 等。不由存储子系统管理 , 不能做快照 / 配额;非特权容器还可能遇到用户映射权限问题 , 不能用 ACL。
vzdump 不备份 bind 挂载点内容。出于安全 , bind 源应使用专门保留目录(如 /mnt/bindmounts/ 下), 切勿 bind /、 /var、 /etc 等系统目录 ; bind 源也不得含符号链接。
例 :把 /mnt/bindmounts/shared 挂到容器 100 /shared, 在 /etc/pve/lxc/100.conf:
mp0: /mnt/bindmounts/shared,mp=/shared
或:
pct set 100 -mp0 /mnt/bindmounts/shared,mp=/shared
设备型挂载点
把主机块设备直接挂入容器。不由存储子系统管理 , 但 quota / acl 会被尊重。
仅特殊场景使用 , 多数情况下存储卷型性能相当且功能更多。 vzdump 不备份设备型挂载点内容。
11.4.5.网络
每容器最多 10 个网卡(net0 – net9):
net[n]: name=<string>[,bridge=...][,firewall=<1|0>][,gw=<v4>][,gw6=<v6>]
[,host-managed=<1|0>][,hwaddr=<XX:XX:XX:XX:XX:XX>]
[,ip=<IPv4/CIDR|dhcp|manual>][,ip6=<IPv6/CIDR|auto|dhcp|manual>]
[,link_down=<1|0>][,mtu=...][,rate=<mbps>]
[,tag=<VLAN>][,trunks=<vlanid;...>][,type=<veth>]
bridge- 挂载到的网桥。
firewall- 是否应用防火墙规则。
gw/gw6- v4 / v6 默认网关。
host-managed- 接口 IP 配置是否由主机管理。
hwaddr- MAC 地址(I/G 位为 0)。
ip/ip6- CIDR 格式(或 dhcp / auto / manual)。
link_down- 断线(如拔线)。
mtu(64 – 65535)- MTU(
lxc.network.mtu)。 name- 容器内接口名(
lxc.network.name)。 rate- 带宽限制(mbps)。
tag(1 – 4094)- VLAN tag。
trunks- 透传 VLAN ID 列表。
type- 接口类型(
veth)。
11.4.6.容器自启停
主机开机自启 :GUI 勾选 Start at boot, 或:
# pct set CTID -onboot 1
启停顺序
- Start/Shutdown order:启动优先级 , 越小越早;关机反序。
- Startup delay:本容器启动与下一个容器启动的间隔(秒)。
- Shutdown timeout:发送关机命令后的等待时间(默认 60 秒)。
未设顺序的容器始终在已设置的容器之后启动;该参数仅在同一主机本地有效 , 不跨集群。
11.4.7.钩子脚本
# pct set 100 -hookscript local:snippets/hookscript.pl
会在容器生命周期多个阶段调用 , 示例 :/usr/share/pve-docs/examples/guest-example-hookscript.pl。
11.5.安全考量Security Considerations
容器用主机内核 , 会给恶意用户提供攻击面。一般 VM 隔离更好 —— 向未知 / 不受信用户开放容器时需考虑。 LXC 以 AppArmor、 cgroup、命名空间缩小攻击面。
11.5.1.AppArmor
AppArmor profile 限制可能危险动作 , 禁用若干 syscall(如 mount)。追踪:
# dmesg | grep apparmor
不建议但可禁用单容器 AppArmor —— 在 /etc/pve/lxc/CTID.conf:
lxc.apparmor.profile = unconfined
生产环境不推荐。
11.5.2.Control Groups(cgroup)
cgroup 按层级组织进程并分配系统资源。容器通过 cgroup 控制 CPU 时间、内存与 swap、设备节点访问;快照前用来「冻结」容器。 cgroup v1 在 PVE 7.0 弃用、 9.0 完全移除。
版本兼容
cgroup v2 下内存与 swap 独立控制 —— memory / swap 配置直接映射到对应值(v1 只能限制 memory 与「memory + swap 总和」)。设备控制器配置方式完全不同 , 纯 v2 下不支持 fs 配额。容器 OS 要支持 v2:systemd ≥ 231, 不用 systemd 作 init 的容器一般可。
CentOS 7 与 Ubuntu 16.10 是 systemd 过旧无法在 cgroup v2 下运行的典型例子 —— 解决办法 :(1) 升级到 Ubuntu 18.04 / 20.04、 CentOS 8、 AlmaLinux、 Rocky 等 ;(2) 通过 backports 升级容器内 systemd ;(3) 把容器或其服务迁到 VM。
切换版本
PVE 9.0 之前可通过内核命令行回退:
systemd.unified_cgroup_hierarchy=0
11.6.客户机操作系统配置Guest Operating System Configuration
PVE 会尝试探测容器内发行版并修改若干文件。启动时会:
- 设置
/etc/hostname为容器名 - 修改
/etc/hosts允许本地 hostname 解析 - 把完整网络配置传入容器
- 配置 DNS(传 DNS 服务器信息)
- 调整 init 系统(如修正 getty 数量)
- 新建容器时设置 root 密码
- 重写
ssh_host_keys使每容器唯一 - 随机化 crontab, 避免所有容器同时跑 cron
PVE 所做修改用注释标记包围:
# --- BEGIN PVE --- <data> # --- END PVE ---
标记会插到合理位置;若存在会就地更新而不移动。可建 .pve-ignore.<file> 阻止修改某文件 —— 例如 /etc/.pve-ignore.hosts 存在时 /etc/hosts 不动 :
# touch /etc/.pve-ignore.hosts
大多数修改与 OS 相关;手动设 ostype 为 unmanaged 可完全禁用修改。 OS 类型探测先看 /etc/os-release, 失败时再看:
- Ubuntu:
/etc/lsb-release(DISTRIB_ID=Ubuntu) - Debian:
/etc/debian_version - Fedora:
/etc/fedora-release - RedHat / CentOS:
/etc/redhat-release - ArchLinux:
/etc/arch-release - Alpine:
/etc/alpine-release - Gentoo:
/etc/gentoo-release
若 ostype 与自动探测结果不符 , 容器启动失败。
11.7.容器存储Container Storage
PVE LXC 容器存储模型比传统更灵活 —— 一个容器可有多个挂载点 , 按应用选最合适存储。例如 rootfs 放廉价慢盘 , 数据库通过另一个挂载点放快速分布式存储。详见 §11.4.4 挂载点。所有 PVE 存储类型可用(本地 LVM / ZFS / 目录、共享 iSCSI / NFS、分布式 Ceph), 底层支持时可用快照 / 克隆 ; vzdump 借助快照做一致性备份。本地设备 / 目录可用 bind 挂载点 , 几乎零开销。
11.7.1.FUSE 挂载
因 Linux freezer 子系统现存问题 , 强烈不建议 容器内使用 FUSE ——suspend / 快照备份需冻结容器。若无替代方案 , 可在主机做 FUSE 挂载 , 再用 bind 挂载点暴露给容器。
11.7.2.容器内使用 quota
配额可对每用户限制磁盘空间。
目前需要旧版 cgroup(v1)。
仅 ext4 镜像型存储 + 特权容器下可用。
启用 quota 后挂载带上 usrjquota=aquota.user,grpjquota=aquota.group,jqfmt=vfsv0:
# quotacheck -cmug / # quotaon /
之后用 edquota 编辑。每个挂载点都要跑一次 , 把 / 换成对应路径。
11.7.3.容器内使用 ACL
标准 POSIX ACL 可在容器内用 —— 比 user/group/others 更细的属主控制。
11.7.4.挂载点备份
给挂载点加 backup=1 纳入备份 , 现有:
mp0: guests:subvol-100-disk-1,mp=/root/files,size=8G
改为:
mp0: guests:subvol-100-disk-1,mp=/root/files,size=8G,backup=1
GUI 新建挂载点时默认开启。
11.7.5.挂载点复制
默认 Root Disk 复制时附加挂载点一并复制。若要 PVE 存储复制跳过某挂载点 , 为它启用 Skip replication。 PVE 5.0 起复制要求 zfspool 类型;已配置复制又想把挂载点放到非 zfspool, 必须为该挂载点启用 Skip replication。
11.8.备份与恢复Backup and Restore
11.8.1.容器备份
用 vzdump —— 详见其 man 页。
11.8.2.恢复备份
用 pct restore 恢复 vzdump 备份。默认尽量按备份配置恢复;可在命令行手动覆盖选项。
pvesm extractconfig 可查看 vzdump 归档中的备份配置。
Simple 模式
未显式设 rootfs 与 mpX 时 , 按备份配置恢复挂载点:
- 从备份提取挂载点及选项
- 在
storage参数指定的存储(默认local)上为卷型挂载点创建卷 - 从备份解压文件
- 把 bind / 设备型挂载点加到恢复后的配置(仅 root)
bind / 设备型从不被备份 —— 最后一步只恢复配置 , 不恢复文件。假定它们由其他机制备份或不需备份。
Web 界面容器恢复用此简单模式。
Advanced 模式
指定 rootfs(与可选 mpX)时自动切到 advanced —— 完全忽略 备份内的 rootfs / mpX, 仅用命令行参数。可灵活调整 :每挂载点单独设目标存储 / 大小 ; 按新方案重新分布文件;恢复到设备 / bind(仅 root)。
11.9.使用 pct 管理容器Managing Containers with pct
「Proxmox Container Toolkit」(pct)是 PVE 容器管理 CLI —— 创建 / 销毁、控制执行(start / stop / reboot / migrate 等)、改配置参数(网络、内存限制等)。
11.9.1.CLI 示例
用 Debian 模板创建容器:
# pct create 100 /var/lib/vz/template/cache/debian-10.0-standard_10.0-1_amd64.tar.gz
启动:
# pct start 100
通过 getty 开登录会话:
# pct console 100
进入 LXC 命名空间以 root 启 shell:
# pct enter 100
查看配置:
# pct config 100
运行中添加 eth0 网卡(桥到 vmbr0)并设地址 / 网关:
# pct set 100 -net0 name=eth0,bridge=vmbr0,ip=192.168.15.147/24,gw=192.168.15.1
把内存调到 512 MB:
# pct set 100 -memory 512
销毁总会从 ACL 与防火墙配置中移除;如要连同复制 / 备份 / HA 资源一并移除 , 加 --purge:
# pct destroy 100 --purge
启用 purge 同时会从引用该资源的亲和 / 反亲和规则中移除 HA 资源 , 并删除仅剩此一资源的规则。
把挂载点卷移到其他存储:
# pct move-volume 100 mp0 other-storage
把卷划归另一台容器(从源取下 mp0 挂到目标 mp1, 后台重命名卷):
# pct move-volume 100 mp0 --target-vmid 200 --target-volume mp1
11.9.2.获取调试日志
启动失败时加 --debug:
# pct start CTID --debug
或用 lxc-start 把日志写入文件:
# lxc-start -n CTID -F -l DEBUG -o /tmp/lxc-CTID.log
该命令尝试前台启动 , 停止时在另一终端 pct shutdown CTID 或 pct stop CTID。
若上次 pct start 后改过容器配置 , 至少再跑一次 pct start 让 lxc-start 使用新配置。
11.10.迁移Migration
# pct migrate <ctid> <target>
容器 离线 时即可迁移 ; 有本地卷 / 挂载点时 , 只要目标有同名存储 , 内容会通过网络复制过去。
因技术限制 , 运行中容器 不能在线迁移。可做「重启迁移」——关停、移动、目标启动。容器很轻 , 通常只有数百毫秒停机。 GUI 或 pct migrate --restart 都可触发。达到超时(默认 180 秒)后强杀容器 , 再照离线迁移流程移动 , 完成后在目标启动。
11.11.配置Configuration
容器配置存于 /etc/pve/lxc/<CTID>.conf。 /etc/pve/ 中的文件会自动复制到所有集群节点。
CTID < 100 保留 , CTID 需在集群内唯一。
示例
ostype: debian arch: amd64 hostname: www memory: 512 swap: 512 net0: bridge=vmbr0,hwaddr=66:64:66:64:64:36,ip=dhcp,name=eth0,type=veth rootfs: local:107/vm-107-disk-1.raw,size=7G
纯文本可用 vi / nano 改 , 但需重启容器生效。通常建议用 pct 或 GUI —— 可热改的会即时应用到运行中容器(hot plug), 无法热改的标为 pending(GUI 红色), 重启后生效。
11.11.1.文件格式
# this is a comment OPTION: value
空行忽略 , # 开头视作注释。还可直接写底层 LXC 风格:
lxc.init_cmd: /sbin/my_own_init
或:
lxc.init_cmd = /sbin/my_own_init
这些设置直接传给 LXC 底层工具。
11.11.2.快照
创建快照时 , pct 把当时配置存入同一文件的独立 snapshot 段:
memory: 512 swap: 512 parent: testsnaphot ... [testsnaphot] memory: 512 swap: 512 snaptime: 1457170803 ...
parent 记录父子关系 ; snaptime 为 Unix 时间戳。
11.11.3.选项
arch: <amd64|arm64|armhf|i386|riscv32|riscv64>(默认 amd64)- OS 架构。
cmode: <console|shell|tty>(默认 tty)- 控制台模式 ——
consoleattach 到/dev/console,shell启 shell(无 login)。 console: <boolean>(默认 1)- 是否挂控制台设备。
cores: <1 – 8192>- 分配核数 , 默认全部可用核。
cpulimit: <0 – 8192>(默认 0)- CPU 使用上限(0 不限)。
cpuunits: <0 – 500000>(v1=1024, v2=100)- CPU 权重。
debug: <boolean>- 启动时启用 debug 日志。
description: <string>- 容器描述(GUI 摘要 , 以注释存于文件)。
dev[n]: [path=]<Path>[,deny-write=<1|0>][,gid=...][,mode=<八进制>][,uid=...]- 直通给容器的设备。
entrypoint: <命令>(默认 /sbin/init)- 作为 init 运行的命令(可带参数)。
env: <NUL 分隔 K=V 列表>- 容器运行时环境变量 , 替换
lxc.environment.runtime。 features: [force_rw_sys=...][,fuse=...][,keyctl=...][,mknod=...][,mount=<fstype;...>][,nesting=...]- 高级特性 :
force_rw_sys(非特权容器以 rw 而非 mixed 挂/sys)、fuse(允许 FUSE, 注意与 freezer 的 I/O 死锁)、keyctl(非特权 , docker 在容器内需要)、mknod(实验性 , 需 ≥ 5.3 内核)、mount(允许挂载指定 fs 类型 , 有安全副作用)、nesting(嵌套 , 暴露 procfs / sysfs , systemd 隔离服务需要)。 hookscript: <string>- 生命周期钩子脚本。
hostname: <string>- 容器 hostname。
lock: <backup|create|destroyed|disk|fstrim|migrate|mounted|rollback|snapshot|snapshot-delete>- 加锁 / 解锁容器。
memory: <≥16>(默认 512, MB)- 容器 RAM。
mp[n]: ...- 挂载点 , 见 §11.4.4。
nameserver / searchdomain: <string>- DNS 服务器 / 搜索域 , 都未设则沿用主机。
net[n]: ...- 网卡 , 见 §11.4.5。
onboot: <boolean>(默认 0)- 主机开机自启。
ostype: <alpine|archlinux|centos|debian|devuan|fedora|gentoo|nixos|opensuse|ubuntu|unmanaged>- OS 类型 —— 对应
/usr/share/lxc/config/<ostype>.common.conf。unmanaged跳过 OS 专属配置。 protection: <boolean>- 保护标志 , 阻止删除 / 修改盘。
rootfs: ...- 根卷 , 见 §11.4.4。
startup: [[order=]N][,up=N][,down=N]- 启动顺序与 up / down 延迟。
swap: <≥0>(默认 512, MB)- 容器 swap。
tags: <string>- 容器标签(元信息)。
template: <boolean>- 是否为模板。
timezone: <string>- 容器时区 ——
host或/usr/share/zoneinfo/zone.tab中值。 tty: <0 – 6>(默认 2)- 容器可用 tty 数。
unprivileged: <boolean>(创建默认 1)- 非特权运行 ; 恢复时默认同备份。 不要手改。
unused[n]: [volume=]<volume>- 孤立卷引用(内部用 , 勿手改)。
11.12.锁Locks
容器迁移、快照、备份(vzdump)会设锁 , 防止并发不兼容操作。有时需手动移除(如断电后残留):
# pct unlock <CTID>
仅在你确认设锁的操作已不再运行时才解锁。