Dockerで使用されているOverlay Filesystemとは

# はじめに

前回までは、Dockerのネットワークの仕組みについて勉強しました。今回はDockerで使用されているOverlayFS(Overlay Filesystem)の概念を理解していきたいと思います。

https://qiita.com/ymktmk/items/0234e54abd16d3a4f029

https://qiita.com/ymktmk/items/63c56deec99ecdfe94fb

## OverlayFSとは

OverlayFSは、Linuxカーネルに実装された、複数のファイルシステムを組み合わせて1つの論理的なファイルシステムを構成するための仕組みです。OverlayFSを使うと、複数のファイルシステムを上から重ね合わせることができます。そのため、OverlayFSを使用すると、例えば、書き込み可能なファイルシステムと読み取り専用のファイルシステムを組み合わせることで、書き込み可能なファイルシステムの上に、読み取り専用のファイルシステムを重ねることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1295942/890cd77e-21ff-7efc-d68d-d630bee765ea.png)

Ref: https://docs.docker.jp/storage/storagedriver/overlayfs-driver.html


Dockerfileを記述する際に「レイヤの数を最小にする」といったベストプラクティスを聞いたことはありませんか？その理由は、1つ手順で1つのレイヤが追加され、レイヤ構造はコンテナの実行時にも保持されることでイメージのビルドや実行が遅くなるからです。

```dockerfile
FROM ubuntu:18.04
COPY . /app
RUN make /app
CMD python /app/app.py
```

https://docs.docker.jp/develop/develop-images/dockerfile_best-practices.html

## OverlayFSのレイヤー概念

「work」・・・内部的に利用される作業用ディレクトリです。
「lower」・・・読み取り専用。仮想ディレクトリとして用いられます。
「upper」・・・書き込み可能。あらゆる変更は、このディレクトリに対して書き込まれます。
「merged」・・・lowerとupperdを結合したもの。ファイルに対して追加・変更・削除などの操作を行うディレクトリです。

## OverlayFSを確認

実際に手を動かしながらOverlayFSがどういった動きをするのか確認していきます。

### 準備

ディレクトリとファイル作成、マウントの設定を行います。

```
mkdir work lower01 lower02 upper merged
```

```
echo "hoge" > lower01/hoge.txt
echo "fuga" > lower02/fuga.txt
```

```
sudo mount -t overlay overlay -o lowerdir=lower02:lower01,upperdir=upper,workdir=work merged
```

以下の通りになればOKです。

```
.
├── merged
│　　　　　　├── fuga.txt(fuga)
│   └── hoge.txt(hoge)
├── upper
├── lower02
│   └── fuga.txt(fuga)
└── lower01
    └── hoge.txt(hoge)
```

### 新規ファイルの追加

mergedディレクトリにpiyo.txtを追加し、ファイルが追加されていることがわかります。

```console
$ echo piyo > merged/piyo.txt
```

```console
$ ls merged
fuga.txt  hoge.txt  piyo.txt
```

```console
$ ls upper
piyo.txt
```

実際に追加したファイルはupperディレクトリにあります。**追加したファイルはupperに反映されることがわかりました！**

```
.
├── merged
│　　　　　　├── fuga.txt(fuga)
│   ├── hoge.txt(hoge)
│   └── piyo.txt(piyo)
├── upper
│   └── piyo.txt(piyo)
├── lower02
│   └── fuga.txt(fuga)
└── lower01
    └── hoge.txt(hoge)
```

### ファイルの更新

mergedディレクトリのfuga.txtの中身をfuga2に変更してみます。

```console
$ echo fuga2 > merged/fuga.txt
```

```console
$ cat merged/fuga.txt
fuga2
```

```console
$ cat upper/fuga.txt
fuga2
```

以下のように動作することが分かりました。

1. mergedのfuga.txtの内容をfuga2に変更
2. lowerのfuga.txtをupperにコピー
3. コピーされたupperのfuga.txtの内容をfuga2に変更
4. mergedのfuga.txtの内容がfuga2に変更


```
.
├── merged
│　　　　　　├── fuga.txt(fuga2)
│   ├── hoge.txt(hoge)
│   └── piyo.txt(piyo)
├── upper
│   ├── fuga.txt(fuga2)
│   └── piyo.txt(piyo)
├── lower02
│   └── fuga.txt(fuga)
└── lower01
    └── hoge.txt(hoge)
```

### ファイルの削除

mergedディレクトリのhoge.txtを削除します。

```console
$ rm merged/hoge.txt
```

```console
$ ls merged
fuga.txt  piyo.txt
```

```console
$ ls upper
fuga.txt  hoge.txt  piyo.txt
```

以下のように動作することが分かりました。

1. mergedのhoge.txtを削除する
2. lowerのhoge.txtをupperにコピー

```
.
├── merged
│　　　　　　├── fuga.txt(fuga2)
│   └── piyo.txt(piyo)
├── upper
│   ├── fuga.txt(fuga2)
│   ├── hoge.txt(hoge)
│   └── piyo.txt(piyo)
├── lower02
│   └── fuga.txt(fuga)
└── lower01
    └── hoge.txt(hoge)
```

# さいごに

OverlayFSがどういった動きをするか確認しました。次回はDockerにてOverlayFSがどのように用いられているか確認していきたいと思います。