競プロのサイトのように入力されたコードを実行して出力が指定のものになってるかどうかをチェックする機能をプログラミングスクールの機能として作りたい。

少なくともrubyとjsは実行できるようにしたい。メンターの@maedanaさんから競プロのジャッジサーバーのOSSであるarrow-judgeを教えてもらった。

なるほど、chroot, cgroup, ulimit等で実行ディレクトリやCPU・メモリといったリソースを制限しているようだ。

ってことはdockerでもできそうだということで調べてみた。

dockerでコンテナから外部へのネットワークアクセスを禁止する

まずは外部ネットワークにアクセスされると危険なので防ぎたい。

$ docker run --rm debian ping komagata.org -c 3
PING komagata.org (151.101.1.195) 56(84) bytes of data.
64 bytes from 151.101.1.195 (151.101.1.195): icmp_seq=1 ttl=37 time=4.34 ms
64 bytes from 151.101.1.195 (151.101.1.195): icmp_seq=2 ttl=37 time=5.27 ms
64 bytes from 151.101.1.195 (151.101.1.195): icmp_seq=3 ttl=37 time=5.32 ms

--- komagata.org ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 6ms
rtt min/avg/max/mdev = 3.698/4.748/5.385/0.748 ms

これが失敗するようにできれば良い。

$ docker run --net=none --rm debian ping komagata.org -c 3
ping: komagata.org: Temporary failure in name resolution

デフォルトでインストールされる3つのネットワークのうちの一つnoneを指定すればあらゆる外部ネットワークアクセスは防げそうだ。

dockerでメモリ使用量を制限する

docker run -m 100m --rm debian ping komagata.org -c 3 
PING komagata.org (151.101.1.195) 56(84) bytes of data.
64 bytes from 151.101.1.195 (151.101.1.195): icmp_seq=1 ttl=37 time=3.70 ms
64 bytes from 151.101.1.195 (151.101.1.195): icmp_seq=2 ttl=37 time=5.16 ms
64 bytes from 151.101.1.195 (151.101.1.195): icmp_seq=3 ttl=37 time=5.39 ms

--- komagata.org ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 6ms
rtt min/avg/max/mdev = 3.698/4.748/5.385/0.748 ms

100Mに制限してみたがどのぐらいが適量かわからない。

続く

あとはコードを楽にcontainerで実行したい。そして標準入力・コマンドライン引数を流し込んで、標準出力・標準エラーが取れればOKだが・・・

Comments


Option