使用 docker 和 --privileged 构建

Alq*_*qio 9 linux amazon-web-services docker dockerfile amazon-lex

我正在使用本指南使用 Amazon Lex 和 Raspberry Pi 构建语音套件,但我需要使用 Docker。问题是指南卷曲和运行的脚本需要访问 /dev/tty。我可以在运行docker 容器时授予对 /dev/tty 的访问权限,但是在构建容器时我不知道如何做到这一点。

我的 Dockerfile 看起来像这样:

FROM resin/rpi-raspbian

WORKDIR /app

ADD . /app

#The script requires these
RUN apt-get update
RUN apt-get install iputils-ping

#The script has to be run with sudo priviliges but not as root
USER root
ADD /sudoers.txt /etc/sudoers
RUN chmod 440 /etc/sudoers


RUN useradd -ms /bin/bash lex
RUN echo 'lex:test' | chpasswd

RUN curl https://get.pimoroni.com/phatdac | bash 

USER lex

EXPOSE 80

#Comment the last RUN command and uncomment this
#CMD curl https://get.pimoroni.com/phatdac | bash 
Run Code Online (Sandbox Code Playgroud)

当我尝试构建容器时

docker build -t raspi1 .
Run Code Online (Sandbox Code Playgroud)

它在脚本上崩溃,因为它无法访问 /dev/tty。

运行容器时,我可以使用此脚本授予对 /dev/tty 和 /dev/snd 的访问权限

#!/bin/sh

 docker run -ti --rm \
     -v /dev/snd:/dev/snd \
      --privileged \
     raspi7 
Run Code Online (Sandbox Code Playgroud)

然后尝试在启动时使用 Dockerfile 中的 CMD 脚本。但是如果我这样做,那么我每次运行时都需要使用脚本,并且我还需要在脚本完成后在其他东西上运行,这在构建时放在 Dockerfile 上会很好。

TLDR;构建docker镜像时如何向/dev/tty和/dev/snd授予权限?

Gre*_*reg 8

Docker 目前不支持公开设备,也不支持构建时的特权操作。

根据@cpuguy83,您现在正在做的事情 - 构建一个可移植的映像,无需访问主机并在容器首次启动时完成配置 - 是正确的做法:

在第一次容器启动时做这种事情正是正确的方法。这是一个运行时配置,不应该出现在图像中。

请参阅赏金来源

还有一个古老但仍然开放的moby问题。


小智 7

@Greg 提到的 moby问题已关闭。

现在可以使用以下命令构建具有特权的映像docker buildx

  1. Dockerfile参考)中,
    1. 在文件开头设置 Dockerfile 版本:
      # syntax=docker/dockerfile:1.3-labs
      
      Run Code Online (Sandbox Code Playgroud)
    2. --security=insecure选项添加到RUN需要特权操作的命令中:
      RUN somecommand
      
      Run Code Online (Sandbox Code Playgroud) 变成
      RUN --security=insecure somecommand
      
      Run Code Online (Sandbox Code Playgroud)
  2. 创建并使用docker-container 驱动程序来构建映像(参考):
    # syntax=docker/dockerfile:1.3-labs
    
    Run Code Online (Sandbox Code Playgroud)

但请注意,到目前为止,此方法有一些限制。docker-container 驱动程序无法访问docker image( ref ),因此 ref 引用的所有映像都FROM需要位于映像注册表中。为了使构建的图像对 可见docker image,您可能需要output在命令中添加该选项docker buildx build


mrf*_*red 1

您的问题可能是 /dev/snd 在您的 docker 映像中不存在。当您运行容器时,您实际上是在容器内安装主机操作系统 /dev/snd ,以便可以运行您的脚本。看看以下内容:

[INSERT] > cat Dockerfile
FROM resin/rpi-raspbian

RUN ls /dev && ls /dev/tty && ls /dev/snd


[INSERT] > docker build .
Sending build context to Docker daemon  39.94kB
Step 1/2 : FROM resin/rpi-raspbian
 ---> d008ca006edc
Step 2/2 : RUN ls /dev && ls /dev/tty && ls /dev/snd
 ---> Running in 0b738007c71c
core
fd
full
mqueue
null
ptmx
pts
random
shm
stderr
stdin
stdout
tty
urandom
zero
/dev/tty
/bin/ls: cannot access /dev/snd: No such file or directory
The command '/bin/sh -c ls /dev && ls /dev/tty && ls /dev/snd' returned a non-zero code: 2
Run Code Online (Sandbox Code Playgroud)

如您所见,/dev/tty 存在,并且您可以访问它。/dev/snd 不存在,并且您不在正在运行的容器内,因此您无法将其安装为卷(您在运行容器时正在执行此操作)。我建议尝试更全面地了解您正在运行的脚本正在做什么,评估它是否需要访问主机的 /dev/snd,如果是这样,您可能只在正在运行的容器内运行脚本,因为图像不需要对主机有任何概念。