メインコンテンツまでスキップ

CentOS の docker でデフォルトのイメージ保存パスを変更する

· 約10分

環境:CentOS-7、docker 1.13.1。docker のデフォルトイメージ保存パスを変更した際の、ハマりどころ満載の一部始終を記録します。

(ご自身のシステムと docker のバージョンに注意してください。必ず記事を最後まで読んでから操作してください。そうしないと自己責任になります)

docker のデフォルトのイメージ保存パスは /var/lib/docker です。通常はデフォルトの保存場所を使いません。イメージファイルは一般的にサイズが大きく、構築するサービスが増えるほどホストのシステムディスクへの負荷が大きくなりますし、各イメージにはそれぞれマウントボリュームなどもあります(これらは本記事の範囲外です)。したがってデータをシステムディスクに置くべきではなく、対応するデータディスクのパスに切り替えるべきです。

保存パスの変更

本題に入りましょう。docker の設定ファイル /usr/lib/systemd/system/docker.service を修正します。

graph 設定 --graph="your path" \ を追加し、修正して保存した後、設定ファイルをリロードして docker サービスを再起動します。

# systemd の設定をリロード
systemctl daemon-reload
# docker サービスを再起動
systemctl restart docker.service

docker info を実行して docker サービスの現在の情報を確認します。

Docker Root Dir が "your path" と表示されていれば、設定は成功です。イメージを 1 つダウンロードしてから、対応するフォルダを見て反映されているか確認することをおすすめします。その後 reboot でサーバーを再起動し、docker 内のイメージがまだ残っているかを確認しましょう。

docker images を実行した結果、ダウンロードしたイメージが消えていたら。

おめでとうございます、私と同じ状況です。人生に疑問を感じるかもしれません。再度 docker info を実行すると、Docker Root Dir のパスには何の問題もありません。ここでの私のやり方は、元の /var/lib/docker フォルダを削除することでした。もちろん削除する前に、中のデータがまだ必要であれば、先にコピーを取ってから削除するか、フォルダを移動して名前を変えることをおすすめします。名前を変えなくても構いませんが、重要なのは /var/lib/docker を存在しない状態にすることです。その後もう一度試してみれば、おそらく問題ないはずです。少なくとも私はそうでした。

追記:再起動後にまたイメージが消えた(2019-06-16)

これで設定完了だと思っていたのですが、案の定そう単純な話ではありませんでした。やはり私の docker への理解はまだまだ足りなかったのです。

今回はサーバー事業者が突然サーバーのハードウェアを修理し、大部分のサーバーが強制シャットダウンされました(だからやはり、安さにつられて無名ブランドのクラウドサーバーを買うのはやめましょう)。私のサーバーもシャットダウンされ、修理完了後にサーバーが再起動しましたが、ブログには依然としてアクセスできませんでした。docker の自動起動とコンテナの追従起動を設定していたのに、どうやら効いていなかったようで、当然ながら問題の原因を調べる必要がありました。(前回、本当に設定完了だと思っていたのに、どうやら顔をひっぱたかれた気分です)

サーバーにログインして docker images を実行すると、イメージが前回と同じようにまた消えていました。つまり前回の操作では実際には問題を解決できていなかったのです——正確に言えば、設定自体は有効になっていたものの、ホストの再起動に伴って設定に問題が発生したのです。

docker info で見える Docker Root Dir のパスには問題がないものの、実際にはすでに障害が起きています。docker images と docker ps -a を実行しても何の情報も表示されません。しかもこの状態で service docker stop を実行して docker サービスを停止すると、二度と docker を起動できなくなります。service docker start で起動しようとするとエラーが出ます。

Job for docker.service failed because the control process exited with error code. See "systemctl status docker.service" and "journalctl -xe" for details.

指示どおり systemctl status docker.service や journalctl -xe でエラー詳細を確認しても、まったく要領を得ません。具体的なエラー情報を見たければ、docker デーモンをフォアグラウンドで直接起動すれば起動ログが表示されるので、そこからエラーを調べられます。

# docker デーモンをフォアグラウンドで起動し、起動ログを直接出力する
dockerd

ストレージドライバの落とし穴

このエラーを調査する過程で多くの知識を学びました。たとえば docker の 5 種類のストレージドライバモードです。

簡書:https://www.jianshu.com/p/00ffd8df6010

他の方のブログ:https://blog.csdn.net/qq_34018840/article/details/89853119

AUFS、Btrfs、Device mapper、OverlayFS、ZFS

最終的に私は OverlayFS のアップグレード版である Overlay2 を選びました。私が元々使っていたドライバモードは Device mapper でした——docker info を実行すると一番下にヒント情報が表示され、Device mapper というモードはテスト環境で自動選択されたものにすぎず、本番環境では自分で切り替えてよいと教えてくれます。これで Overlay2 に切り替える決心がいっそう固まりましたが、急いで切り替えることはせず、まずこの不思議な現象の調査を続けました。ホストを再起動した後、なぜ docker は /home/docker_data 配下のイメージファイルを読み取れないのでしょうか?

google、百度、github、知乎、フォーラム、簡書、公式ドキュメントを探してもこの問題は見つからず、最後に docker の公式コミュニティで、私とほぼ同じ状況に遭遇した海外の方を見つけました。彼らの議論ではこれはバージョンの問題だとのことで、私は「なるほど、では新しめのバージョンを入れる必要があるようだ」と考えました。

そこで docker を完全に削除してから再インストールしました(注意:docker はバージョン 1.13 以降、タイムラインベースのバージョン番号を採用しており、コミュニティ版 CE とエンタープライズ版 EE に分かれています)。

# 旧バージョンの docker を完全にアンインストール
yum remove docker
yum remove docker-selinux

docker-ce-17.12.0.ce バージョン(比較的安定したバージョンだと聞きました)を再インストールし、/etc/docker/daemon.json を設定しました。

docker を起動すると、私の linux カーネルが overlay2 ストレージドライバ方式をサポートしていないことが判明したため、カーネルをアップグレードしました。サポートには 4.0 以上のカーネルが必要です。

その後 docker info を実行すると、今度はディスクが d_type をサポートしていないというヒントが表示されました。そこでマウントディスクをフォーマットし直し、ftype=1 の xfs にフォーマットしました。

# ファイルシステム情報を確認。ftype=1 は d_type をサポートしていることを示す
xfs_info /home

そして docker のデフォルトイメージ保存場所を、この d_type をサポートするデータマウントディスクに設定し、docker を再起動しました。

再度 docker info を実行すると警告情報は一切なくなり、d_type は有効になり、ストレージ方式も overlay2 に変更されていました。

今回はもう完璧だと感じました。なにしろ docker info を実行しても警告が 1 つもないのですから。すぐに tomcat イメージをダウンロードしてみると、イメージは指定したフォルダに置かれています。素晴らしい!すぐさま reboot でホストを再起動しました。

再起動後、docker images のイメージがまた消えました!!!

私は誰で、何をしていて、こんなに頑張って一体何をしているのでしょうか?

本当にお手上げでした。どのステップで何を間違えたのか分かりません。

最終的な解決

最後に私はこう解決しました。データディスクを /var/lib/docker フォルダに直接マウントし、起動時の自動マウントを設定したうえで、/etc/docker/daemon.json 内の data-root の設定を削除しました。

その後ホストを再起動して docker images を実行すると、イメージが表示され、コンテナも自動的に起動していました。今度は停電もシャットダウンも怖くありません。ホストの再起動後、docker は自動的にコンテナを起動してくれます。

しかしその後アリババクラウドのサーバーに乗り換えたところ、何事もなくすべて正常だったので、もしかするとやはりハードウェアの問題だったのかもしれません。

小まとめ

イメージ保存パスの変更は --graph パラメータを 1 つ追加するだけの話に見えますが、実際にはストレージドライバ、カーネルバージョン、ファイルシステムの d_type サポートといった一連の問題を芋づる式に引き起こしました。さんざん格闘した末の私の最終案は、逆転の発想でした。docker のパス設定は変えず、データディスクを /var/lib/docker に直接マウントして起動時の自動マウントを設定するのです。これで再起動後もイメージとコンテナは正常に復旧できます。もしあなたも再起動後にイメージが消える状況に遭遇したら、まずストレージドライバとディスクマウントのタイミングの問題を調べてみてください。格安サーバー自体のハードウェアの不具合という可能性も否定できません。クラウド事業者選びは、やはり安さを追いすぎないほうがよいでしょう。

COMMENTS