在Docker容器中无法执行二进制文件("操作不允许")

3

问题

我正在构建一个基于RHEL的Docker容器,其中包含来自第三方存储库的自定义二进制文件。在容器中执行该二进制文件时,我收到一个不明确的错误:“操作不允许”。

分析

Dockerfile

Dockerfile非常简单。

FROM dockerregistry.example.com/rhel7:latest

RUN yum -y install \
    curl \
    custom-package && \
    curl -Lsq https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64 > /sbin/dumb-init && \
    chmod 755 /sbin/dumb-init && \
    yum clean all

ADD custom-package.conf /etc/custom-package/custom-package.conf

ENTRYPOINT ["/sbin/dumb-init", "--"]
CMD ["/usr/local/custom-package/bin/custom-package", "--config", "/etc/custom-package/custom-package.conf"]

构建镜像

我在工作站上使用以下命令构建并进入容器。

$ docker build -t custom-package:v1 .
$ docker run --security-opt seccomp:unconfined -d custom-package:v1 tail -f /dev/null
$ docker exec -it <image ID> /bin/bash

“操作不允许”

当我进入镜像后,如果尝试执行二进制文件,则会收到非常无用的错误。运行strace也会给出混乱的输出。在检查文件权限和元数据时,它似乎是正常的。

# /usr/local/telegraf/bin/telegraf
bash: /usr/local/telegraf/bin/telegraf: Operation not permitted

# strace -f /usr/local/telegraf/bin/telegraf
execve("/usr/local/telegraf/bin/telegraf", ["/usr/local/telegraf/bin/telegraf"], [/* 17 vars */]) = -1 EPERM (Operation not permitted)
write(2, "strace: exec: Operation not perm"..., 38strace: exec: Operation not permitted
) = 38
exit_group(1)                           = ?
+++ exited with 1 +++

# ls -l /usr/local/telegraf/bin/telegraf    
-rwxr-xr-x 1 telegraf telegraf 38664736 Jun  3 15:41 /usr/local/telegraf/bin/telegraf

# getcap -v /usr/local/telegraf/bin/telegraf
/usr/local/telegraf/bin/telegraf = cap_sys_rawio+ep

我无法收集足够的信息来调试我的容器,也不知道为什么可执行二进制文件无法正常工作。是否有明显的错误或者原因导致我收到这样一个无用的错误提示?

谢谢!


问题中的信息不足以重现/回答。最多我们可以猜测一下?(这是一个ulimit问题吗?) - anthony sottile
@AnthonySottile 我能提供哪些信息以便更容易调试?最终,我并不希望修复这个包(我想这是我自己要做的事情),但我只是想获得更多有用的信息来进行调试。 - J.W.F.
1个回答

6

SYS_RAWIO权限需要使用--privileged选项才能访问设备。请参见capabilities(7)。

http://man7.org/linux/man-pages/man7/capabilities.7.html

   CAP_SYS_RAWIO
          * Perform I/O port operations (iopl(2) and ioperm(2));
          * access /proc/kcore;
          * employ the FIBMAP ioctl(2) operation;
          * open devices for accessing x86 model-specific registers (MSRs, see msr(4))
          * update /proc/sys/vm/mmap_min_addr;
          * create memory mappings at addresses below the value specified by /proc/sys/vm/mmap_min_addr;
          * map files in /proc/bus/pci;
          * open /dev/mem and /dev/kmem;
          * perform various SCSI device commands;
          * perform certain operations on hpsa(4) and cciss(4) devices;
          * perform a range of device-specific operations on other devices.

1
谢谢,这解决了问题,我能够顺利执行二进制文件。不过,我有一个快速跟进的问题 - 如果在生产环境中以提升的权限运行Docker容器,您是否预见到这可能会成为安全问题? - J.W.F.
3
你可以使用strace来查看它需要访问的设备,并通过--device参数传递设备,使用--cap-add选项添加sys_rawio能力(以及其他可能的能力)。最后,你可以使用AppArmor/SELinux和seccomp配置文件进一步加固它。 - Ricardo Branco

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接