3
1

More than 1 year has passed since last update.

gunicornでディスク使用量が増え続ける現象への対処

Last updated at Posted at 2023-04-03

はじめに

Linux環境にてFastAPIをgunicornで動かしています。
しばらく運用しているうちにローカルストレージの使用量が増えていっていることに気が付きました。
なぜなのか等、調査し対応したメモを残しておきます。

AWSのFargateでの事象および回避方法ですが、
オンプレサーバなどの環境でも設定方法が違うだけで内容は同じはずです。

なお、gunicornのバージョンは20.1.0です。

結論

max-threadsを設定するとコアダンプファイルがストレージを圧迫するので、
コアダンプが出力されないように設定しよう。

調査

Fargateの場合、Cloudwatch Container Insightを有効化することでコンテナのストレージ使用量(EphemeralStorageUtilized)を見ることができます。
有効化してしばらく運用していたところ、使用量が増えていっていることに気が付きました。

どんなファイルが増えていっているのか?

Fargateなので、コンテナに直接ログインしてみて中身を見てみます。
CloudShellからAmazon ECS Execを使ってコンテナにログインします。
あらかじめ設定等が必要ですが、こちらを参考に設定しておきます。

aws ecs execute-command  \
    --region ap-northeast-1 \
    --cluster クラスタ名 \
    --task XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX \
    --container コンテナ名 \
    --interactive \
    --command "/bin/sh"

つながったらlsなどでFastAPIを動かしているディレクトリを見てみると、
core.999 という謎のファイルが多数、、、

/HOGE # ls -lh
total 2G     
drwxr-xr-x    2 root     root        4.0K Feb 28 07:30 __pycache__
-rw-------    1 root     root      164.7M Feb 28 19:05 core.1058 ←???
-rw-------    1 root     root      156.9M Feb 28 23:24 core.1257 ←???
-rw-------    1 root     root      175.9M Feb 28 09:54 core.21  ←???
-rw-------    1 root     root      178.7M Feb 28 13:01 core.337  ←???
drwxr-xr-x    1 root     root        4.0K Feb 28 07:30 hogehoge
-rw-r--r--    1 root     root        3.7K Feb 21 00:39 main.py
-rw-r--r--    1 root     root         285 Feb 21 00:39 requirements.txt
/HOGE # 

fileコマンドで何者かを確認してみましょう。

/HOGE # file core.1058
core.1058: ELF 64-bit LSB core file, x86-64, version 1 (SYSV), SVR4-style, from '/usr/local/bin/python /usr/local/bin/gunicorn main:app --workers 2 --worker-cla', real uid: 0, effective uid: 0, real gid: 0, effective gid: 0, execfn: '/usr/local/bin/gunicorn', platform: 'x86_64'

ELF 64-bit LSB core fileということでコアダンプのファイルだとわかりました。
また、gunicornの異常終了でできたものであることもわかりました。

gunicornの異常終了はなぜ起こるのか

gunicornには指定回数分の処理をこなすとワーカープロセスを再起動してくれる設定(max_requests)があります。
これを設定しておくことで、万一メモリリークなどが発生していたとしても回避することが可能です。

今回、gunicornの起動オプションとして --max-requests 500 を指定していたため、
ワーカープロセスが再起動されるのですが、
その再起動が異常終了とみなされてコアダンプが生成されているようです。

対処

再起動してもコアダンプを出さないように設定することで対処します。
ulimitでcore file sizeを0に設定します。

Webコンソール > ECS > タスク定義 > 設定したいタスクの最新リビジョン
新しいリビジョンの作成 > JSONを利用した新しいリビジョンの作成
を開きます。
(2023/03現在、JSONでないと設定できません)

以下のように containerDefinitions.ulimits[] にcoreの設定を追加して、サービスに適用させれば完了です。

{
  ~略~
  "containerDefinitions": [
    {
      ~略~
      "ulimits": [
        {
          "name": "core",
          "softLimit": 0,
          "hardLimit": 0
        }
      ],
      ~略~
    }
  }
}

冒頭に記載しましたように、上記はFargateでの設定です。
オンプレ環境だと /etc/init.d/ や /etc/security/limits.conf にulimitの設定をすることになると思います。

おわりに

max-requestsを設定するときは同時にmax-requests-jitterも設定しましょう。という記載は比較的よく見かけるのですが、
コアダンプファイルへの注意を記載しているのが見つからなかったので、
今後のために記録しておきます。

3
1
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
3
1