跳转到内容

挂载点权限被拒绝 ​

适用范围 ​

容器能正常启动,但给它挂载的宿主机目录(mp0 这类挂载点,或 bind mount)在容器内部显示属主是 nobody:nogroup,读写报 Permission denied。

不适用于容器本身启动失败的情况,见容器起不来。

开始排查前 ​

先确认这个容器是特权 (privileged) 还是非特权 (unprivileged),两者的处理方式完全不同:

sh
pct config <ctid> | grep unprivileged

看到 unprivileged: 1 是非特权容器(PVE 默认值),本页主要针对这种情况。没有这一行(不写 unprivileged: 0,而是完全不出现)是特权容器,这类容器里的 root 就是宿主机的 root,理论上不应该有这个问题——如果特权容器也报权限错误,通常是目录本身的 Linux 权限位问题,不是本页要讲的 UID 映射问题。

不要用「改成特权容器」来绕开

把非特权容器改成特权容器确实能让这个问题消失,但代价是关掉了容器和宿主机之间的隔离:特权容器里的 root 就是宿主机 UID 0。这不是本页推荐的方向,正确做法是处理下面的 UID 映射。原理见特权与非特权容器。

排查步骤 ​

第一步:理解问题的根源——UID 平移 ​

非特权容器里,容器内的 UID 会整体平移映射到宿主机的一段不特权 UID 上。默认映射规则:

宿主机 UID = 100000 + 容器内 UID。

例如容器内的 root(UID 0)在宿主机上实际是 UID 100000;容器内 UID 1000 的普通用户,在宿主机上是 101000。

宿主机上被挂载进容器的目录,如果属主是宿主机的 root(UID 0)或者其他和 100000+ 对不上的用户,容器里看到的就会是一个不认识的用户(显示为 nobody),自然没有写入权限。

第二步:确认具体是哪个 UID 对不上 ​

sh
# 在容器内部执行:确认容器内需要写入的用户和它的 UID
id <容器内用户名>

# 在宿主机执行:确认被挂载目录当前的属主
ls -ln <宿主机路径>

ls -ln 显示的是数字 UID。用容器内的 UID 加上 100000,看是否等于宿主机目录当前显示的属主。不相等,就是这里的问题。

第三步:三种处理方式,按场景选 ​

方式一:直接改宿主机目录的属主(最简单) ​

适合这个目录只给这一个容器用的场景:

sh
# 在宿主机执行,把目录属主改成"容器内 UID + 100000"
chown -R 100000:100000 <宿主机路径>

改完后容器里看到的属主就是 root(或对应的用户),读写恢复正常。

先在小范围验证再扩大范围

chown -R 是递归操作,路径写错会影响到不该影响的文件。先对一个测试子目录验证效果,确认路径无误后再对整个目录执行。

方式二:宿主机和多个容器共享同一个目录 ​

适合这个目录需要被宿主机进程或多个容器同时访问的场景,直接 chown 会互相冲突。

做法是在宿主机上建一个统一的组,让目录对这个组可写,并确保每个容器映射后的 UID 都在这个组里。具体配置根据场景(NFS、多容器、宿主机服务共用)差异较大,属于更进阶的内容,可以先在命令行工具全景里查阅相关命令再动手,必要时用只读挂载规避写权限问题。

方式三:自定义 UID 映射(lxc.idmap) ​

适合需要容器内某个特定 UID 直接对应宿主机某个特定 UID(不走默认的 100000 偏移)的场景。

自定义映射要同时改两个地方,配错会导致容器起不来

除了在 /etc/pve/lxc/<ctid>.conf 里写 lxc.idmap 条目,还必须在宿主机的 /etc/subuid、/etc/subgid 里给 root 授权对应的 ID 段,两处不一致会直接导致容器无法启动(见容器起不来)。

改之前先备份配置文件:

sh
cp /etc/pve/lxc/<ctid>.conf /root/<ctid>.conf.bak

改完如果容器起不来,先恢复这份备份,确认容器能正常启动后再重新、逐项调整映射。

第四步:确认容器内部的应用是否也需要额外配置 ​

有些应用(数据库、媒体服务器)在容器内部还会以特定的非 root 用户运行。改完宿主机侧的属主后,还要确认容器内运行该服务的用户,对这个挂载点确实有对应的读写权限(容器内部的权限位和属主,不只是跨越宿主机边界的那一层映射)。

确认恢复 ​

  1. 容器内对挂载点执行写入测试:
sh
# 在容器内部执行
touch <容器内挂载路径>/test-write && rm <容器内挂载路径>/test-write
  1. 实际运行的服务能正常读写这个目录(不仅仅是 root 能写)。
  2. 重启容器一次,确认挂载和权限在重启后依然正常(pct config <ctid> 里挂载点定义没有丢失)。

仍未解决 ​

按如何有效求助整理信息:

sh
pveversion -v
pct config <ctid>

加上 ls -ln 对挂载目录的输出、容器内 id 的输出,以及如果用了自定义 idmap,附上 /etc/subuid、/etc/subgid 中与该容器相关的行(注意脱敏,这些通常不含敏感信息,但整份文件如有其他容器的信息也一并检查)。

参考资料 ​

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