如何在基于Alpine的dockerfile中使用超时?

时间:2019-10-31 18:22:50

标签: docker timeout alpine

上下文

我正在编写一个dockerfile,其中我基于alpine:3.9 docker镜像运行服务器应用程序。我通过运行应用程序并使用GET发送curl请求来测试我的应用程序是否正确安装。

我发送请求,直到得到答案。因此,万一遇到麻烦,我想使用内置的timeout函数使测试超时。

先决条件

我在debian上使用docker version 19.03.4, build 9013bf583a

问题

命令:

docker run --rm -it alpine:3.9 timeout -t 2 /bin/sh -c 'sleep 5; echo "Not to be seen..."'

退出显示Not to be seen...

如果我以这种方式使用超时,则超时似乎被忽略了……如果将其放入docker文件中,也会遇到同样的问题。

FROM alpine:3.9
RUN timeout -t 2 /bin/sh -c 'sleep 5; echo "Not to be seen..."'
docker build -t test .

Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM alpine:3.9
 ---> 055936d39205
Step 2/2 : RUN timeout -t 2 /bin/sh -c 'sleep 5; echo "Not to be seen..."'
 ---> Running in 0fa22cd02173
Not to be seen...
Removing intermediate container 0fa22cd02173
 ---> e88107c3811b
Successfully built e88107c3811b
Successfully tagged test:latest

我们可以看到控制台中显示的Not to be seen...

如何解决此问题?

反思/测试

我测试了多件事,并且超时功能运行良好。在dockerfile中使用它或在docker run函数中传递它时应该有问题...


当我尝试:

docker run --rm -it alpine:3.9 /bin/sh
# Then in container
timeout -t 2 /bin/sh -c 'sleep 5; echo "Not to be seen..."'

退出,状态码为143。并显示Terminated


当我尝试:

docker run --rm --name test -td alpine:3.9 /bin/sh
docker exec -it test timeout -t 2 /bin/sh -c 'sleep 5; echo "Not to be seen..."'

退出,状态码为143。未按预期显示任何内容。

3 个答案:

答案 0 :(得分:1)

在dockerfile上下文中,可以使用https://github.com/krallin/tini工具解决pb。

使用以下Dockerfile:

FROM alpine:3.9
RUN apk add --no-cache tini
RUN /sbin/tini timeout -t 2 /bin/sh -c 'sleep 5; echo "Not to be seen..."'

执行docker build .

结果

Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM alpine:3.9
 ---> 055936d39205
Step 2/3 : RUN apk add --no-cache tini
 ---> Running in 018e342caa67
fetch http://dl-cdn.alpinelinux.org/alpine/v3.9/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.9/community/x86_64/APKINDEX.tar.gz
(1/1) Installing tini (0.18.0-r0)
Executing busybox-1.29.3-r10.trigger
OK: 6 MiB in 15 packages
Removing intermediate container 018e342caa67
 ---> 915c3d5dc7fe
Step 3/3 : RUN /sbin/tini timeout -t 2 /bin/sh -c 'sleep 5; echo "Not to be seen..."'
 ---> Running in 3852a4f6a43d
The command '/bin/sh -c /sbin/tini timeout -t 2 /bin/sh -c 'sleep 5; echo "Not to be seen..."'' returned a non-zero code: 143

如图所示,构建已停止,代码为143。

该解决方案使用外部工具强加。如果有更直接的解决方案,请随时提出。

PS:感谢@Eduardo Baitello将我设置在正确的路径上:)

答案 1 :(得分:0)

许多程序以PID 1(包括/bin/sh)的身份运行时会丢弃默认信号处理程序。

您需要使用--init标志以使容器正确退出:

  

-init在容器内运行一个初始化程序,以转发信号并获取进程

这应该有效:

docker run --rm -it --init alpine:3.9 timeout -t 2 /bin/sh -c 'sleep 5; echo "Not to be seen..."'

答案 2 :(得分:0)

Dockerfile 中的超时选项,可以在 Dockerfile 中直接为命令嵌入 timeout <value>

例如:

ARG GOLANG=golang:1.16.4-alpine3.12
FROM ${GOLANG}
RUN timeout 60 curl -sL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh```