Docker for Windows 突然の不調
Dockerが動いてるはずなのにアクセスできない、リクエストは飛んでいるのか?dockerコマンドが信用できない、マウントしたはずのボリュームがない、けどコンテナを作り直しても消えたはずのフォルダが残ってしまっている。。。
怪談のような実話、docker for windows の怖い世界へようこそ。
こちらの Docker for WindowsのMobyLinuxVMに接続する方法 ページにを参考に、Docker for Windowsの本体である Moby Linuxへダイブしてみましょう。
対象バージョン
OS: Windows10 Pro 1803
Docker: Docker Desktop CE Ver.2.0.0.3(31259), Build:8858db3
Dockerファイルを作成
Hyper-V ManagerをもってしてもMobyVMには接続できません。
細かい仕組みはよくわかりませんが、上記ページにある通りにDockerfileを作成し…
FROM alpine
RUN apk update && \
apk add util-linux && \
rm -rf /var/cache/apk/*
ENTRYPOINT ["nsenter", "--target", "1", "--mount", "--uts", "--ipc", "--net", "--pid"]
Dockerfileをビルド!
> docker build -t docker-admin .
コンテナを起動!
> docker run -it --privileged --pid=host docker-admin /bin/sh
入れた〜!
/ #
Dockerの使用メモリを調べる
さっそくfreeコマンドで実際にDockerが使っているメモリの量を調べてみます。
WindowsのリソースモニタからはDockerで設定したメモリの全量が起動時に割り当てられているように見えるため、現在起動中の全コンテナ含めてdockerが使っているメモリの量と、残りの空き容量をサクッと調べるにはこれが手っ取り早いのです。
/ # free
total used free shared buffers cached
Mem: 10197936 3979880 6218056 1076 90512 3252380
-/+ buffers/cache: 636988 9560948
Swap: 2097148 0 2097148
うん、あと、コンテナ3つくらいいけるな、と。
Docker for WindowsとMoby上のDocker Serviceとの通信ログ
続いてdockerデーモン?のログです。ここではdocker for windowsのdockerコマンドが実際に投げているdockerコマンドがログに出力されています。(ややこしくてすいません。)
/ # tail -f /var/log/docker.log
2019-02-20T09:38:15Z docker time="2019-02-20T09:38:15.036785600Z" level=debug msg="Calling GET /v1.24/networks"
2019-02-20T09:38:15Z docker time="2019-02-20T09:38:15.037680700Z" level=debug msg="Calling GET /v1.24/version"
2019-02-20T09:43:15Z docker time="2019-02-20T09:43:15.003472500Z" level=debug msg="Calling GET /_ping"
2019-02-20T09:43:15Z docker time="2019-02-20T09:43:15.003966800Z" level=debug msg="Calling GET /v1.24/info"
Windows側とどのようにやり取りして、結果どうなったかがわかります。コンテナの中身がどうなったかはここでは出てきませんが。。。
あるはずのないVolume
そして、一番問題だった例のアレ。docker run
の-v
に架空のパスを指定するとエラーにはならずに作られてしまう問題。
通常のWindowsのターミナルやPower Shellでは適当に /mnt/c/work/github/... などと指定してもパスの解決でエラーになるため弾かれますが、WSLやMsys2、Git for Windowsなどのシェルからdockerコマンド入れる際にパスをミスってLinuxスタイルのパスを入力してもなんとなく解決できてしまう?ため、このままMobyにパスが送られてしまうのです!
当然、MobyもLinuxなので/
始まりのパスは問題なく受け付けられます。
晴れて『エクスプローラーでは存在しないなのに実在するパス』がマウントされてしまうのです。
そんな存在しないはずなのに実在するパス
の入口が以下!
rootfs
って明らかに怪しいよね!
/ # ls containers/services/docker/ -l
total 18
-rw-r--r-- 1 root root 12420 Jan 1 1970 config.json
drwxr-xr-x 19 root root 4096 Jan 1 1970 lower
drwxr-xr-x 1 root root 200 Feb 20 06:57 rootfs
-rw-r--r-- 1 root root 1272 Jan 1 1970 runtime.json
drwxrwxrwt 4 root root 80 Feb 20 06:57 tmp
そしてさらにrootfs
の中は以下のようにいかにもなディレクトリ構成になっております。
ちらっと見えますかmnt
が。私の/mnt/c/work/githubなどとやってしまった結果があそこに作成されてしまっているのです!
drwxr-xr-x 2 root root 14336 Feb 13 10:29 bin
drwxr-xr-x 4 root root 2048 Feb 13 10:29 dev
drwxr-xr-x 1 root root 140 Feb 20 06:57 etc
drwxr-xr-x 2 root root 2048 Feb 13 10:28 home
drwxr-xr-x 1 root root 60 Feb 20 06:57 lib
drwxr-xr-x 5 root root 2048 Feb 13 10:28 media
drwxr-xr-x 2 root root 2048 Feb 13 10:28 mnt # <- これな。。。
drwxr-xr-x 1 root root 80 Feb 20 06:57 opt
drwxr-xr-x 2 root root 40 Feb 20 06:57 port
dr-xr-xr-x 2 root root 2048 Feb 13 10:28 proc
drwx------ 2 root root 2048 Feb 13 10:29 root
drwxr-xr-x 1 root root 100 Feb 20 06:57 run
drwxr-xr-x 2 root root 22528 Feb 13 10:29 sbin
-rwxr-xr-x 1 root root 0 Feb 20 06:57 sendtohost
drwxr-xr-x 2 root root 2048 Feb 13 10:28 srv
drwxr-xr-x 2 root root 2048 Feb 13 10:28 sys
drwxrwxrwt 1 root root 40 Feb 20 08:09 tmp
drwxr-xr-x 1 root root 80 Feb 13 10:29 usr
drwxr-xr-x 12 root root 2048 Feb 13 10:29 var
ただし、出来てしまったディレクトリをむやみにrm -rf
などで消してはいけません。
私のようにドライブ共有ができなくなってしまうかもしれませんよ・・・?