为什么docker build在中间容器中运行命令,然后将其删除,导致该命令被忽略?

时间:2019-04-23 04:31:18

标签: docker dockerfile

由于种种原因,我无法确定将docker的默认名称服务器地址应用于Linux容器,导致无法解析外部地址。我试图通过在resolv.conf文件上使用sed命令来更新名称服务器地址,但是命令运行后,docker似乎会删除其上运行的映像,导致名称服务器未更新。

当docker build在我的Windows机器上创建Linux容器时,所得容器在resolv.conf中的名称服务器值为192.168.65.1。如此设置,我无法解决任何问题。我什至无法ping google.com。如果我将名称服务器更新为使用8.8.8.8的Google DNS,则可以ping其他主机并成功运行启动该问题的命令(dotnet还原)。

我建立了一个映像,将我的文件复制到/ src中,然后以交互方式运行它以尝试调试。我通过运行以下命令解决了问题

# copy resolv.conf because I can't run sed on it directly
RUN cp /etc/resolv.conf /etc/resolv.conf.temp
# make my change to the temp file
RUN sed -i 's/192.168.65.1/8.8.8.8/' /etc/resolv.conf.temp
# copy the modified file over original
RUN cp /etc/resolv.conf.temp /etc/resolv.conf    

在容器中交互运行,然后我可以成功地对src文件调用dotnet restore。

但是,当我在Dockerfile中包含这些指令并构建映像时,就会发生复制,sed命令会在临时文件中发生,并且似乎会发生copyover命令,但是生成的映像仍然具有原始的192.168.65.1名称服务器值。

在第二个cp之后添加此命令:

RUN cat /etc/resolv.conf

确认运行cat命令时,原始resolv.conf内容完整无缺。

以下是构建输出的相关部分:

Step 9/12 : RUN cp /etc/resolv.conf /etc/resolv.conf.temp
 ---> Running in cf8e037f5675
Removing intermediate container cf8e037f5675

 ---> 53f1c8bb86c6
Step 10/12 : RUN sed -i 's/192.168.65.1/8.8.8.8/' /etc/resolv.conf.temp
 ---> Running in 14b6a8381261
Removing intermediate container 14b6a8381261
 ---> 22039e11f812

Step 11/12 : RUN cp /etc/resolv.conf.temp /etc/resolv.conf
 ---> Running in 46d295d869bf
Removing intermediate container 46d295d869bf
 ---> ea1a18576f87

Step 12/12 : RUN cat /etc/resolv.conf
 ---> Running in 6cb4726e58cb
# This configuration is written to the config.iso
nameserver 192.168.65.1
search mycompany.local
domain mycompany.local
Removing intermediate container 6cb4726e58cb
 ---> 5ad060514a74
Successfully built 5ad060514a74

我希望从第10步和第11步开始,构建的图像将具有新的名称服务器值,但事实并非如此,看起来工作正在进行,但是中间图像已被丢弃,我不知道为什么以及什么正确的解决方法是。

2 个答案:

答案 0 :(得分:0)

可以通过将名称服务器传递给docker守护程序将其添加到docker容器中。

在文件/etc/docker/daemon.json中,将"dns":["172.16.3.241", "127.0.0.1", "8.8.8.8", "8.8.4.4"]或类似dns的{​​{1}}添加到docker daemon。

答案 1 :(得分:0)

您可以在构建容器映像后更改容器的DNS设置,请参见。 the Docker docs

最小示例:

Dockerfile:

FROM alpine

CMD ["cat", "/etc/resolv.conf"]

在同一文件夹中,运行:

docker build --tag foo . && docker run --rm --dns-search=foo.bar --dns=8.8.8.8 foo

输出将显示:

search foo.bar
nameserver 8.8.8.8