0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Dockerを完全理解するためにコードを実行してくれるDiscord BotをKotlinで作った話

Last updated at Posted at 2023-12-23

Kotlin(とか)をDiscord上で実行したいことってありますよね?
ありますよね??

そんな夢を叶えるDiscord Bot 「こーどらんなー」を作ったので少し早いですがプレゼントします!!!

速く試させろって方は記事の一番下へ!

機能

まずは機能から紹介します!

コードをDiscord上で実行できる!!

image.png

おおおお!KotlinがDiscord上で!!! かわいいね

これがこーどらんなーを走らせるコマンドです

コマンド
!run
```<言語名|拡張子>
<実行ファイル内容>
```
# 下は任意
```input
<標準入力(stdin)に入れる内容>
```
コマンド
!run
```kt
fun main() = println("Hello World!")
```

もちろん標準入力にも対応しています
image.png

対応言語 (2023/12/24時点)

言語 ツール ツールバージョン
Brainf*ck bf 20041219
C gcc 11.4.0
C++ g++ 11.4.0
C# dotnet 7.0.404
Go go 1.10.6
Java java Temurin-17.0.9+9
JavaScript node 18.18.2
Kotlin kotlinc 1.9.10 (JRE 17.0.9+9)
なでしこ cnako3 3.4.23
Python python 3.12.0
Rust rustc 1.73.0
WebAssembry (WAT) wasmtime 15.0.1

たまに変な言語がありますね・・・

言語追加要望は大歓迎です!
Debian・Ubuntu上で動くなら基本大丈夫です
それ以外でもなんとかします

実装とかの話

どうでもいいかもしれませんがここからは実装の話を一応書いておきます。

個人的な理由からKotlin以外の言語を使うことは許されなかったためこーどらんなーはDiscord Bot含むすべてがKotlinで書かれています。

こーどらんなー.drawio.png

BotとバックエンドはHTTPで通信してます。
本当はgRPCとか使ってみたいけど・・・

主な使ったライブラリ

用途 名前
サーバーフレームワーク Ktor
Discord Bot kord
Docker API docker-java

言語実行環境の定義

Dockerfileとmanifest.ymlを追加するだけで新しい言語を増やすことができます。
(あと curl -X POST http://localhost:8080/runtime/rebuild)

Kotlin の場合

Dockerfile
FROM eclipse-temurin:17-jdk
# 変数
ARG KOTLIN_COMPILER_URL="https://github.com/JetBrains/kotlin/releases/download/v1.9.10/kotlin-compiler-1.9.10.zip"
USER root
# 依存パッケージインストール
RUN apt update && apt install wget zip unzip -y
# ユーザー設定
ARG USERNAME=runner
ARG GROUPNAME=runner
ARG UID=1000
ARG GID=1000
RUN groupadd -g $GID $GROUPNAME && \
    useradd -m -s /bin/bash -u $UID -g $GID $USERNAME
# その他実行環境インストールなど (Option)
WORKDIR /opt
RUN wget $KOTLIN_COMPILER_URL -O kotlin.zip && \
    unzip kotlin.zip
ENV PATH $PATH:/opt/kotlinc/bin
# 初期ユーザー設定
USER $USERNAME
RUN mkdir /home/$USERNAME/work
WORKDIR /home/$USERNAME/work
CMD ["/bin/bash"]
manifest.yml
id: kotlin
name: Kotlin
sourcefileName: Main.kt
extension: kt
alias:
  - kotlin
  - kt
metaData:
  version: 1.9.10
  processor: JVM
commands:
  prepare: null
  compile: 'kotlinc -include-runtime Main.kt -d out.jar'
  execute: 'java -jar out.jar'

中のソースコードいじらなくても言語追加ができるのでとてもいいです。

Q. 変なコード実行しても大丈夫なの?

A. 大丈夫です!

実行環境には様々な制限が掛かっており悪意あるコードもこーどらんなーの前では無力です

たぶん

制限の情報はBotの/info host limitから確認できます。
limits.png

ここからは対策の一例を挙げていきます

実行時間

実行時間が決まっておりこれを過ぎるとコンテナごと終了します。

コンパイル2分、実行10秒です。

無限ループしても10秒で強制終了です。

メモリ

コンテナあたりのメモリが決まっており、それ以上のメモリ確保はできません。

いっぱいmallocしたのにfreeしないで放置してやるぜ〜〜〜〜〜
ってコードを実行されても10秒後にはきれいに消えます

フォーク爆弾

大量に子プロセスを増やすアレです
コンテナのプロセス数を制限することで対策しています

開発中知ったんですが対策なしでフォーク爆弾やられるとDocker Engine自体がすべての操作にエラー返すようになって正常に動かなくなるんですね・・・

↓ 実行中に力尽きたこーどらんなー
image.png
(Docker Desktopから見たCPU使用率の表示が NaN% になっていてびっくりしました)

withPidsLimitで対策すると一定のプロセス数を超えてからはしっかりエラーが起きるようになっています。
image.png

ディスク制限

Dockerでコンテナ毎のディスク使用量制限をする--storage-opt size=XXを使用するにはいくつか条件があります。

参考
https://docs.docker.com/engine/reference/commandline/run/#storage-opt

ドライバー ファイルシステム 備考
overlay2 xfs マウントオプションにpquotaを設定する必要あり
devicemapper - デフォルトのBaseFSより小さいサイズは不可
btrfs - デフォルトのBaseFSより小さいサイズは不可
zfs - デフォルトのBaseFSより小さいサイズは不可

今回は overlay2 + xfsを使用します。

/etc/fstabhttps://reece.tech/posts/docker-container-size-quota/ を参考に編集しました。

/etc/fstab
UUID=700696bd-cd1a-49b0-b17d-08b80f516965 /                       ext4    defaults,noatime                      1 0
UUID=618e96a4-aa0f-49a5-8d74-c0cecb9bd276 /boot                   ext4    defaults,noatime                      1 0
UUID=5232294a-cad8-4040-92c2-6cb5d3b62c4e /var/lib/docker         xfs     defaults,pquota                       0 0

これで /var/lib/docker に xfs & pquotaな領域が割り当てられるので--storage-opt size=XXが使えるようになりました!

しっかりと256MBまでになっています!
image.png

おわり

作ってみて、俺Dockerなにもわかってなかったなってなりました
今もよくわかりません。

こーどらんなーを試す

試す用のDiscordサーバー作ったのでぜひ!!!
(まだ公開Botにはしません・・・)

こーどらんなーと同じ環境でコードを実行する

各言語の実行環境をDockerイメージとして公開してます

docker run -it ghcr.io/naotiki/code-runner-runtimes/kotlin:main

他のイメージ

ソースコード

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?