我的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文件描述符的限制。
我在这里做什么错了?
答案 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