Fargate上でRのスクリプトをREST APIにしたい

記事タイトルとURLをコピーする

こんちくわ。

RのスクリプトをAPIにしたいときってありますよね? しかもそれをDockerで。

というわけで今回はFargate上でRのスクリプトをAPIにしてみました。

準備

もろもろ準備します。今回はAmazon Linux2で実施しました。

もとになるイメージ

r-baseという公式のイメージがあります。今回はこれをもとにイメージを作成します。

イメージのプル


docker pull r-base

Rのスクリプト

Rにはplunberというパッケージがあり、これを利用するとRのスクリプトをREST APIとして使えるようになります。詳しい使い方はリンク先で確認してください。

plumberを起動するスクリプトを書きます。

plumber.R


library(plumber)
api <- plumber::plumb("sample.R")
api$run(host = "0.0.0.0", port=8000)

上記のスクリプト内で呼び出しているsample.Rは以下のようにしました。今回はサンプルなのですべてGETの簡単なものです。

sample.R


#* @get /hello
hw <- function() {
    return("Hello, world!")
}

#* @get /hello//
hw <- function(name, age) {
    return(paste("Hello", name, "You're", age, "years old", seq=" "))
}

#* @get /fn
hw <- function(x) {
    x <- as.numeric(x)
    y <- 2 * x + 1
    return(y)
}

#irisを読み込み
df <- iris

#* @get /plot
#* @png
hw <- function() {
    p <- plot(df$Sepal.Length, df$Sepal.Width, 
        main="Sample plot", xlab="Sepal.Length", ylab="Sepal.Width")
    print(p)
}

Dockerflileを書く

Dockerflileはこんな感じ

Dockerfile


FROM r-base

COPY  sample.R /usr/local/src/
COPY  plumber.R /usr/local/src/

WORKDIR /usr/local/src/

RUN R -e 'install.packages("plumber")'

EXPOSE 8000

ENTRYPOINT ["Rscript", "plumber.R"]


ECR

ECRにリポジトリを作成しておきます。ECRの画面を開き、「リポジトリの作成」をクリック。 いい感じのリポジトリ名を入力して、「リポジトリの作成」をクリック。今回はリポジトリ名をr-apiとしました。

構築

さてイメージをビルドして、Fargateを構築していきます。

イメージのビルド・プッシュ

作成したリポジトリの詳細画面からプッシュコマンドを確認できます。

表示されるプッシュコマンドはこんな感じ。下記を実行してビルド・プッシュします。plumberのインストールにちょっと時間がかかります。


#認証。Amazon Linux2なのでAWS CLIがプリインストールされてます。
#されてない場合は先にインストールする必要があります
$(aws ecr get-login --no-include-email --region ap-northeast-1)
#イメージのビルド
docker build -t リポジトリ名 .
#タグつけ
docker tag リポジトリ名:latest 119463424712.dkr.ecr.ap-northeast-1.amazonaws.com/リポジトリ名:latest
#プッシュ
docker push 119463424712.dkr.ecr.ap-northeast-1.amazonaws.com/リポジトリ名:latest

プッシュされました

Fargate起動

さて最後にプッシュしたイメージからコンテナをFargateで起動します。

タスク定義

まずはコンテナを起動するためのタスク定義をします。

ECSのタスク定義の画面から「新しいタスク定義の作成」をクリック。

起動タイプはFargateを選択。「次のステップ」をクリック。 いい感じのタスク定義名を入力。 CPUとメモリは最小にしました。 「コンテナを追加」をクリック。 いい感じのコンテナ名を入力。イメージにはプッシュしたイメージのURIえお入力。 ポートマッピングはDockerfile内で指定したのと同じ8000とします。その他はデフォルトで「追加」。 タスク定義の設定も上記以外はデフォルトとして「作成」をクリック。

クラスター作成

ECSのクラスター画面から「クラスターの作成」をクリック。 「ネットワーキングのみ」を選択して「次へ」 いい感じのクラスター名を入力。VPCを新規作成する場合は、その項目にチェックを入れます。「作成」をクリック。

タスク実行

今回は負荷分散やAutoScaleを考えないのでサービスからはタスクを実行せずに、手動でタスクを1つ実行するだけにします。

作成したクラスターの詳細の「タスク」タブの「新しいタスクの実行」をクリック。 起動タイプはFargateを選択。タスク定義は先ほど作成したものを選択。 VPCとセキュリティグループはいい感じに既存のものを使用するか新規で作成してください。ECRからイメージをとる必要があるのでインターネットへアクセスできる必要があります。そのためパブリックIPも「ENABLED」。 「タスクの実行」をクリックし、タスク一覧からステータスが「RUNNING」となればOKです。

確認

curlを叩いて確認するのもいいですが、図の表示もあるのでブラウザから確認してみます。 タスクの詳細からパブリックIPが確認できるので、そのIPに接続します。

Hello, world 名前と年齢 計算 いい感じです。

まとめ

いかがでしたでしょうか。plumber + DockerはAmazon SagemakerでRを使用する場合にも必要となるのでいろいろ試してみたいと思います。