All Articles

AWS App Runner を早速さわってみた【接続数でオートスケーリング・ゼロスケール(?)】

本日 (2021/05/19)、AWS に App Runner というサービスがリリースされました。

App Runner は、コンテナアプリケーションを非常に簡単にデプロイできるサービスのようです。

GitHub と連携した自動デプロイや、接続数でのオートスケーリングを試したのと、ゼロスケールのような挙動に気付いたので、そのあたりをまとめました。

公式ブログによると…

公式ブログの記事「New – AWS App Runner: From Code to a Scalable, Secure Web Application in Minutes」によると、

I can configure the auto scaling behavior. By default, my service will have one instance of my container image, but if the service receives more than 80 concurrent requests, it will scale to multiple instances. You can optionally specify a maximum number for cost control.

とので、CPU 使用率などではなく、接続数をもとにオートスケーリングしてくれるようです。

これは少し特徴的だなと思ったので、チュートリアル的なものをやりつつ、オートスケーリングも試すことにしました。

さわってみる

まずは公式ワークショップ「AWS App Runner Workshop :: AWS App Runner Workshop」をもとに、アプリケーションを起動してみます。

GitHub にリポジトリ (os1ma/aws-app-runner-demo) を作成します。

package.json を用意します。

{
  "name": "apprunner_example",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "dependencies": {
    "express": "^4.17.1"
  },
  "devDependencies": {},
  "author": "",
  "license": "ISC"
}

index.js を用意します。

const express = require('express');
const app = express();
const port = 3000;

app.get('/', (req, res) => {
  res.send('Hello World!');
});

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`);
});

ワークショップの内容とは違いますが、設定は YAML ファイルでやってみたいので、apprunner.yaml を書きます。

書き方は公式ドキュメントのこちら (Setting App Runner service options using a configuration file - AWS App Runner) の通りです。

version: 1.0
runtime: nodejs12
build:
  commands:
    build:
      - npm install
run:
  command: node index.js
  network:
    port: 3000

これをコミットした状態で、マネジメントコンソールでぽちぽちすると、無事、デプロイされました!

$ curl https://<ドメイン>
Hello World!

GitHub と連携した自動デプロイ

コードを書き換えて自動デプロイされるか試します。

あとでオートスケールを試しやすいように、index.js レスポンスを返すまで指定した秒数待つような仕組みを入れます。

const express = require('express');

const app = express();
const port = 3000;

app.get('/', (req, res) => {
  console.log('Receive request');

  const delaySec = req.query.delay || 0;

  setTimeout(() => {
    console.log('Return response');
    res.send('Hello World!');
  }, delaySec * 1000);
});

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`);
});

これを GitHub の main ブランチに入れると、無事自動デプロイされました。

getting-started-with-aws-app-runner-deployment.png

ちなみに、コードにエラーがあってコンテナが正常に起動しない場合は、自動でロールバックしてくれました。

接続数でオートスケールさせてみる

では、接続数でのオートスケールを試します。

デフォルトでは 80 の接続でスケールするようになっていますが、10 に変更しました。

そのうえで、何かツールを入れるのも手間なので、簡易的に curl を使ったワンライナーで 20 アクセスしてみます。

for i in {1..20}; do bash -c 'curl https://<ドメイン>/?delay=5 &'; done

すると、しっかりオートスケールしてくれました。

getting-started-with-aws-app-runner-scaling.png

Fargate などのサービスは基本的に CPU 使用率等でオートスケールさせるので、接続数でオートスケールするのは特徴的ですね。

使い方のイメージが、少し Lambda に近いのかなと思いました。

ちなみに、Fargate で接続数でオートスケールする場合は、こちら (爆速でFargateをスケールさせる「aws-fargate-fast-autoscaler」を試してみた | DevelopersIO) の記事のようなことをすることになるようです。

もしかしてゼロスケールしてる???

アクティブなインスタンス数のデータを見て「おや?」と思ったのですが、どうやらアクセスがないときはゼロスケールしてくれるようです。

Google Cloud Run (Knative) みたいですね。

料金のページ (AWS App Runner Pricing – Fully managed container application service – Amazon Web Services) を見ると、アクティブなインスタンスがない状態でもメモリは確保しているため、少し料金はかかるようです。

Cloud Run や Knative のゼロスケールとはちょっと違う雰囲気ですね。

感想

App Runner をなんとなくさわってみましたが、確かに楽だなと思いました。

細かい設定が不要で、とりあえずサクッと動かしたいときには良いかもしれません。

気になったところ

現状では

  • VPC には配置できない
  • ヘルスチェックは TCP のコネクション確立のみ
  • パラメータストアなどの値を環境変数に設定できない

などの制約がありそうです。

あと、どっちでもよくはあるのですが、「マネジメントコンソールでログが下から上向きに表示される」というのが気になりました笑

今後のアップデートに期待してます!