Docker build --ulimit标志无效

时间:2018-09-20 06:11:56

标签: docker ulimit

我的Docker构建由于文件句柄限制错误而失败。他们以

崩溃

Error: EMFILE: too many open files

当我在看到的容器上检查ulimit -n时

-n: file descriptors 1024

所以我将以下标志传递给我的构建命令

docker build --ulimit nofile=65536:65536 -t web .

但这没有任何改变,我的容器仍然显示

-n: file descriptors 1024

无论我做什么,似乎都无法更改ulimit文件描述符的限制。

我在这里做什么错了?

3 个答案:

答案 0 :(得分:4)

因此,我找到了原因。发布答案,以防其他人遇到与我一天大部分时间都在浪费的相同问题。 我一直在调试一个运行时间很长的构建,并一直在使用

export DOCKER_BUILDKIT=1

启用一些扩展的构建信息。时间安排非常有用,尽管看起来好像启用DOCKER_BUILDKIT完全忽略了传递给docker build命令的ulimit标志。
当我设置

export DOCKER_BUILDKIT=0

有效。长话短说,避免将buildkit与ulimit参数一起使用

答案 1 :(得分:2)

我写了一个简单的测试,它可以在Docker 18.06上正常工作

> $ docker -v
Docker version 18.06.1-ce, build e68fc7a

我这样创建了一个Dockerfile

FROM alpine
RUN ulimit -n > /tmp/ulimit.txt

然后:

> $ docker build --ulimit nofile=65536:65536 .
Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM alpine
 ---> e21c333399e0
Step 2/2 : RUN ulimit -n > /tmp/ulimit.txt
 ---> Running in 1aa4391d057d
Removing intermediate container 1aa4391d057d
 ---> 18dd1953d365
Successfully built 18dd1953d365

docker run -ti 18dd1953d365 cat /tmp/ulimit.txt
65536

> $ docker build --ulimit nofile=1024:1024 --no-cache .
Sending build context to Docker daemon  2.048kB
Step 1/2 : FROM alpine
 ---> e21c333399e0
Step 2/2 : RUN ulimit -n > /tmp/ulimit.txt
 ---> Running in c20067d1fe10
Removing intermediate container c20067d1fe10
 ---> 134fc7252574
Successfully built 134fc7252574

> $ docker run -ti 134fc7252574 cat /tmp/ulimit.txt
1024

答案 2 :(得分:0)

使用BuildKit时,docker似乎在具有ulimit的守护程序的systemd单元上下文中执行命令。

我用Dockerfile进行了测试:

> cat <<EOF >Dockerfile
FROM alpine
RUN echo -e "\n\n-----------------\nulimit: $(ulimit -n)\n-----------------\n\n"
EOF

首先检查docker服务的实际极限值:

> systemctl show docker.service | grep LimitNOFILE
LimitNOFILE=infinity
LimitNOFILESoft=infinity

正在运行的容器中设置的值为1048576

> docker run -it --rm alpine sh -c "ulimit -n"
1048576

在BuildKit内部版本中设置的值为1073741816

> DOCKER_BUILDKIT=1 docker build --progress=plain --no-cache .
#2 [internal] load build definition from Dockerfile
#2 transferring dockerfile: 195B done
#2 DONE 0.0s

#1 [internal] load .dockerignore
#1 transferring context: 2B done
#1 DONE 0.0s

#3 [internal] load metadata for docker.io/library/alpine:latest
#3 DONE 0.0s

#5 [1/2] FROM docker.io/library/alpine
#5 CACHED

#4 [2/2] RUN echo -e "\n\n-----------------\nulimit: $(ulimit -n)\n--------...
#4 0.452
#4 0.452
#4 0.452 -----------------
#4 0.452 ulimit: 1073741816
#4 0.452 -----------------
#4 0.452
#4 0.452
#4 DONE 0.5s

#6 exporting to image
#6 exporting layers 0.0s done
#6 writing image sha256:facf7aee0b81d814d5b23a663e4f859ec8ba54d7e5fe6fdbbf8beacf0194393b done
#6 DONE 0.0s

将docker.service配置为设置另一个默认值(LimitNOFILE = 1024),该默认值也将由BuildKit使用(请注意不要覆盖现有文件):

> mkdir -p /etc/systemd/system/docker.service.d
> cat <<EOF >/etc/systemd/system/docker.service.d/service.conf.ok
[Service]
LimitNOFILE=1024
EOF
> systemctl daemon-reload
> systemctl restart docker.service

在运行容器中设置的值保持不变,为1048576

> docker run -it --rm alpine sh -c "ulimit -n"
1048576

现在BuildKit构建中设置的值是1024

> DOCKER_BUILDKIT=1 docker build --progress=plain --no-cache .
#2 [internal] load build definition from Dockerfile
#2 transferring dockerfile: 195B done
#2 DONE 0.0s

#1 [internal] load .dockerignore
#1 transferring context: 2B done
#1 DONE 0.0s

#3 [internal] load metadata for docker.io/library/alpine:latest
#3 DONE 0.0s

#5 [1/2] FROM docker.io/library/alpine
#5 CACHED

#4 [2/2] RUN echo -e "\n\n-----------------\nulimit: $(ulimit -n)\n--------...
#4 0.452
#4 0.452
#4 0.452 -----------------
#4 0.452 ulimit: 1024
#4 0.452 -----------------
#4 0.452
#4 0.452
#4 DONE 0.5s

#6 exporting to image
#6 exporting layers 0.0s done
#6 writing image sha256:7e40c8a8d5f0ca8f2b2b53515f11f47655f6e1693ffcd5f5a118402c13a44ab4 done
#6 DONE 0.0s