蓝盟系统集成,了解如何使用Podman在不同的用户空间中运行容器

发布者:上海IT外包 来源:www.linemore.com

  Podman是libpod库的一部分,允许用户管理pod,容器和容器映像。在我的上一篇文章中,我写了关于Podman作为运行容器的更安全的方法。本节介绍如何使用Podman在单独的用户命名空间中运行容器。
  作为分离容器的一大特色,我想到了主要由Red Hat的Eric Biederman开发的用户命名空间用户命名空间。用户命名空间允许您为容器执行指定用户标识符(UID)和组标识符(GID)映射。也就是说,您可以在容器内运行UID 0,在容器外运行UID 100000。如果容器进程转义容器,则内核认为容器使用UID 100000运行。此外,UID拥有的所有未映射到用户命名空间的文件对象都被视为nobody(65534,其中UID被指定为kernel.overflowuid),并且容器进程无法访问它,除非该对象可以是“other”。人们“访问(例如世界可读/可写)
  如果您的文件包含660个拥有“真实”根的所有者,并且命名空间中的容器进程尝试读取该文件,则会阻止您访问该文件并假定该文件不属于任何人。
  例子
  以下是它的工作原理:首先在root拥有的系统上创建一个文件。
  $ sudo bash -c'echo Test>
  /tmp/test'
  $ sudo chmod 600/tmp/test
  $ sudo ls -l/tmp/test
  -rw -------。 1 root root 5 Dec 17 16: 40/tmp/test
  接下来,将文件卷挂载到使用用户命名空间映射0: 100000: 5000运行的容器上。
  $ sudo podman运行-ti -v/tmp/test:/tmp/test: Z --uidmap 0: 100000: 5000 fedora sh
  #ID
  Uid=0(根)gid=0(根)组=0(根)#ls -l/tmp/test
  -rw-rw ----。 1无人无人11月11日30 12: 40/tmp/test
  #cat/tmp/test
  Cat:/tmp/test:权限被拒绝
  上面的--uidmap设置指示Podman映射容器内的一系列5000 UID,从容器外的UID 100000开始的范围(100000-104999)映射到从容器的UID 0开始的范围(0-4999)。会的。如果进程在具有UID 1的容器内运行,则它在主机上为100001。
  由于实际的UID=0没有映射到容器,因此root拥有的所有文件都被视为nobody。即使容器内的进程具有CAP_DAC_OVERRIDE函数,也无法覆盖此保护。 DAC_OVERRIDE功能允许根进程读取和写入系统上的文件,即使root用户不拥有进程或无法全局读取或写入。
  用户命名空间的功能与主机的功能不同。它们是命名空间的函数。换句话说,容器的根只在容器内具有功能.——实际上,只有此范围内的UID映射到内部用户命名空间。当容器进程转义容器时,除了未映射到用户命名空间的UID之外,没有其他功能,包括UID=0。无论进程如何进入其他容器,如果容器使用不同的UID范围,这些功能都不可用。
  SELinux和其他技术也限制了容器进程停止容器时发生的情况。
  使用podman top显示用户命名空间。
  添加了podman top的功能,以检查在容器内运行的进程的用户名,并识别主机上的实际UID。
  首先让我们使用UID映射运行一个sleep容器。
  $ sudo podman run --uidmap 0: 100000: 5000 -d fedora sleep 1000
  现在运行podman top。
  $ sudo podman顶级最新用户用户
  用户HUSER
  根100000$ ps -ef | grep睡觉
  100000 21821 21809 0 08: 04? 00: 00: 00/usr/bin/coreutils --coreutils-prog-shebang=sleep/usr/bin/sleep 1000
  podman top报告用户进程在容器内以root身份运行,但在主机(HUSER)上的UID 100000上运行。 ps命令还会检查睡眠过程是否以UID 100000运行。
  现在让我们运行第二个容器。这次,我将从200000中选择一个单独的UID映射。
  $ sudo podman run --uidmap 0: 200000: 5000 -d fedora sleep 1000
  $ sudo podman顶级最新用户用户
  用户HUSER
  根200000
  $ ps -ef | grep睡觉
  100000 21821 21809 0 08: 04? 00: 00: 00/usr/bin/coreutils --coreutils-prog-shebang=sleep/usr/bin/sleep 1000
  200000 23644 23632 1 08: 08? 00: 00: 00/usr/bin/coreutils --coreutils-prog-shebang=sleep/usr/bin/sleep 1000
  podman top报告第二个容器在容器内以root身份运行,但在主机上,UID=200000。
  请参阅ps命令,该命令指示您正在运行两个休眠进程(100000和200000)。
  换句话说,在单独的用户命名空间中运行容器允许在进程之间分离现有的UID,这从一开始就是Linux/Unix的标准安全工具。
  用户名空间问题
  多年来,我一直坚持认为用户命名空间应该是每个人都应该拥有的安全工具,但我很少使用它。原因是没有文件系统支持,也没有移动文件系统移动文件系统。我正在尝试在容器中的多个容器之间共享基本映像。 Fedora基本映像用于上面的每个示例中。 Fedora映像中的大多数文件都由实际UID=0拥有。使用用户名称空间0在此映像上运行容器: 100000: 5000基本上将所有文件视为不拥有,因此您需要移动所有UID以匹配用户命名空间。多年来,我们希望mount选项重新映射这些文件UID,以便内核与用户命名空间匹配。上游内核存储开发人员仍在开发此功能并取得了一些进展,但这是一个问题。
  Podman可以在同一图像中使用不同的用户命名空间,因为由Nalin Dahyabhai领导的团队开发的自动chown已内置于容器/存储中。如果Podman使用容器/存储并且Podman首先在新用户命名空间中使用容器图像,则容器/存储将使用映射到用户命名空间的UID“chowns”(例如,更改所有权)图像中的所有文件。创建一个新图像。可以把它想象成Fedora: 0: 100000: 5000图像。
  当使用相同的UID映射在镜像上运行其他容器时,Podman使用“预先准备好的”映像。当我在0: 200000: 5000上运行第二个容器时,容器/存储器会创建第二个映像,称为fedora: 0: 200000: 5000。
  如果您运行podman build或podman commit并将新创建的映像推送到容器注册表,Podman将使用容器/存储来恢复移动并将所有文件所有者推回到实际的UID=0。镜像。
  根据图像中的文件数量,Chown可能会很慢,从新的UID映射创建容器时,这可能会导致真正的减速。此外,在典型的OverlayFS中,将复制图像中的所有文件。常规的Fedora映像最多可能需要30秒才能完成chown并启动容器。
  幸运的是,Red Hat内核存储团队(主要是Vivek Goyal和Miklos Szeredi)在内核4.19中为OverlayFS添加了新功能。此功能称为“仅复制元数据”。如果使用metacopy=on选项安装级联文件系统,则在更改文件属性时,不会复制较低层的内容,并且内核会创建一个新的inode,其中包含引用较低级别数据的属性。即使内容发生变化,它仍会复制内容。如果您想尝试一下,可以在Red Hat Enterprise Linux 8 Beta中使用此功能。换句话说,容器chown可以在2秒内发生,并且它不会使每个容器的存储空间加倍。
  这允许像Podman这样的工具在不同的用户名称空间中运行容器,从而大大提高系统安全性。
>
400-635-8089
立即
咨询
电话咨询
服务热线
400-635-8089
微信咨询
微信咨询
微信咨询
公众号
公众号
公众号
返回顶部