💡
Dockerのtmpfs内で実行ファイルを実行する方法
docker run
のオプションで --tmpfs
を使うと、コンテナに tmpfsのボリュームをマウントすることができます。
$ docker run --rm -it --tmpfs /tmpfs ubuntu bash
ところがデフォルトだと、この tmpfs領域に置いた実行ファイルを実行することができません。
root@b1be696bd550:/# cat <<EOF > /tmpfs/a.sh
> #!/bin/bash
> echo hello
> EOF
root@b1be696bd550:/# chmod 0755 /tmpfs/a.sh
root@b1be696bd550:/# /tmpfs/a.sh
bash: /tmpfs/a.sh: Permission denied
これはなぜでしょうか。mountコマンドでマウント状態を調べてみましょう。
root@b1be696bd550:/# mount | grep /tmpfs
tmpfs on /tmpfs type tmpfs (rw,nosuid,nodev,noexec,relatime)
"noexec" という、いかにもそれっぽい単語が見えます。
Linuxマニュアルによるとお、
noexec
マウントされたファイルシステム上の任意のバイナリの直接実行を禁止する。
ということで、デフォルトでは実行禁止になっているんですね。まあセキュリティ的にはその方が安心ですね。
一方でコンパイラ開発などをしていると、コンパイラが tmpfs に吐いた大きめのバイナリをすぐ実行してテストしたいということがよくあります。
試行錯誤したら、下記のように exec
オプションをつけると実行できるようになりました。
$ docker run --rm -it --tmpfs /tmpfs:exec ubuntu bash
root@c15f0207a000:/# cat <<EOF >/tmpfs/a.sh
> #!/bin/bash
> echo hello
> EOF
root@c15f0207a000:/# chmod 0755 /tmpfs/a.sh
root@c15f0207a000:/# /tmpfs/a.sh
hello
mount状況を見てみると、noexec
の文字が消えています。
root@c15f0207a000:/# mount | grep /tmpfs
tmpfs on /tmpfs type tmpfs (rw,nosuid,nodev,relatime)
めでたしめでたし。
sizeやmodeを同時に指定するときはこう書きます。
$ docker run --rm -it --tmpfs /tmpfs:rw,exec,size=500m,mode=1777 ubuntu bash
ちなみにこの exec
オプションはなんとdockerの公式マニュアルにも載っていないのです。
どうやって知ったのかというと、なんとなく勘でつけてみたら成功したという。
Discussion