在Docker容器中进行apk更新期间文件描述符描述符错误...为什么?

l3x*_*l3x 8 linux docker dockerfile devops alpine-linux

运行后:

docker network rm $NETNAME
docker network create --driver bridge $NETNAME --subnet "${SUBNET}0/24"
docker run --name $NODENAME -it --net $NETNAME --ip 192.168.0.2 --volume --detach $IMGNAME
Run Code Online (Sandbox Code Playgroud)

在容器中,以root身份运行apk udpdate

# apk update
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/main/x86_64/APKINDEX.tar.gz
ERROR: http://dl-cdn.alpinelinux.org/alpine/v3.7/main: Bad file descriptor
WARNING: Ignoring APKINDEX.70c88391.tar.gz: Bad file descriptor
fetch http://dl-cdn.alpinelinux.org/alpine/v3.7/community/x86_64/APKINDEX.tar.gz
ERROR: http://dl-cdn.alpinelinux.org/alpine/v3.7/community: Bad file descriptor
WARNING: Ignoring APKINDEX.5022a8a2.tar.gz: Bad file descriptor
2 errors; 33 distinct packages available
Run Code Online (Sandbox Code Playgroud)

...并击中Bad file descriptor错误。

还有许多其他人遇到相同的错误:

CDN似乎已关闭,无法使镜像工作#280

仓库问题?#279

有关如何解决此问题的建议,范围如下:

“这是一个DNS查找错误。只需将google DNS服务器(8.8.8.8、8.8.4.4)添加到Docker主机的守护进程配置文件中即可。”

... 至 ...

“将以下内容添加到您的Dockerfile:”

RUN echo http://mirror.yandex.ru/mirrors/alpine/v3.5/main > /etc/apk/repositories; \ echo http://mirror.yandex.ru/mirrors/alpine/v3.5/community >> /etc/apk/repositories

(你应该不要做。切勿从非官方的消息来源补充包)。

解决方案很容易。将这两行添加到您的RUN命令中:

rm -rf /var/cache/apk && \
mkdir /var/cache/apk && \
Run Code Online (Sandbox Code Playgroud)

在Dockerfile中...

RUN apk add --update --no-cache bash \
    git \
    make \
    clang \
    g++ \
    go && \
    mkdir -p $REPO && \
    mkdir -p $GODIR/src && \
    rm -rf /usr/share/man && \
    rm -rf /var/cache/apk && \
    mkdir /var/cache/apk && \
    apk del git clang
Run Code Online (Sandbox Code Playgroud)

添加删除和重新创建/var/cache/apk目录的命令就像被黑客入侵一样。

我的hack可以用,但是此错误的根本原因是什么?谁应该修复它?

小智 2

--no-cache选项允许不在本地缓存索引。这有助于保持容器较小。

另外,它相当于位于 apk update顶部和rm -rf /var/cache/apk/底部。

所以你可以尝试这样使用它:

RUN apk add --update --no-cache bash \
    git \
    make \
    clang \
    g++ \
    go && \
    mkdir -p $REPO && \
    mkdir -p $GODIR/src && \
    rm -rf /usr/share/man && \
    apk del git clang
Run Code Online (Sandbox Code Playgroud)