A criação de threads falha com “Recurso temporariamente indisponível” com kernel 4.3

30

Estou executando um servidor docker no Arch Linux (kernel 4.3.3-2) com vários contêineres. Desde a minha última reinicialização, tanto o servidor docker quanto os programas aleatórios dentro dos contêineres travam com uma mensagem sobre não conseguir criar um encadeamento ou (menos frequentemente) para bifurcar. A mensagem de erro específica é diferente dependendo do programa, mas a maioria parece mencionar o erro específico Resource temporarily unavailable . Veja no final deste post algumas mensagens de erro de exemplo.

Agora, há muitas pessoas que receberam essa mensagem de erro e muitas respostas a elas. O que é realmente frustrante é que todos parecem estar especulando como o problema pode ser resolvido, mas ninguém parece apontar como identificar qual das muitas causas possíveis para o problema está presente.

Eu coletei estas 5 possíveis causas para o erro e como verificar se elas não estão presentes no meu sistema:

  1. Existe um limite para todo o sistema no número de segmentos configurados em /proc/sys/kernel/threads-max ( fonte ). No meu caso, isso é definido como 60613 .
  2. Cada thread ocupa algum espaço na pilha. O limite de tamanho de pilha é configurado usando ulimit -s ( fonte ). O limite do meu shell costumava ser 8192 , mas eu o adicionei colocando * soft stack 32768 em /etc/security/limits.conf , portanto, ulimit -s agora retorna 32768 . Eu também o adicionei para o processo do docker, colocando LimitSTACK=33554432 em /etc/systemd/system/docker.service ( fonte e verifiquei que o limite aplica-se analisando /proc/<pid of docker>/limits e executando ulimit -s dentro de um contêiner docker.
  3. Cada thread leva um pouco de memória. Um limite de memória virtual é configurado usando ulimit -v . No meu sistema, ele está definido como unlimited e 80% dos meus 3 GB de memória são gratuitos.
  4. Existe um limite no número de processos usando ulimit -u . Os threads contam como processos nesse caso ( source ). No meu sistema, o limite é definido como 30306 e, para o daemon do docker e dentro de contêineres do Docker, o limite é 1048576 . O número de threads atualmente em execução pode ser encontrado executando ls -1d /proc/*/task/* | wc -l ou executando ps -elfT | wc -l ( fonte ). No meu sistema, eles estão entre 700 e 800 .
  5. Existe um limite no número de arquivos abertos, que de acordo com alguns source s também é relevante ao criar threads. O limite é configurado usando ulimit -n . No meu sistema e dentro da janela de encaixe, o limite é definido como 1048576 . O número de arquivos abertos pode ser encontrado usando lsof | wc -l ( fonte ), em meu sistema é sobre 30000 .

Parece que, antes da última reinicialização, eu estava executando o kernel 4.2.5-1, agora estou executando o 4.3.3-2. O downgrade para o 4.2.5-1 corrige todos os problemas. Outros posts mencionando o problema são este e isso . Eu abri um relatório de erros para o Arch Linux .

O que mudou no kernel que poderia estar causando isso?

Aqui estão algumas mensagens de erro de exemplo:

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
    
por cdauth 07.01.2016 / 16:16

3 respostas

42

O problema é causado pelo TasksMax systemd atributo. Foi introduzido no systemd 228 e faz uso do subsistema pid do cgroups, que foi introduzido no kernel do Linux 4.3. Um limite de tarefa de 512 é assim habilitado no systemd se o kernel 4.3 ou mais recente estiver sendo executado. O recurso é anunciado aqui e foi introduzido no este pedido pull e os valores padrão foram definidos por este pedido pull . Após atualizar meu kernel para 4.3, systemctl status docker exibe uma linha Tasks :

# 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

A configuração de TasksMax=infinity na seção [Service] de docker.service corrige o problema. docker.service geralmente está em /usr/share/systemd/system , mas também pode ser colocado / copiado em /etc/systemd/system para evitar que seja substituído pelo gerenciador de pacotes.

Um pull request está aumentando TasksMax para os arquivos systemd de exemplo do docker e um Relatório de bugs do Arch Linux está tentando alcançar o mesmo para o pacote. Há alguma discussão adicional em no Arch Linux Forum e em um relatório de bug do Arch Linux sobre lxc .

DefaultTasksMax pode ser usado no [Manager] seção em /etc/systemd/system.conf (ou /etc/systemd/user.conf para serviços executados pelo usuário) para controlar o valor padrão para TasksMax .

O Systemd também aplica um limite para os programas executados a partir de um shell de login. Esses padrões para 4096 por usuário (serão aumentados para 12288 ) e são configurados como UserTasksMax na seção [Login] de /etc/systemd/logind.conf .

    
por 15.01.2016 / 20:18
3

A resposta da cdauth está correta, mas há outro detalhe para adicionar.

No meu sistema Ubuntu 16.04 com systemd 229 e um kernel 4.3, um limite de 512 pid foi aplicado nos escopos de sessão por padrão, mesmo quando UserTasksMax foi definido para o novo padrão aumentado de 12288. Portanto, qualquer escopo de sessão do usuário foi limitado a 512 threads.

A única maneira que encontrei de remover o limite foi definir DefaultTasksMax=unlimited em /etc/systemd/system.conf e systemctl daemon-reexec (ou reinicialização).

Você pode verificar se isso está acontecendo, emitindo systemctl status , escolhendo um escopo de sessão e cat /sys/fs/cgroup/pids/user.slice/user-${UID}.slice/session-FOO.scope/pids.max .

    
por 07.04.2016 / 07:03
1

Depois de ler o este tópico

.

Esta solução funcionou para mim: docker -d --exec-opt native.cgroupdriver=cgroupfs . Na verdade, adicionei-o ao OPTIONS in /etc/sysconfig/docker ...

    
por 15.11.2016 / 13:22