OverlayFSは上側に重ねるファイルシステムがファイルタイプを返すd_typeをサポートしていないと使えません。d_typeをサポートしないファイルシステムでOverlayするとwhiteoutファイルをDT_CHRと判定できないため、消したはずのファイル(やディレクトリ)が中途半端に見えてしまいます。
実際にどうなるかというと
Dockerfile
FROM busybox
RUN mkdir /tmp/a; touch /tmp/a/b
RUN rm -rf /tmp/a
このDockerfileでコンテナイメージをdocker build
すると失敗します。
$ docker build -t amatsus/ovl-test .
Sending build context to Docker daemon 2.048 kB
Step 1 : FROM busybox
---> 63e6ca37d7f4
Step 2 : RUN mkdir /tmp/a; touch /tmp/a/b
---> Running in fb1dcc19fabb
---> e5cf048d5b44
Step 3 : RUN rm -rf /tmp/a
---> Running in 7a0b086ad4e9
rm: can't remove '/tmp/a': Directory not empty
The command '/bin/sh -c rm -rf /tmp/a' returned a non-zero code: 1
Btrfsやext2/3/4はd_typeをサポートしていますが、XFSもd_typeをサポートしています。ですが現時点ではデフォルトで有効になるディストリビューションは少ないと思います。d_typeを使えるようにするにはXFS v4フォーマットにFTYPEフィールドを付与するか、v5フォーマットでフォーマットします。
xfsprogs-3.2.0から3.2.2まで
# mkfs.xfs -n ftype=1 <device>
もしくは
# mkfs.xfs -m crc=1 <device>
xfsprogs 3.2.3以降ではcrc=1がデフォルトになったので、mkfs.xfsにオプションをつけずにv5でフォーマットするか、crc=0にした上でFTYPEフィールドを追加します。
xfsprogs-3.2.3以降
# mkfs.xfs <device>
もしくは
# mkfs.xfs -m crc=0 -n ftype=1 <device>
次のコマンドでFTYPEが有効であることを確認できます。
# xfs_db -r -c version /dev/mapper/centos-root
versionnum [0xb4b4+0x28a] = V4,ATTR,NLINK,ALIGN,DIRV2,LOGV2,EXTFLG,MOREBITS,ATTR2,LAZYSBCOUNT,PROJID32BIT,FTYPE
# xfs_info /var/lib/docker| grep ftype
naming =version 2 bsize=4096 ascii-ci=0 ftype=1
ちなみにFTYPEが有効でないときは
# xfs_db -r -c version /dev/mapper/centos-root
versionnum [0xb4b4+0x8a] = V4,ATTR,NLINK,ALIGN,DIRV2,LOGV2,EXTFLG,MOREBITS,ATTR2,LAZYSBCOUNT,PROJID32BIT
# xfs_info /var/lib/docker| grep ftype
naming =version 2 bsize=4096 ascii-ci=0 ftype=0
参考
- OverlayFS
https://www.kernel.org/doc/Documentation/filesystems/overlayfs.txt - overlayfs: Can't delete file moved from base layer to newly created dir even on ext4 #9572
https://github.com/docker/docker/issues/9572#issuecomment-218201293 - ovl: Ensure upper filesystem supports d_type
https://github.com/torvalds/linux/commit/45aebeaf4f67468f76bedf62923a576a519a9b68