overlayfsとDockerの関係性(実装も少しだけ見てみる記事)

![Q9jiI1pL_400x400.jpg](https://qiita-image-store.s3.amazonaws.com/0/258841/0608637e-ec2d-ede2-f9f8-1ecae7bfbfb9.jpeg)

## 改版履歴的なの

2018/09/30 初版
2018/11/15 誤字修正
2018/12/23 情報追記
2019/02/17 実行例追記

## 背景

namespaceとcgroupsの概要的なものは調べたので残りの主要機能であるoverlayfsについてまとめた記事です。
誤り等ありましたらご指摘ください。
ホントにふわっとした理解だけなので詳しい情報は公式リファレンスなどをご参照ください。

## Dockerとは

一言でいえばコンテナ型の仮想化ツールです。
Dockerはコンテナを作成するために種々のLinuxが持つ機能を利用しており、主要なものとして以下の3つがよく挙げられます。

* overlayfs
* namespaces
* cgroups

今回はこの中のoverlayfsについて掘り下げて行こうと思います。

## Overlayfsとは

overlayfsはnamespaceやcgryoups同様コンテナ専用として使う機能ではありません。
overlayfsはunion filesystemの実装の1つで，ディレクトリを重ね合わせて1つのディレクトリツリーが構成できます。
コンテナイメージの差分管理に一躍買っている。
overlayfsは3.18カーネルでマージされています。

* overlayfsは上の層と下の層をマージして1つのファイルシステムに見せる仕組み
* ディレクトリだけマージするが、その他のファイルは単純に上だけが見える。上がない場合は下が見える
* このマージは、statやreaddirなどのシステムコールの値を何と報告するかを適切に調整することにより行われる
* 下の層はReadonly、上の層はReadonly/Writableどちらでも良い
* Readonlyの層はNFSや別のoverlayfsでも良い

## UnionFileSystemとは

UnionFS は Linux と FreeBSD 向けのファイルシステムサービスであり、複数の異なるファイルシステム (ブランチと呼ばれる) のファイルやディレクトリ同士を透過的に重ねる (マージする) ことができる技術のこと

## aufsとは

Linux のファイルシステムサービスであり、複数の異なるファイルシステム (ブランチと呼ばれる) のファイルやディレクトリ同士を透過的に重ねる (マージする) ことができる技術のこと
色々調べているとaufsも関連しそうな領域のようです。
が今回は触れません。基本的には使われていないと考えている為です。

記事としては以下が参考になりました(ただ使えないわけではないようなので調査が必要になったらまとめようかな)。
[Docker = AUFSという図式はもう忘れたほうがいいかもしれない、あるいはDockerとストレージドライバの話](https://qiita.com/DQNEO/items/ee0caf80b056487cb762)

## overlayfsを使ってみる

下記のような構成のディレクトリツリーを作成します。

``` bash
$ mkdir upperdir
$ mkdir lowerdir
$ mkdir mergedir
$ echo "upper" >> upperdir/fileA
$ echo "upper" >> upperdir/only_upper
$ echo "lower" >> lowerdir/fileB
$ echo "lower" >> lowerdir/only_lower

rootdir
|
|- lowerdir/
|   |- tqq fileB
|   |_ only_lower
|- upperdir/
|   |- fileA
|   |_ mqq only_upper
|- mergedir/

# only_upper: 上のみに存在するファイル
# only_lower: 下のみに存在するファイル
```

``` bash
$ sudo mount -t overlay overlay -o lowerdir=lowerdir,upperdir=upperdir,workdir=work mergedir

[root@zeus overlayfs]# sudo mount -t overlay overlay -o lowerdir=lowerdir,upperdir=upperdir,workdir=work mergedir

$ df mergedir
Filesystem               1K-blocks      Used  Available Use% Mounted on
overlay                   52403200   3261824   49141376   7% /root/work/overlayfs/mergedir

$ ls -l mergedir/
total 16
-rw-r--r--. 1 root root 6 Feb 17 20:46 fileA
-rw-r--r--. 1 root root 6 Feb 17 20:46 fileB
-rw-r--r--. 1 root root 6 Feb 17 20:46 only_lower
-rw-r--r--. 1 root root 6 Feb 17 20:46 only_upper
```

上記の時点でmergedirにどちらのファイルも存在していることが確認できます。
ここで両方に同じファイルを作成して挙動を見てみます。

``` bash
ls -l mergedir/
total 20
-rw-r--r--. 1 root root 6 Feb 17 20:46 fileA
-rw-r--r--. 1 root root 6 Feb 17 20:46 fileB
-rw-r--r--. 1 root root 6 Feb 17 20:58 fileC
-rw-r--r--. 1 root root 6 Feb 17 20:46 only_lower
-rw-r--r--. 1 root root 6 Feb 17 20:46 only_upper
```

fileCが透過的に一つのファイルとして見えています。

## overlayfsとDocker

overlayfsがイメージやコンテナの管理に大きく関わっています。
Dockerでいうイメージレイヤがlowdirでコンテナレイヤがupperdir。
コンテナマウントはoverlayfsから見えた結果というイメージです。

下図がDockerイメージレイヤとコンテナレイヤの構造の概要です。
イメージレイヤは下位ディレクトリとして構成されており、コンテナレイヤが上位ディレクトリです。

![overlay-construct.png](https://qiita-image-store.s3.amazonaws.com/0/258841/d38b5465-aafe-df4f-5077-5fe8ca87b3c6.png)
公式ドキュメントより引用

コンテナのファイルシステム関連の内容ですがホストOS上で以下のように配置されています。

``` bash
$ ls -l /var/lib/docker/overlay2 | head -n5
合計 1080
drwx------ 4 root root  4096 12月  1 15:53 02847b2115f435552f94d693ed3f041eb6467269756567dfcc18e42cb76d80b7
drwx------ 4 root root  4096  1月 10 21:12 02e8e4fbf430d5d3666d4a08e9c880c5af260f7378adf13868595d696f9cd415
drwx------ 4 root root  4096 12月  1 15:53 04ff3b7540486f64dc50d5687234c7108b0b3d87d848b7c3f6370a2ec98a79e5
drwx------ 4 root root  4096  1月 13 14:20 0661aa841ea4b7f829e6475cc060ff5d85f2a67ad55dde540f9cf2800049550d
```

/var/lib/docker/overlay2/<container id> にコンテナのファイルシステムに関連するものがまとまっています。

``` bash
ls -l /var/lib/docker/overlay2/f4b0c20f0dee750c9488368d744021866ab5e8b406923f67c55555c56a663f62
合計 20
drwxr-xr-x 6 root root 4096 12月  1 21:48 diff
-rw-r--r-- 1 root root   26 12月  1 21:48 link
-rw-r--r-- 1 root root  318 12月  1 21:48 lower
drwxr-xr-x 1 root root 4096 12月  1 21:48 merged
drwx------ 3 root root 4096 12月  1 21:23 work
```

ディレクトリの構成は大まかに下記のような仕組みとなっています。

* diff がupperdir
* lower がlowerdir
* work がworkdir

## Dockerのストレージドライバ

現在Dockerでストレージドライバとして利用できるものは以下です。
デフォルトではoverlay2が使用されており最近の記事だとoverlay2以外に関する記事はあまり見られません
(みつけられて無いだけの可能性もあります。。。)

| ストレージドライバ | サポートファイルシステム |
| --- | --- |
| overlay2, overlay | xfs, ext4 |
| devicemapper | direct-lvm |
| aufs | xfs, ext4 |
| btrfs | btrfs |
| zfs | zfs |
| vfs | その他ファイルシステム |

自分の環境で使用しているストレージドライバの確認は```docker info```コマンドのStorage Driver欄で確認できます。

``` bash
$ docker info | grep Storage
Storage Driver: overlay2
```

## 終わりに

overlayfsの概要までを掴んで見るための記事でした。
Dockerのストレージドライバとしてはそのシーンで都度検討が必要であると思います。
/var/lib/docker配下がどのように構成されているかを知るのはdockerを学ぶ上でも大事なことだと思うので
この記事が少しでも役立てていただけたら幸いです。

## 参考記事

[OverlayFS ストレージの使用](http://docs.docker.jp/engine/userguide/storagedriver/overlayfs-driver.html)
[Docker技術入門](https://blog.tiqwab.com/2017/02/18/docker-technology.html)
[Dockerのストレージドライバを理解する](https://qiita.com/NaotoHanaue/items/b9f395a63f7aae2a41b7)