[Docker for Mac] Docker Volumeの実態がどこにあるのか、探してみた
拙者、僭越ながらジュニアのエンジニアが書いたdocker-compose.yamlファイルのレビューしてましてね。フィードバックで「DBのデータは、コンテナ消しても消えぬように、Persistent(永続) Volumeにしたほうがえーんちゃう?」みたいなアドバイスしましたの。(← 偉そう)
そしたら、「そのPersistent Volumeの実態はどこにあるのんや!」みたいな質問を受けましたの。
それな!
拙者も気になってたけど、ちゃんと調べたことなかったわ!スマン!笑。
まぁ、気になるよね。だってエンジニアだもんね。ww
というわけで、ちゃんと調べてみた。(° ꈊ °)✧˖°オホッ!
■ 実態のマウントポイントを知る
とりあえず、まずは、今持ってるVOLUME NAMEを取得してみるよ、うん。
$ docker volume ls
DRIVER VOLUME NAME
local 27fcd21fc72e0338cf1d1aee5fe3fd48569fa24d7cc9da53be85918b86cd89fc
local docker-compose-local_psql_db
はいはい。2つあるよね。んで、下のほうが、docker-composeでDB用に作ったやつね。もう名前がそんな感じだもんね。
Google先生によると、ホスト側のマウントポイントは 'inspect' オプションで得られる結果の 'Mountpoint' に書かれてあるらしいので、カタカタカタ、ッターン!
$ docker volume inspect docker-compose-local_psql_db
[
{
"CreatedAt": "2020-05-25T12:40:08Z",
"Driver": "local",
"Labels": {
"com.docker.compose.project": "docker-compose-local",
"com.docker.compose.version": "1.25.5",
"com.docker.compose.volume": "psql_db"
},
"Mountpoint": "/var/lib/docker/volumes/docker-compose-local_psql_db/_data",
"Name": "docker-compose-local_psql_db",
"Options": null,
"Scope": "local"
}
]
はいはい。'/var/lib/docker/volumes/docker-compose-local_psql_db/_data' にあるってさ、実態は。なんだ簡単。秒速解決。はい天才!
■ しかしMacにそのパスは存在しない、辛み。
というわけで、見てみるよ、そのディレクトリの中身を。
$ ls /var/lib/docker/volumes/docker-compose-local_psql_db/_data
ls: /var/lib/docker/volumes/docker-compose-local_psql_db/_data: No such file or directory
ガーン。
ないってさ。そんなファイルもディレクトリもないってさ。
なんでやねん。そんなあほな。だってDocker Volumeちゃんと動いてるもん。
■ MacのDockerEngineはVMの上で動いている罠・・・!
ふたたびGoogle先生に助けを求めたら、
"Docker for MacのDocker EngineはVM(Virtual Machine)の上で動いているので、MountpointはローカルのMacのPATHじゃなくて、VM上のPATH"
とのこと。ほーん。
じゃ、そのDocker EngineのVMにはどうやってログインすればいーのよ?
■ 方法1: Screenを使う
screenコマンドでDocker for MacのVMにアクセスすればいーらしい!早速、カタカタカタ、ッターン!
$ screen ~/Library/Containers/com.docker.docker/Data/vms/0/tty
バシバシEnter押してみたら、なんかDocker Engineが動いているVMにアクセスできてるぽい雰囲気を感じる!ビシビシ感じる!
docker-desktop:~#
docker-desktop:~#
docker-desktop:~#
ほな、'/var/lib/docker/volumes/docker-compose-local_psql_db/_data' をのぞいてみまひょか。
docker-desktop:~# ls /var/lib/docker/volumes/docker-compose-local_psql_db/_data
PG_VERSION pg_notify pg_wal
base pg_replslot pg_xact
global pg_serial pgroonga.log
pg_commit_ts pg_snapshots postgresql.auto.conf
pg_dynshmem pg_stat postgresql.conf
pg_hba.conf pg_stat_tmp postmaster.opts
pg_ident.conf pg_subtrans postmaster.pid
pg_logical pg_tblspc
pg_multixact pg_twophase
docker-desktop:~#
きた!これ!これこれ!拙者がみたかったのはこれよ!
というわけで。結論。見つけてしまった。ミッションこんぷ。
さ、このVMから退出しよー、ってことで、適当に 'exit' って打ったら、まさかのクジラ登場。
docker-desktop:~# exit
__ __
Welcome to LinuxKit
## .
## ## ## ==
## ## ## ## ## ===
/"""""""""""""""""__/ ===
{ / ===-
_____ O __/
__/
_________/
docker-desktop login: root (automatic login)
Welcome to LinuxKit!
NOTE: This system is namespaced.
The namespace you are currently in may not be the root.
System services are namespaced; to access, use `ctr -n services.linuxkit ...`
login[81050]: root login on 'ttyS0'
docker-desktop:~#
いやいや、今そんなん求めてないし。つか、むしろはじめにでてこいよ!拙者は終わりたいのよ、今このセッションを!
'quit' ? 'Ctrl-Shift-d'? とりあえず、'help'?
あかん。ぜんぶクジラ出てくる。
え、まさか拙者、このVMから出られない系?
ググりまくった結果、'Ctrl-a k' で抜けられるぽいことを発見!
# disconnect that session but leave it open in background
Ctrl-a d
# list that session that's still running in background
screen -ls
# reconnect to that session (don't open a new one, that won't work and 2nd tty will give you garbled screen)
screen -r
# kill this session (window) and exit
Ctrl-a k
さっそく 'Ctrl-a k' ビシビシ!
出られた。でも、もう1回VMに入ってみたら、めっちゃ文字化けする・・・。
というわけで、screenで入る方法はお勧めできぬ。
■ 方法2: nsenterを使う (こっちがオヌヌメ)
他の方法はないものか。と探してみたらば、こんな便利そうなコンテナ見つけましたねん。
$ docker run -it --privileged --pid=host debian nsenter -t 1 -m -u -n -i sh
Phil Estes (Docker Maintainer) says:
it’s running a container (using the debian image..nothing special about it other than it apparently has nsenter installed), with pid=host (so you are in the process space of the mini VM running Docker4Mac), and then nsenter says “whatever is pid 1, use that as context, and enter all the namespaces of that, and run a shell there"
いやぁ、外国の人ってほんとうにホスピタリティすごいね。超意訳すると、
コンテナ用意したで。nsenterがインストールされてる以外はフッツーのdebianでっせ。これ使えばMac用のDocker Engineで使われている名前空間に入れるやでー(`・ω・´)キリッ
って言ってる。
ちなみに、nsenterっていうのは、Dockerで作った名前空間に入るためのコマンドライン・ツール。
では早速カタカタカタ、ッターン! 。
$ docker run -it --privileged --pid=host debian nsenter -t 1 -m -u -n -i sh
/ #
ふつうにDockerコンテナにはいったのとおんなじ感じ。やだステキ!
'/var/lib/docker/volumes/docker-compose-local_psql_db/_data' をのぞいてみる。
/ # ls /var/lib/docker/volumes/docker-compose-local_psql_db/_data/
PG_VERSION pg_dynshmem pg_multixact pg_snapshots pg_tblspc pgroonga.log
base pg_hba.conf pg_notify pg_stat pg_twophase postgresql.auto.conf
global pg_ident.conf pg_replslot pg_stat_tmp pg_wal postgresql.conf
pg_commit_ts pg_logical pg_serial pg_subtrans pg_xact postmaster.opts
/ #
みえる!ボリュームの中身が!
出るのもいつも通り。
/ #
/ # exit
$
超絶簡単。ステキ!抱いて!
■ まとめ
Docker For MacのDocker Engineは、VMの上で動いている。Volumeの実態は、nsenterコマンドのはいったコンテナイメージを起動してホスト側の名前空間にこっそり入り込めば、確認できる。
$ docker run -it --privileged --pid=host debian nsenter -t 1 -m -u -n -i sh
/ #
/ # ls /var/lib/docker/volumes/${VOLUME_NAME}/_data/
■ (おまけ) Docker For Windowsの場合は?
知らぬ。すまぬ。