【问题标题】:Privileged containers and capabilities特权容器和功能
【发布时间】:2016-07-25 07:51:21
【问题描述】:

如果我在特权模式下运行容器,它是否具有所有内核功能,还是需要单独添加它们?

【问题讨论】:

    标签: docker linux-kernel kubernetes linux-capabilities


    【解决方案1】:

    在特权模式下运行确实为容器提供了所有功能。 但最好始终为容器提供所需的最低要求。

    Docker run command documentation 指的是这个标志:

    完整的容器功能(--privileged)

    --privileged 标志为容器提供了所有功能,它还解除了设备 cgroup 控制器实施的所有限制。换句话说,容器几乎可以做主机可以做的所有事情。此标志的存在是为了允许特殊用例,例如在 Docker 中运行 Docker。

    您可以使用--cap-add 标志提供特定功能。有关这些功能的更多信息,请参阅man 7 capabilities。可以使用文字名称,例如--cap-add CAP_FOWNER.

    【讨论】:

    • 有没有办法找出特定应用程序需要哪些功能?对于大多数应用程序来说,这似乎没有记录。
    • @codefx 这里没有经验法则,这取决于应用程序以及它在运行时可能调用的系统调用。如果您使用的是来自集线器的现成 docker 映像,则很可能会在此处提及。如果您使用自己编写的东西,您应该知道您使用的内核 API 可能需要特殊功能
    • @buddy123 你有参考文档吗?你的版本比我目前在Docker run reference 中找到的更有意义:“当操作员执行 docker run --privileged 时,Docker 将启用对主机上所有设备的访问,并在 AppArmor 或 SELinux 中设置一些配置以允许容器对主机的访问几乎与在主机上的容器外运行的进程相同。”它对“扩展权限”说了一些模糊的话,根本没有提到功能。
    • @IainSamuelMcLeanElder 好吧,我的评论已经快 7 年了。引用本身当时是从 docker docs 中获取的,但在那段时间里它改变了很多次...... :-)
    • 运行command(不是reference)实际上有一个不同的重叠页面。您的报价今天仍然出现:github.com/docker/cli/blob/… 我将编辑您的答案以链接到该页面。
    【解决方案2】:

    您永远不想使用--privileged 运行容器。

    我在配备 NVMe 驱动器的笔记本电脑上执行此操作,但它适用于任何主机:

    docker run --privileged -t -i --rm ubuntu:latest bash
    

    首先让我们做一些小事,测试 /proc 文件系统

    从容器中:

    root@507aeb767c7e:/# cat /proc/sys/vm/swappiness
    60
    root@507aeb767c7e:/# echo "61" > /proc/sys/vm/swappiness    
    root@507aeb767c7e:/# cat /proc/sys/vm/swappiness
    60
    

    好的,是为容器改还是为主机改?

    $ cat /proc/sys/vm/swappiness
    61
    

    哎呀!我们可以任意改变hosts内核参数。但这只是DOS情况,让我们看看我们是否可以从父主机收集特权信息。

    让我们遍历/sys 树并找到引导磁盘的主要次要编号。

    注意:我有两个 NVMe 驱动器,容器在另一个驱动器上的 LVM 下运行

    root@507aeb767c7e:/proc# cat /sys/block/nvme1n1/dev
    259:2
    

    好的,让我们在 dbus 规则不会自动扫描的位置创建一个设备文件:

    root@507aeb767c7e:/proc# mknod /devnvme1n1 b 259 2
    root@507aeb767c7e:/proc# sfdisk -d /devnvme1n1 
    label: gpt
    label-id: 1BE1DF1D-3523-4F22-B22A-29FEF19F019E
    device: /devnvme1n1
    unit: sectors
    first-lba: 34
    last-lba: 2000409230
    <SNIP>
    

    好的,我们可以读取引导盘,让我们为其中一个分区制作一个设备文件。虽然我们无法挂载它,因为它会打开,但我们仍然可以使用dd 来复制它。

    root@507aeb767c7e:/proc# mknod /devnvme1n1p1 b 259 3
    root@507aeb767c7e:/# dd if=devnvme1n1p1 of=foo.img
    532480+0 records in
    532480+0 records out
    272629760 bytes (273 MB, 260 MiB) copied, 0.74277 s, 367 MB/s
    

    好的,让我们挂载它,看看我们的努力是否奏效!!!

    root@507aeb767c7e:/# mount -o loop foo.img /foo
    root@507aeb767c7e:/# ls foo
    EFI
    root@507aeb767c7e:/# ls foo/EFI/
    Boot  Microsoft  ubuntu
    

    因此,基本上,您允许任何人在其上启动 --privileged 容器的任何容器主机都与授予他们对该主机上每个容器的 root 访问权限相同。

    不幸的是,Docker 项目选择了可信计算模型,并且在身份验证插件之外没有办法防止这种情况发生,所以总是在添加所需功能而不是使用 --privileged 方面犯错。

    【讨论】:

      【解决方案3】:

      a good article from RedHat covering this

      虽然以“root”身份运行的 docker 容器在主机上的权限低于 root,但根据您的用例(用作开发环境与共享生产集群),它仍可能需要强化。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-05-28
        • 2020-05-13
        • 2023-02-08
        • 2019-05-17
        • 1970-01-01
        • 1970-01-01
        • 2015-02-13
        • 1970-01-01
        相关资源
        最近更新 更多