web-dev-qa-db-ja.com

4.3カーネルで「リソースが一時的に使用不可」でスレッドの作成が失敗する

いくつかのコンテナーを使用して、Arch Linux(カーネル4.3.3-2)でDockerサーバーを実行しています。前回の再起動以降、コンテナ内のdockerサーバーとランダムプログラムの両方がクラッシュし、スレッドを作成できない、または(あまり頻繁ではないが)forkできないというメッセージが表示されます。特定のエラーメッセージはプログラムによって異なりますが、それらのほとんどは特定のエラーResource temporarily unavailableについて言及しているようです。エラーメッセージの例については、この投稿の最後を参照してください。

現在、このエラーメッセージが表示された多くの人々と、それらに対する多くの応答があります。本当にイライラしているのは、誰もが問題を解決する方法を推測しているようですが、誰がどのように多くの可能なものを識別するかを指摘するようには見えないことです問題の原因が存在します。

エラーのこれらの5つの考えられる原因と、それらがシステムに存在しないことを確認する方法を収集しました。

  1. /proc/sys/kernel/threads-maxsource )で構成されたスレッドの数には、システム全体の制限があります。私の場合、これは60613に設定されています。
  2. すべてのスレッドは、スタック内のいくつかのスペースを使用します。スタックサイズの制限は、ulimit -ssource )を使用して構成されます。私のシェルの制限は以前は8192でしたが、* soft stack 32768/etc/security/limits.confに入れることでそれを増やしたため、ulimit -s32768を返すようになりました。 LimitSTACK=33554432/etc/systemd/system/docker.servicesource )に入れてDockerプロセス用にそれを増やしました。また、/proc/<pid of docker>/limitsを調べて実行することで制限が適用されることを確認しましたulimit -sはdockerコンテナー内にあります。
  3. すべてのスレッドはメモリを消費します。仮想メモリの制限は、ulimit -vを使用して構成されます。私のシステムではunlimitedに設定されており、3 GBのメモリの80%が解放されています。
  4. ulimit -uを使用するプロセスの数には制限があります。この場合、スレッドはプロセスとしてカウントされます( source )。私のシステムでは、制限は30306に設定されており、Dockerデーモンと内部のDockerコンテナーの場合、制限は1048576です。現在実行中のスレッドの数は、ls -1d /proc/*/task/* | wc -lを実行するか、ps -elfT | wc -lsource )を実行することで確認できます。私のシステムでは、それらは700800の間にあります。
  5. 開くファイルの数には制限があり、一部の source sによると、スレッドの作成時にも関係があります。制限はulimit -nを使用して構成されます。私のシステムと内部のDockerでは、制限は1048576に設定されています。開いているファイルの数はlsof | wc -lsource )を使用して確認できます。私のシステムでは約30000です。

前回の再起動前はカーネル4.2.5-1を実行していたようですが、現在は4.3.3-2を実行しています。 4.2.5-1にダウングレードすると、すべての問題が修正されます。問題に言及している他の投稿は this および this です。 Arch Linuxのバグレポート を開きました。

これを引き起こしている可能性のあるカーネルの変更点は何ですか?


エラーメッセージの例をいくつか示します。

Crash dump was written to: erl_crash.dump
Failed to create aux thread

Jan 07 14:37:25 edeltraud docker[30625]: runtime/cgo: pthread_create failed: Resource temporarily unavailable

dpkg: unrecoverable fatal error, aborting:
 fork failed: Resource temporarily unavailable
E: Sub-process /usr/bin/dpkg returned an error code (2)

test -z "/usr/include" || /usr/sbin/mkdir -p "/tmp/lib32-popt/pkg/lib32-popt/usr/include"
/bin/sh: fork: retry: Resource temporarily unavailable
 /usr/bin/install -c -m 644 popt.h '/tmp/lib32-popt/pkg/lib32-popt/usr/include'
test -z "/usr/share/man/man3" || /usr/sbin/mkdir -p "/tmp/lib32-popt/pkg/lib32-popt/usr/share/man/man3"
/bin/sh: fork: retry: Resource temporarily unavailable
/bin/sh: fork: retry: No child processes
/bin/sh: fork: retry: Resource temporarily unavailable
/bin/sh: fork: retry: No child processes
/bin/sh: fork: retry: No child processes
/bin/sh: fork: retry: Resource temporarily unavailable
/bin/sh: fork: retry: Resource temporarily unavailable
/bin/sh: fork: retry: No child processes
/bin/sh: fork: Resource temporarily unavailable
/bin/sh: fork: Resource temporarily unavailable
make[3]: *** [install-man3] Error 254

Jan 07 11:04:39 edeltraud docker[780]: time="2016-01-07T11:04:39.986684617+01:00" level=error msg="Error running container: [8] System error: fork/exec /proc/self/exe: resource temporarily unavailable"

[Wed Jan 06 23:20:33.701287 2016] [mpm_event:alert] [pid 217:tid 140325422335744] (11)Resource temporarily unavailable: apr_thread_create: unable to create worker thread
42
cdauth

この問題は TasksMax systemd属性が原因で発生します。これはsystemd 228で導入され、Linuxカーネル4.3で導入されたcgroups pidサブシステムを利用します。したがって、カーネル4.3以降が実行されている場合、systemdでは512のタスク制限が有効になります。この機能は ここ で発表され、 このプルリクエスト で導入され、デフォルト値は このプルリクエスト によって設定されました。カーネルを4.3にアップグレードした後、systemctl status dockerTasks行を表示します。

# systemctl status docker
● docker.service - Docker Application Container Engine
   Loaded: loaded (/etc/systemd/system/docker.service; disabled; vendor preset: disabled)
   Active: active (running) since Fri 2016-01-15 19:58:00 CET; 1min 52s ago
     Docs: https://docs.docker.com
 Main PID: 2770 (docker)
    Tasks: 502 (limit: 512)
   CGroup: /system.slice/docker.service

TasksMax=infinity[Service]セクションでdocker.serviceを設定すると、問題が解決します。 docker.serviceは通常/usr/share/systemd/systemにありますが、パッケージマネージャによってオーバーライドされないようにするために/etc/systemd/systemに配置/コピーすることもできます。

pull request はdockerサンプルsystemdファイルのTasksMaxを増やしており、- Arch Linuxバグレポート はパッケージに対して同じことを達成しようとしています。 Arch Linuxフォーラム および lxcに関するArch Linuxバグレポート について、いくつかの追加の議論が行われています。

DefaultTasksMax は、[Manager](またはユーザー実行サービスの場合は/etc/systemd/system.conf)の/etc/systemd/user.confセクションで使用して、TasksMaxのデフォルト値を制御できます。

Systemdは、ログインシェルから実行されるプログラムにも制限を適用します。これらはデフォルトでユーザーごとに4096になり(- 12288に増加 )、[Login]/etc/systemd/logind.confセクションで UserTasksMax として構成されます。

49
cdauth

cdauthの答えは正しいですが、追加する詳細がもう1つあります。

Systemd 229と4.3カーネルを搭載した私のUbuntu 16.04システムでは、UserTasksMaxが新しい拡張されたデフォルトの12288に設定されている場合でも、デフォルトでセッションスコープに512 pid制限が適用されました。したがって、ユーザーセッションスコープは512スレッドに制限されていました。

制限を解除する唯一の方法は、DefaultTasksMax=unlimited/etc/systemd/system.confsystemctl daemon-reexecに設定する(または再起動する)ことでした。

これが発生しているかどうかを確認するには、systemctl statusを発行し、セッションスコープを選択し、cat /sys/fs/cgroup/pids/user.slice/user-${UID}.slice/session-FOO.scope/pids.maxを選択します。

4

this スレッドを読んだ後。

このソリューションは私にとってうまくいきました:docker -d --exec-opt native.cgroupdriver=cgroupfs/etc/sysconfig/dockerOPTIONSに実際に追加しました...