为什么我无法获得由docker build创建的文件尾部的输出

时间:2017-03-05 22:29:13

标签: docker dockerfile

Docker信息:

Containers: 18
 Running: 18
 Paused: 0
 Stopped: 0
Images: 188
Server Version: 1.13.1
Storage Driver: overlay2
 Backing Filesystem: extfs
 Supports d_type: true
 Native Overlay Diff: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins: 
 Volume: local
 Network: bridge host macvlan null overlay
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Init Binary: docker-init
containerd version: aa8187dbd3b7ad67d8e5e3a15115d3eef43a7ed1
runc version: 9df8b306d01f59d3a8029be411de015b7304dd8f
init version: 949e6fa
Security Options:
 seccomp
  Profile: default
Kernel Version: 4.9.0-1-amd64
Operating System: Debian GNU/Linux 9 (stretch)
OSType: linux
Architecture: x86_64
CPUs: 4
Total Memory: 15.56 GiB
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
WARNING: No swap limit support
Experimental: false
Insecure Registries:
   127.0.0.0/8
Live Restore Enabled: false

Docker版本:Docker version 1.13.1, build 092cba372

我有这个泊坞文件:

FROM debian:latest
RUN touch /var/log/mylog.log
CMD ["tail", "-F", "/var/log/mylog.log"]

使用docker build . -t test/test构建它并使用docker run -ti test/test运行它会在stdout中拖尾文件(忽略尾警告):

$ docker run --name test -t test/test
tail: unrecognized file system type 0x794c7630 for '/var/log/mylog.log'.   please report this to bug-coreutils@gnu.org. reverting to polling

执行以下命令将写入文件/var/log/mylog.log,该文件后面跟着tail

docker exec -ti test bash -c "echo 'asd' >> /var/log/mylog.log"

不幸的是,即使cat显示文件中有内容,其他终端也没有输出:

$ docker exec -ti test bash -c "cat /var/log/mylog.log"
asd

虽然,如果我使用PID1创建文件而不是在dockerfile中创建它,我会看到带尾部的文件内容。 如果我docker stop test && docker start test使用之前的命令,我也可以获得尾部的内容。

到底发生了什么?在docker build中创建文件与live容器中的运行脚本有什么不同吗?

2 个答案:

答案 0 :(得分:6)

我在Docker SELECT student.studentFirstName, student.studentLastName, test.test_results FROM student, test WHERE student.studentID = test.studentID AND test_results > (SELECT AVG(test_results) FROM test); Alpine版本上使用SELECT student.studentFirstName, student.studentLastName, test.test_results FROM student INNER JOIN test ON student.id = test.id WHERE test_results >( SELECT AVG(test.test_results) FROM test); 存储驱动程序时出现同样的问题。

似乎overlay2正在打开4.9.8-moby创建的覆盖图层中的CMD tail文件。

当你追加到日志时,一个" new"文件是在最顶层的覆盖层中创建的,容器用于在运行时对图像顶部进行的任何文件系统更改,并且实际上正在附加此新文件。 /var/log/mylog.log无法使用RUN touch /var/log/mylog.logtail正确选择转换。

-f-F解决了问题,docker start进程在docker stop更新后再次启动,然后指向" new&#34 ;文件在容器覆盖层中。使用略有不同的tail会以类似的方式解决问题:

/var/log/mylog.log

CMD图像包含coreutils-8.26-2,其中包含用于支持叠加幻数的修复,以删除该警告消息,但仍然表现出相同的行为。

最有可能是在内核中修复的重叠问题。使用CMD ["sh", "-c", "touch /var/log/mylog.log && tail -f /var/log/mylog.log"] 时,coreutils可能会解决此问题。

你正在尝试的是Docker中的一个边缘案例。使用debian:testing作为前台进程的容器通常在运行-F之前在脚本中完成大量工作,其中包括运行创建要挂起的日志文件的命令。可能是为什么很多人都没有选择这个。

答案 1 :(得分:2)

您的CMD json语法无效,您缺少coma。否则,它在我的环境中工作正常:

$ cat df.tail
FROM debian:latest
RUN touch /var/log/mylog.log
CMD ["tail", "-F", "/var/log/mylog.log"]

$ docker build -t test-tail -f df.tail .
Sending build context to Docker daemon 265.7 kB
Step 1/3 : FROM debian:latest
 ---> 7b0a06c805e8
Step 2/3 : RUN touch /var/log/mylog.log
 ---> Using cache
 ---> 412295d58dc8
Step 3/3 : CMD tail -F /var/log/mylog.log
 ---> Using cache
 ---> d7e9c7fee4a0
Successfully built d7e9c7fee4a0

$ docker run -t --rm --name test-tail test-tail
asd
^C
$

在第二个窗口中,这是在上面的docker run命令之后运行的:

$ docker exec test-tail bash  -c "echo 'asd' >> /var/log/mylog.log"