なぜ匿名ボリュームが増えるのか?実際に遭遇したトラブルから学ぶDockerのデータ保存

 

はじめに

4月に未経験からエンジニアになったボンコハラです。日々分からないことを調べながら、開発に携わっています。
今回は、私が開発を進める中で実際に遭遇した「ランダム文字列のような名前のボリュームがどんどん増えていく」という現象について書いていきます。原因を調べていくうちに、Dockerのボリュームの仕組みや、だけでなくまで確認することの大切さを学ぶことができました。
私と同じようにDockerを触り始めたばかりの方や、ボリューム周りでモヤモヤした経験のある方の参考になれば嬉しいです。なお、Docker全体の仕組みそのものについては、話が大きくなりすぎてしまうため、次回以降の記事で改めて説明する予定です。今回は「匿名ボリュームがなぜ増えるのか」という一点に絞ってお伝えします。

実際に遭遇した現象

私が担当していた開発環境では、にバインドマウントを設定していました。そのため、私はずっと「この環境で使っているボリュームはこれだけだ」と思い込んでいました。
ところが、ある日なんとなくを実行してみたところ、次のような内容が表示されました。
見覚えのない、意味のわからない長いランダムな名前のボリュームがずらりと並び、コンテナを起動するたびに増えていくのです。
ここで大きな疑問が浮かんできました。
「バインドマウントを設定しているのに、なぜこんな匿名ボリュームが勝手に作られているのだろう?」
この疑問が、今回の調査のきっかけになりました。
増えてしまった匿名ボリュームは不要なものなので、一旦で消してから原因の調査に入りました。

匿名ボリュームとは何か?

その前に、まず「匿名ボリューム」という言葉を整理しておきます。
Dockerにはコンテナのデータを保存するための仕組みがいくつかあります。その中でも「ボリューム」はDockerが管理する領域にデータを保存する仕組みです。
ボリュームには大きく分けて「名前付きボリューム」と「匿名ボリューム」の2種類があります。
名前付きボリュームは、その名の通りのような分かりやすい名前が付いたボリュームです。開発者が意図的に作成し、名前で管理できます。
匿名ボリュームは、名前を指定せずに作られたボリュームです。名前を指定しないため、Dockerが自動的にランダムな長い文字列を名前として割り当てます。私がで見た、あのランダム文字列のような名前のボリュームも匿名ボリュームです。
つまり、匿名ボリューム自体は異常なものでも壊れたものでもなく、Dockerの正常な仕組みの一部です。問題は「意図していないのに大量に作られてしまう」という点にありました。なぜ大量に作られるのか、名前付きとの違いは後ほど詳しく説明します。

調査:なぜ増えるのか?

では、なぜバインドマウントを設定しているのに匿名ボリュームが作られていたのでしょうか。

compose.yamlを確認する

まず自分が設定したを確認しました。
の記述はとなっており、これは間違いなくバインドマウントの書き方です。ホスト側のディレクトリを、コンテナ側のにマウントしています。
を見る限り、匿名ボリュームを作るような記述はどこにもありません。ここで「じゃあ、この匿名ボリュームはいったいどこから来ているんだろう?」と、さらに混乱してしまいました。

Dockerfileを確認する

に原因がないのであれば、他の場所に原因があるはずです。そこで私は、から参照しているを確認してみることにしました。
すると、その中に次のような記述を見つけました。
このという命令が、実は今回のボリューム増加の原因でした。

なぜVOLUMEで匿名ボリュームが作られるのか

ここで、命令について説明します。
命令は、「このパスはボリュームとして扱ってください」とDockerに指示するものです。この命令が書かれていると、コンテナ起動時に、そのパスに対して明示的なマウント(バインドマウントや名前付きボリューム)が指定されていない場合、Dockerが自動的に匿名ボリュームを作成してマウントします。
私の環境では、はバインドマウントしていましたが、で指定していたについては、側で何もマウントを指定していませんでした。そのため、コンテナを起動するたびに用の匿名ボリュームが新しく作られ、どんどん溜まっていたのです。
つまり、私の環境では「バインドマウント」と「VOLUMEによる匿名ボリューム」が共存している状態になっていました。それにもかかわらず、「バインドマウントを設定したから、ボリュームはこれだけ」という誤解をしてしまっていたのです。

本当に匿名ボリュームなのか確かめる

原因の見当はつきましたが、念のため「本当にこれが匿名ボリュームなのか」を確かめてみることにしました。を使うと、ボリュームの詳細を確認できます。
で見えていたボリュームの一つを調べてみると、次のような情報が返ってきました。
ここで注目すべきは、の中にあるという項目です。このラベルは、Dockerが自動生成した匿名ボリュームに付くものです。これで、に並んでいたのが確かに匿名ボリュームだったと裏付けが取れました。

コメントアウトして検証する

原因が命令だと分かったので、最後に実際に確かめてみることにしました。命令をコメントアウトして、ビルドし直してみました。
この状態でコンテナを起動し直したところ、増えていた匿名ボリュームが、まったく増えなくなりました。これは、命令が匿名ボリュームの発生源だったことを裏付ける、決め手となる結果でした。
なお、匿名ボリュームにはコンテナを削除しても自動では消えないという性質があります。だからこそ、起動を繰り返すたびに使われないボリュームが積み重なり、があの状態になっていたのです。

名前付きボリュームとの違い

先ほど、名前付きボリュームと匿名ボリュームがあると説明しました。ここでは、なぜ匿名ボリュームだけが「増えていく」ように見えたのか、両者の挙動の違いから整理してみます。
名前付きボリュームは、のように決まった名前を持っています。同じ名前を指定すれば同じボリュームが再利用されるため、コンテナを何度起動しても数が増えることはありません。データも保持され続けます。
一方で匿名ボリュームは、名前を指定せずに作られるため、状況によっては起動のたびに新しいものが作られ、古いものは使われないまま残ります。これが「どんどん増えていく」ように見えた正体でした。
もしのデータを永続的に管理したいのであれば、で名前付きボリュームを明示的に指定するのが適切です。
このようにという名前付きボリュームを指定しておけば、は毎回同じボリュームにマウントされ、匿名ボリュームが無限に増えていくことはなくなります。

学んだこと

今回のトラブルを通して、私が学んだことをまとめます。
  1. ボリュームの設定はだけを見ていては分からない場合があるということ
    1. 命令のように、別のファイルの記述が影響していることもあります。トラブルシューティングの際は、関係するファイルを一通り確認する姿勢が大切だと感じました。
  1. 「自分が設定した覚えのないもの」が現れたときこそ学びのチャンスだということ
    1. 今回の匿名ボリュームも、最初は「意味がわからない」と戸惑うだけでしたが、でラベルを確認したり、命令をコメントアウトして挙動を確かめたりと、一つずつ確認していくことで、Dockerのボリュームの仕組みそのものを理解することができました。
  1. 思い込みを疑うことの大切さ
    1. 「バインドマウントを設定したから、ボリュームはこれだけ」という思い込みが、原因の発見を遅らせていました。実際にのようなコマンドで現状を確認し、事実を確かめることが解決への第一歩でした。

最後に

今回は、私が実際に遭遇した「匿名ボリュームがどんどん増える」という現象を入り口に、Dockerのボリュームの仕組みについて書いてきました。
まとめると、命令があると、明示的なマウントが指定されていないパスに対して匿名ボリュームが自動的に作成されること、そしてそれがコンテナ起動のたびに積み重なっていくことが、増加の原因でした。実際に命令をコメントアウトすることで、匿名ボリュームが増えなくなることも確認できました。解決策としては、で名前付きボリュームを明示的に指定することが有効です。
未経験からエンジニアになって日が浅い私にとって、こうした小さなトラブルの一つひとつが、仕組みを理解するための貴重なきっかけになっています。同じような現象に遭遇した方の助けになれば幸いです。
Docker全体の仕組みについては、次回以降の記事で改めて掘り下げていく予定です。最後までお読みいただき、ありがとうございました。