Failed to Extract Layer
Errors
FATA[0006] failed to extract layer sha256:d2d4d2c16a00dd998866a33049d4a1801ba34b719f377ffdf3ec7ae78c9b03eb: lstat /var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/566/fs/var/cache/dnf/update-e8b0d229956b0b0b: not a directory: unknown
Dockerfile
FROM registry.example.com/openeuler:22.03-lts-sp2
WORKDIR /app
RUN mkdir -p /etc/nginx/html/foo/
RUN rm -rf /var/cache/dnf/*
RUN sed -i 's|http://repo.openeuler.org/|https://mirrors.huaweicloud.com/openeuler/|g' /etc/yum.repos.d/openEuler.repo && yum clean all -y && dnf clean all -y
RUN yum update -y && yum install -y nginx libXau
RUN mkdir -p /etc/nginx/html/foo/
COPY dist /etc/nginx/html/foo
使用 nerdctl(基于 containerd)时报错,而 docker 没问题,通常是因为 Docker 和 containerd 处理文件系统(snapshotter)方式不同。
1. 主要区别:overlayfs 处理方式不同
- Docker 默认使用
overlay2作为存储驱动,对rm -rf的兼容性较好。 - containerd(nerdctl)默认使用
overlayfs作为 snapshotter,在某些情况下,rm -rf可能会破坏dnf依赖的目录结构,导致lstat失败。
影响:
dnf可能在/var/cache/dnf/update-*目录创建了符号链接或特殊 inode,直接rm -rf可能会让 containerd 误认为 某个目录已损坏或变成非法文件。- Docker 的
overlay2可能对这个情况做了额外的处理,所以不会报错。
containerd 的 overlayfs 可能会在某些情况下导致 lstat 失败,表现为:
lstat /var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/snapshots/XXX/fs/var/cache/dnf/update-*: not a directory: unknown
2. 解决方案
方法 1:避免 rm -rf /var/cache/dnf/*
把 rm -rf /var/cache/dnf/* 替换为官方推荐的 dnf clean all:
RUN dnf clean all
或者:
RUN yum clean all -y && rm -rf /var/cache/dnf
dnf clean all 会正确清理缓存文件,而不会误删关键目录。
方法 2:强制 containerd 使用 overlay2
如果你的 containerd 运行时允许,你可以尝试强制使用 overlay2 作为 snapshotter:
sudo systemctl stop containerd
sudo sed -i 's/overlayfs/overlay2/' /etc/containerd/config.toml
sudo systemctl restart containerd
然后重新构建镜像:
nerdctl build -t my-nginx-image .
WARNING
overlay2 可能并不是所有 containerd 版本的默认选项,请检查 containerd config.toml 是否支持。
方法 3:使用 devicemapper 作为 snapshotter
如果 overlay2 方案不可行,可以改用 devicemapper:
sudo sed -i 's/overlayfs/devmapper/' /etc/containerd/config.toml
sudo systemctl restart containerd
3. 结论
- Docker(overlay2)可以容忍
rm -rf误删目录,但containerd(overlayfs)可能不行。 - 最好的做法是避免
rm -rf /var/cache/dnf/*,用dnf clean all替代。 - 如果你必须用
rm -rf,可以尝试改用overlay2或devicemapper作为 containerd 的 snapshotter。 - 在
containerd中,dnf运行时可能会依赖/var/cache/dnf/结构,删除后会导致lstat失败。
建议你先尝试 方法 1(改用 dnf clean all),如果仍然有问题,再考虑切换 snapshotter(方法 2 或 3)。
No comments to display
No comments to display