如何管理以非 root 用户身份运行的容器的绑定挂载所有权和权限?

如何管理以非 root 用户身份运行的容器的绑定挂载所有权和权限?

我们在 RHEL 主机上使用 Red Hat 容器镜像,所有镜像均基于其 ubi7 或 ubi8 镜像,默认情况下以默认用户 (uid 1001) 身份运行。

当容器需要对主机目录的写访问权限(即写入日志或临时文件)时,这会带来挑战,因为主机的 UID 和 GID 保存在容器中,并且容器写入的文件将归容器用户的 UID 所有。

据我所知,这让我有两个选择:

  1. 在我的主机上创建一个 UID 为 1001 的用户,并将该用户设置为已挂载卷的所有者。这可能会带来问题,因为 UID 1001 是在主机上添加新用户时使用的第一个 UID,而主机上的 UID 并未强制为某个特定 UID。因此,如果需要将容器部署在可能具有相同或可能不具有相同一致 UID 映射的多台服务器上,则可能难以管理。然而,据我所知,这是唯一方法,使容器(UID 为 1001)写入的文件的所有者与主机上的所需用户匹配,并使主机上写入的文件的所有者与容器中的现有 UID 匹配。
  2. 将挂载的主机目录设置为全球可写,这会带来许多安全隐患,其中之一就是主机上的任何用户都有权删除容器写入的文件。如果 UID 1001 已分配给主机上的另一个用户,则这些文件也可能显示为由另一个用户拥有。

通常情况下,我只会在容器镜像中创建一个匹配的用户:组组合,在需要的地方重置所有权和权限并重建它,但对于 Red Hat 创建的图像,这意味着大量的工作,因为一切都以 UID 1001 运行,并且有许多脚本(container-entrypoint fix-permissions、generate-container-user)强制这样做。

我是否理解得正确,或者是否有其他(更好的)方法可以做到这一点?

答案1

我刚刚明白了...Red Hat 映像会自动将默认用户的 uid 更改为使用 generate-container-user 脚本运行容器的任何内容,因此我只需要使用 USER 完成我的 Dockerfile,或者使用 --user 运行它就可以了。

答案2

还有其他方法可以做到这一点吗?

另一个选择是使用 ACL。ACL 比用户/组/其他标准 *nix 权限灵活得多。

当然,ACL 的灵活性也使其变得更加复杂。您可以使用类似以下示例的方法设置 ACL。

花些时间阅读 acl、setfacl、getfacl 的手册页,并进行一些测试以确保你的权限正确。ACL 很复杂,下面只是一个例子。

例子

set_acl 脚本

TMP_DIR_ACL=path/acl_directories
FILE_ACL=path/acl_files
ITEMPATH=/srv/data
OWNER=root
GROUP=root

# set user/group owner on any existing files/dirs
find $ITEMPATH ! -user $OWNER -exec chown --no-dereference $OWNER {} +
find $ITEMPATH ! -group $GROUP -exec chgrp --no-dereference $GROUP {} +
# set acls for all existing direcoties
find $ITEMPATH -type d -exec setfacl --modify-file $DIR_ACL $ITEMPATH {} +
# set acls for all existing files
find $ITEMPATH -type f -exec setfacl --modify-file $FILE_ACL $ITEMPATH {} +
# makes any files created in a directory be owned by the directories group
find $ITEMPATH -type d -exec chmod g+s {} +

acl_directories

group::r-x
mask::rwx
other::r-x
user::rwx
user:1001:rwx
default:group::rwx
default:mask::rwx
default:other::r-x
default:user::rwx
default:user:1001:rwx

acl_文件

user::rwX
user:1001:rwX
group::r-X
other::r-X

相关内容