結論
Docker Hub: centos の A note about vsyscall
に書かれている現象が起きています。centos:6
に限らず、Linux kernel 4.11 以前をベースとした古いコンテナでよく発生するようです。
問題
Docker Desktop for Windows (WSL2 backend) を使っていて centos:6
を動かそうとすると、起動せずに Exited (139)
で即落ちるというエラーに遭遇しました。
> docker run -it --rm centos:6 bash
> docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6c33d78abb9c centos:6 "/bin/bash" 17 seconds ago Exited (139) 7 seconds ago sad_wescoff
centos:7
の場合は問題なく起動します。コンテナに依存する問題のようです。
> docker run -it --rm centos:7 bash
[root@de06793c93fe /]#
対処法
Docker Desktop for Windows (WSL2 backend) で問題を回避するには %USERPROFILE%/.wslcofig
に設定を追加して PC を再起動します。参照: GitHub microsoft/WSL Issue#4694
[wsl2]
kernelCommandLine = vsyscall=emulate
再起動して .wslconfig の設定が反映されたか確認するには、適当な WSL2 で以下のコマンドを実行します。vsyscall=emulate
が表示されていれば OK です。
> wsl cat /proc/cmdline
initrd=\initrd.img panic=-1 pty.legacy_count=0 nr_cpus=4 vsyscall=emulate
そうすると、以降は起動できるようになります。
> docker run -it --rm centos:6 bash
[root@4464b48b5c69 /]#
原因
「単に docker run centos:6
しただけで落ちるなら FAQ なのでは?」と思って Docker Hub: centos を見に行ったら A note about vsyscall
に答えが書いてありました。
If running docker run --rm -it centos:centos6.7 bash immediately exits with status code 139, check to see if your system has disabled vsyscall:
$ cat /proc/self/maps | egrep 'vdso|vsyscall'
7fffccfcc000-7fffccfce000 r-xp 00000000 00:00 0 [vdso]
$vs
$ cat /proc/self/maps | egrep 'vdso|vsyscall'
7fffe03fe000-7fffe0400000 r-xp 00000000 00:00 0 [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0 [vsyscall]If you do not see a vsyscall mapping, and you need to run a CentOS 6 container, try adding vsyscall=emulated to the kernel options in your bootloader
「もし docker run --rm -it centos:centos6.7 bash
がすぐに status code 139 で終了する場合は、あなたのシステム(ホスト)の vsyscall が disable になっていないか調べてください。vsyscall マッピングが表示されず、CentOS 6コンテナーを実行する必要がある場合は、ブートローダーのカーネルオプションに vsyscall=emulated
を追加してみてください」とのことで、問題の現象ドンピシャです。
そこで、Docker Desktop for Windows (WSL2 backend) で vsyscall がどうなのか調べると GitHub microsoft/WSL Issue#4694 に WSL2 で vsyscall=emulate
を有効にする方法がありました。
私の場合は、これで解決しました。
centos:6 以外でも同じ問題は起きる
Linux kernel 4.11 から vsyscall がデフォルトで無効になったため、この問題は、
- vsyscall が無効なホスト OS 上(最近の Linux は全部そう)で、
- vsyscall を利用している古いコンテナを docker で起動する
場合に発生するようです。
古いコンテナを起動して Exited (139)
が起きる場合は、まずこの問題を疑ったほうが良いかもしれません。
環境
- Windows10 [Version 10.0.19041.264]
- docker 2.3.0.3 (45519) WSL2 backend