これは、なにをしたくて書いたもの?
Dockerではtmpfsをマウントすることができます。
前に似たようなエントリーを書いたことがあるのですが、なぜか「(起動後の)Dockerコンテナ内でマウントする」で終わっていました…。
今回は、コンテナ起動時に最初からtmpfsをマウントするようにしてみたいと思います。
Dockerコンテナでtmpfsをマウントする
Dockerのtmpfsに関するドキュメントはこちら。
Dockerコンテナでホスト側とストレージを共有するにはvolumeを使います。
volumeは主にコンテナ内のデータの永続化目的で使いますが、tmpfsでマウントした先に書き込んだ内容はホスト側のメモリーにのみ
保持され、コンテナが停止すると削除されます。
用途としては、メモリーにのみ保持しておきたい機密情報や、ディスクの代わりにメモリーを書き込み先によるパフォーマンスの向上目的
あたりが考えられます。
また、tmpfsマウントの制限は以下です。
- コンテナ間でマウントを共有することはできない
- Linux上でDockerを使用している場合のみ利用可能
- tmpfsに権限を設定すると、コンテナの再起動後に権限がリセットされることがある
tmpfs mounts / Limitations of tmpfs mounts
tmpfsをマウントする方法は2つあります。
--tmpfs
オプションでマウントする … 簡単に使用可能だが、tmpfsのオプションの指定が不可--mount
オプションでマウントする … 冗長な表現になるが、tmpfsのオプションの指定が可能
ここでいうtmpfsのオプションとは、以下の2つです。
- tmpfs-size … マウントするtmpfsのサイズをバイト単位で指定。デフォルトでは無制限
- tmpfs-mode … 8進数で表現されるtmpfsのファイルモード。
700
や0770
で指定し、デフォルトは1777
(誰でも書き込み可能)
tmpfs mounts / Use a tmpfs mount in a container / Specify tmpfs options
Docker Composeで使う場合は、こちらでの指定になります。
ここまで見たところで、試してみましょう。
環境
今回の環境はこちら。
$ docker version Client: Docker Engine - Community Version: 25.0.1 API version: 1.44 Go version: go1.21.6 Git commit: 29cf629 Built: Tue Jan 23 23:09:23 2024 OS/Arch: linux/amd64 Context: default Server: Docker Engine - Community Engine: Version: 25.0.1 API version: 1.44 (minimum version 1.24) Go version: go1.21.6 Git commit: 71fa3ab Built: Tue Jan 23 23:09:23 2024 OS/Arch: linux/amd64 Experimental: false containerd: Version: 1.6.27 GitCommit: a1496014c916f9e62104b33d1bb5bd03b0858e59 runc: Version: 1.1.11 GitCommit: v1.1.11-0-g4bccb38 docker-init: Version: 0.19.0 GitCommit: de40ad0
Docker Compose。
$ docker compose version Docker Compose version v2.24.2
Ubuntu Linux 22.04 LTS上のDockerです。
$ lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 22.04.3 LTS Release: 22.04 Codename: jammy $ uname -srvmpio Linux 5.15.0-92-generic #102-Ubuntu SMP Wed Jan 10 09:33:48 UTC 2024 x86_64 x86_64 x86_64 GNU/Linux
tmpfsを使ってDockerコンテナを起動してみる
では、tmpfsを使ってDockerコンテナを起動してみましょう。
--tmpfs
オプションを使用する場合。/app
ディレクトリにtmpfsをマウントしてみました。
$ docker container run -it --rm --name ubuntu --tmpfs /app ubuntu:22.04
dfで見ると、/app
がtmpfsとしてマウントされていることが確認できます。
# df -h Filesystem Size Used Avail Use% Mounted on overlay xxxG xxxG xxxG xxx% / tmpfs 64M 0 64M 0% /dev shm 64M 0 64M 0% /dev/shm tmpfs 7.8G 0 7.8G 0% /app /dev/sda8 xxxG xxxG xxxG xxx% /etc/hosts tmpfs 7.8G 0 7.8G 0% /proc/asound tmpfs 7.8G 0 7.8G 0% /proc/acpi tmpfs 7.8G 0 7.8G 0% /proc/scsi tmpfs 7.8G 0 7.8G 0% /sys/firmware tmpfs 7.8G 0 7.8G 0% /sys/devices/virtual/powercap
次に、--mount
オプションでtmpfsをマウントしてみます。
$ docker container run -it --rm --name ubuntu --mount type=tmpfs,destination=/app ubuntu:22.04
特にオプションを指定していないので、結果は同じです。
# df -h Filesystem Size Used Avail Use% Mounted on overlay xxxG xxxG xxxG xxx% / tmpfs 64M 0 64M 0% /dev shm 64M 0 64M 0% /dev/shm tmpfs 7.8G 0 7.8G 0% /app /dev/sda8 xxxG xxxG xxxG xxx% /etc/hosts tmpfs 7.8G 0 7.8G 0% /proc/asound tmpfs 7.8G 0 7.8G 0% /proc/acpi tmpfs 7.8G 0 7.8G 0% /proc/scsi tmpfs 7.8G 0 7.8G 0% /sys/firmware tmpfs 7.8G 0 7.8G 0% /sys/devices/virtual/powercap
では、オプションを指定してみましょう。今回はtmpfs-size
を指定して、マウントするtmpfsを100Mにしてみます。
$ docker container run -it --rm --name ubuntu --mount type=tmpfs,destination=/app,tmpfs-size=100M ubuntu:22.04
df -h
で見ると、/app
にマウントされているのが100Mになっていることが確認できます。
# df -h Filesystem Size Used Avail Use% Mounted on overlay xxxG xxxG xxxG xxx% / tmpfs 64M 0 64M 0% /dev shm 64M 0 64M 0% /dev/shm tmpfs 100M 0 100M 0% /app /dev/sda8 xxxG xxxG xxxG xxx% /etc/hosts tmpfs 7.8G 0 7.8G 0% /proc/asound tmpfs 7.8G 0 7.8G 0% /proc/acpi tmpfs 7.8G 0 7.8G 0% /proc/scsi tmpfs 7.8G 0 7.8G 0% /sys/firmware tmpfs 7.8G 0 7.8G 0% /sys/devices/virtual/powercap
試してみましょう。
50Mのファイルの作成。
# dd if=/dev/zero of=/app/file bs=1M count=50 50+0 records in 50+0 records out 52428800 bytes (52 MB, 50 MiB) copied, 0.020767 s, 2.5 GB/s # ll -h /app/file -rw-r--r-- 1 root root 50M Jan 28 11:35 /app/file
200Mのファイルの作成。
# dd if=/dev/zero of=/app/file bs=1M count=200 dd: error writing '/app/file': No space left on device 1+0 records in 0+0 records out 0 bytes copied, 0.000457989 s, 0.0 kB/s # ll -h /app/file -rw-r--r-- 1 root root 100M Jan 28 11:36 /app/file
こちらは容量が足りずに失敗することが確認できました。
OKですね。
実際の使い方としては、メモリーで扱える範囲になりますがMySQLのようなデータベースのストレージをtmpfsにして速度を上げると
いったこともあるのではないでしょうか。
$ docker container run -it --rm --name mysql --tmpfs /var/lib/mysql -e MYSQL_ROOT_PASSWORD=password mysql:8.0.36
Docker Composeでtmpfsを使う
最後は、Docker Composeでtmpfsを使ってみましょう。
こんな感じで指定します。
compose.yaml
services: mysql: image: mysql:8.0.36 environment: MYSQL_ROOT_PASSWORD: password tmpfs: /var/lib/mysql
起動はふつうに。
$ docker compose up
確認してみましょう。
$ docker compose exec mysql bash # df -h Filesystem Size Used Avail Use% Mounted on overlay xxxG xxxG xxxG xxx% / tmpfs 64M 0 64M 0% /dev shm 64M 0 64M 0% /dev/shm /dev/sda8 xxxG xxxG xxxG xxx% /etc/hosts tmpfs 7.8G 201M 7.6G 3% /var/lib/mysql tmpfs 7.8G 0 7.8G 0% /proc/asound tmpfs 7.8G 0 7.8G 0% /proc/acpi tmpfs 7.8G 0 7.8G 0% /proc/scsi tmpfs 7.8G 0 7.8G 0% /sys/firmware tmpfs 7.8G 0 7.8G 0% /sys/devices/virtual/powercap
OKですね。
以下のように、リスト形式で複数の指定もOKです。
services: mysql: image: mysql:8.0.36 environment: MYSQL_ROOT_PASSWORD: password tmpfs: - /var/lib/mysql
volumesで指定する場合は、こうなるようです。
compose.yaml
services: mysql: image: mysql:8.0.36 environment: MYSQL_ROOT_PASSWORD: password volumes: - type: tmpfs target: /var/lib/mysql tmpfs: size: 2G
tmpfs-size
の指定方法が最初わからなかったのですが、この記述でうまくいきました。
# df -h Filesystem Size Used Avail Use% Mounted on overlay xxxG xxxG xxxG xxx% / tmpfs 64M 0 64M 0% /dev shm 64M 0 64M 0% /dev/shm /dev/sda8 xxxG xxxG xxxG xxx% /etc/hosts tmpfs 2.0G 189M 1.9G 10% /var/lib/mysql tmpfs 7.8G 0 7.8G 0% /proc/asound tmpfs 7.8G 0 7.8G 0% /proc/acpi tmpfs 7.8G 0 7.8G 0% /proc/scsi tmpfs 7.8G 0 7.8G 0% /sys/firmware tmpfs 7.8G 0 7.8G 0% /sys/devices/virtual/powercap
これは、Composeファイルのバージョン3のリファレンスに記述がありました。
Compose file version 3 reference / Service configuration reference / tmpfs
現在のバージョンのドキュメントにはこの記述がないので、あまり使わない方がいいのかもしれません…。
tmpfs-mode
については記載がないですし…。
おわりに
Dockerでtmpfsをマウントするようにしてみました。
これができることをコロッと忘れていたりするのと、そもそもこのブログでも書いたのが通常使うであろう状況と全然違うものだったので、
あらためてまとめなおした感じですね。
ちゃんとドキュメントを見る機会にもなって良かったです。