Dockerで一定数以上のコンテナ作成に失敗する(could not create session key: disk quota exceeded)場合の対処

弊社でも最近Dockerに触る機会が増えてきました。触り始めた当初は仮想化との違いに戸惑うことも多かったのですが、少しずつ慣れてきた気がします。今回はコンテナをスケールさせた時にハマったことを記事にしました。

発生事象

コンテナのスケール時、CPU等のリソースに余裕があるにもかかわらず、Dockerが以下のエラーを出力して一定数以上のコンテナを起動できない。

ERROR: for otest_app_21  b’rpc error: code = 2 desc = “oci runtime error: could not synchronise with container process: could not create session key: disk quota exceeded”‘

原因

Linuxのカーネルパラメータ「kernel.keys.root_maxkeys」の設定値が低い為、キー生成に失敗しエラーとなる。

対処

Linuxのカーネルパラメータ「kernel.keys.root_maxkeys」の設定値を十分な値に変更する。

本設定値はOSの提供元によって異なるようです。

提供元 バージョン 設定値
Ubuntu 14.04 LTS 1000000
Ubuntu 16.04 LTS 1000000
AWS 14.04 LTS(ami-a21529cc) 200

Ubuntu公式のISOイメージで構築する場合は、十分に大きな値なので気が付きませんが、AWSで公開されているAMIの場合だけ極端に値が低かったので今回この事象に悩まされました…。

なお、本事象は既に対応版のPRがリポジトリにマージされたようなので、次回(1.12?)のDockerではデーモン起動時に適切な値に設定されるようになるようです。

Change root_maxkeys #23182

最新のDockerを用いることができない利用環境では、同様の事象に悩まされる可能性もあると思いますので注意しましょう。

再現手順

せっかくなので再現手順をメモしておきます。

環境

環境は以下の通りです。

OS 14.04.4 LTS
Docker 1.11.2
Docker Compose 1.7.1

コンテナ設定

DockerとDocker-Composeのインストールは以下手順で実施しました。

$ wget -qO- https://get.docker.com/ | sh
$ sudo usermod -aG docker $(whoami)
$ sudo apt-get -y install python-yaml
$ sudo pip install docker-compose

今回コンテナ上で以下のPythonスクリプトを起動します。

  • app.py
import time

i = 1
while True:
print "run:%d" % i
i += 1
time.sleep(1)

とりあえず単独コンテナで実行してみます。

$ docker run --rm -v $(pwd):/app -w /app python:2-alpine python -u app.py
run:1
run:2
run:3
^CTraceback (most recent call last):
  File "app.py", line 7, in <module>
    time.sleep(1)
KeyboardInterrupt

今回コンテナは軽量ディストリビューションである「Alpine Linux」を利用しています。

次は複数コンテナで簡単に実行できるようにDocker Composeで起動するようにします。

  • docker-compose.yml
app:
  image: python:2-alpine
  volumes:
    - .:/app
  working_dir: /app
  command: python -u app.py

Docker Composeを利用して単独コンテナで実行してみます。

$ docker-compose up
Creating otest_app_1
Attaching to otest_app_1
app_1  | run:1
app_1  | run:2
^CGracefully stopping... (press Ctrl+C again to force)
Stopping otest_app_1 ...
Killing otest_app_1 ... done
$ docker-compose down
Removing otest_app_1 ... done

カーネル設定変更

マシンスペックがボトルネックにならないようにとりあえず5にします。

$ sudo -s
# echo 5 > /proc/sys/kernel/keys/root_maxkeys
# cat /proc/sys/kernel/keys/root_maxkeys
5

コンテナスケール起動

同じコンテナをスケールさせて10個起動してみます。

$ docker-compose scale app=10
Creating and starting otest_app_1 ... done
Creating and starting otest_app_2 ... done
Creating and starting otest_app_3 ... error
Creating and starting otest_app_4 ... error
Creating and starting otest_app_5 ... error
Creating and starting otest_app_6 ... error
Creating and starting otest_app_7 ... error
Creating and starting otest_app_8 ... error
Creating and starting otest_app_9 ... error
Creating and starting otest_app_10 ... error

ERROR: for otest_app_8  b'rpc error: code = 2 desc = "oci runtime error: could not synchronise with container process: could not create session key: disk quota exceeded"'
(以下略)

途中で失敗してしまいました。

$ docker ps
CONTAINER ID        IMAGE               COMMAND              CREATED              STATUS              PORTS               NAMES
545d4fbbdd26        python:2-alpine     "python -u app.py"   About a minute ago   Up About a minute                       otest_app_2
a83dcc9ae7f1        python:2-alpine     "python -u app.py"   About a minute ago   Up About a minute                       otest_app_1

コンテナを10起動しようとしたにもかかわらず2しか起動できていません。なぜ上限の5ではないのかは謎ですが…。

カーネル設定変更(再)

デフォルト値に戻します。

$ sudo -s
# echo 100000 > /proc/sys/kernel/keys/root_maxkeys
# cat /proc/sys/kernel/keys/root_maxkeys
100000

コンテナスケール起動(再)

先ほどの続きでコンテナが2つ起動している状態でコンテナを10までスケールさせます。

$ docker-compose scale app=10
Starting otest_app_3 ... done
Starting otest_app_4 ... done
Starting otest_app_5 ... done
Starting otest_app_6 ... done
Starting otest_app_7 ... done
Starting otest_app_8 ... done
Starting otest_app_9 ... done
Starting otest_app_10 ... done

今度は全て成功しました。

$ docker ps
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS               NAMES
8846ed26a071        python:2-alpine     "python -u app.py"   5 minutes ago       Up About a minute                       otest_app_7
8c534dab2e71        python:2-alpine     "python -u app.py"   5 minutes ago       Up About a minute                       otest_app_5
01d93af52a90        python:2-alpine     "python -u app.py"   5 minutes ago       Up About a minute                       otest_app_6
b5ac477d0679        python:2-alpine     "python -u app.py"   5 minutes ago       Up About a minute                       otest_app_9
3748d2f684d6        python:2-alpine     "python -u app.py"   5 minutes ago       Up About a minute                       otest_app_8
1724a4dd83f9        python:2-alpine     "python -u app.py"   5 minutes ago       Up About a minute                       otest_app_10
bb443905ab34        python:2-alpine     "python -u app.py"   5 minutes ago       Up About a minute                       otest_app_4
545d4fbbdd26        python:2-alpine     "python -u app.py"   5 minutes ago       Up 5 minutes                            otest_app_2
0f6860a859c1        python:2-alpine     "python -u app.py"   5 minutes ago       Up About a minute                       otest_app_3
a83dcc9ae7f1        python:2-alpine     "python -u app.py"   5 minutes ago       Up 5 minutes                            otest_app_1

無事、起動しています。

コンテナはスケールしやすさ、デプロイの容易さが仮想化と比較した場合のメリットですが、まだまだ枯れていない部分も見受けられます。ぜひ人柱となってコミュニティに貢献していきましょう。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*