A criação de threads falha com o "recurso temporariamente indisponível" com o kernel 4.3


39

Estou executando um servidor docker no Arch Linux (kernel 4.3.3-2) com vários contêineres. Desde a minha última reinicialização, o servidor de docker e os programas aleatórios nos contêineres falham com uma mensagem sobre a impossibilidade de criar um encadeamento ou (com menos frequência) de bifurcar. A mensagem de erro específica é diferente dependendo do programa, mas a maioria delas parece mencionar o erro específico Resource temporarily unavailable. Veja no final deste post alguns exemplos de mensagens de erro.

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

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

  1. Há um limite para todo o sistema no número de threads configurados em /proc/sys/kernel/threads-max( origem ). No meu caso, isso está definido como 60613.
  2. Cada thread ocupa algum espaço na pilha. O limite de tamanho da pilha é configurado usando ulimit -s( origem ). O limite para o meu shell costumava ser 8192, mas eu o aumentei colocando * soft stack 32768em /etc/security/limits.conf, então ele ulimit -sagora retorna 32768. Também a ampliei para o processo da janela de encaixe, inserindo LimitSTACK=33554432em /etc/systemd/system/docker.service( source) e verifiquei que o limite se aplica examinando /proc/<pid of docker>/limitse executando ulimit -sdentro de um contêiner de janela de encaixe.
  3. Cada thread ocupa um pouco de memória. Um limite de memória virtual é configurado usando ulimit -v. No meu sistema, ele está definido como unlimitede 80% dos meus 3 GB de memória estão livres.
  4. Há um limite no número de processos usando ulimit -u. Threads contam como processos neste caso ( origem ). No meu sistema, o limite é definido como 30306, e para o daemon de encaixe e dentro dos contêineres de encaixe, o limite é 1048576. O número de threads em execução no momento pode ser encontrado executando ls -1d /proc/*/task/* | wc -lou executando ps -elfT | wc -l( origem ). No meu sistema eles estão entre 700e 800.
  5. Há um limite no número de arquivos abertos, o que, de acordo com algumas fontes, também é relevante ao criar threads. O limite é configurado usando ulimit -n. No meu sistema e na janela de encaixe, o limite está definido como 1048576. O número de arquivos abertos pode ser encontrado usando lsof | wc -l( fonte ), no meu sistema 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 4.2.5-1 corrige todos os problemas. Outras postagens mencionando o problema são isso e isso . Abri um relatório de bug para o Arch Linux .

O que mudou no kernel que pode estar causando isso?


Aqui estão alguns exemplos de mensagens de erro:

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

11
Você atualizou recentemente para o kernel 4.3?
Roni Choudhury

Isso é muito bem possível. Por quê?
Cdauth

11
Incrível, fiz o downgrade para o kernel 4.2.5-1 e tudo está funcionando novamente! Você tem alguma idéia do que está causando isso e como corrigi-lo com o 4.3?
Cdauth

Nenhuma pista do que está causando isso. Meu método de corrigi-lo está aguardando que os tópicos do fórum do Arch Linux sobre o tópico sejam marcados "RESOLVIDO" :-P.
Roni Choudhury

11
+1 Por ser uma pergunta excelente pediu e pesquisado, mesmo se eu não tenho o mesmo problema
Roy Truelove

Respostas:


47

O problema é causado pelo TasksMaxatributo systemd. Foi introduzido no systemd 228 e faz uso do subsistema pid do cgroups, que foi introduzido no kernel 4.3 do linux. Um limite de tarefas de 512é ativado no systemd se o kernel 4.3 ou mais recente estiver em execução. O recurso é anunciado aqui e foi introduzido nesta solicitação de recebimento e os valores padrão foram definidos por essa solicitação de recebimento . Depois de atualizar meu kernel para 4.3, systemctl status dockerexibe uma Taskslinha:

# 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 TasksMax=infinityna [Service]seção docker.servicecorrige o problema. docker.servicegeralmente está dentro /usr/share/systemd/system, mas também pode ser colocado / copiado /etc/systemd/systempara evitar que seja substituído pelo gerenciador de pacotes.

Uma solicitação pull está aumentando TasksMaxpara os arquivos systemd de exemplo do docker, e um relatório de erro do Arch Linux está tentando obter o mesmo para o pacote. Há alguma discussão adicional em andamento no Arch Linux Forum e em um relatório de erro do Arch Linux sobre o lxc .

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

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


11
FWIW, o arquivo de serviço estava no /lib/systemd/system/docker.servicemeu teste Debian.
A Compiler

2
FWIW, dizendo systemctl set-property docker.service TasksMax=4096definirá a propriedade para um serviço em execução no momento e persistirá a configuração para reinicializações subsequentes no local correto para a instalação do docker em questão.
Nakedible 08/04

Essa é uma abordagem comum . Mas observe que a alteração do Docker que você propôs foi revertida após a publicação desta resposta, em 09/02/2016, sendo essa reversão lançada ao mundo no Docker versão 1.10.1.
JdeBP

homem obrigado obrigado obrigado! i foram à procura de tooooo longo para este
achabahe

Se você fizer a alteração no arquivo de configuração (o meu estava no /etc/systemd/system/docker.service.d/50-TasksMax.confUbuntu 16), você precisará executar systemctl daemon-reload. Fazer um sudo service docker restartNÃO funcionará.
Osman

4

A resposta do cdauth está correta, mas há outro detalhe a acrescentar.

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

A única maneira que encontrado para remover o limite foi definido DefaultTasksMax=unlimitedem /etc/systemd/system.confe 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.


Fiz a alteração para /etc/systemd/system.conf e reiniciei. O Docker ainda lista o limite de tarefas como 512. O uso do comentário de @ Nakedible acima atualizou as tarefas disponíveis.
Ben Mathews

11
Obrigado Ryan! @BenMathews talvez isso foi porque ambos são questões válidas no Ubuntu 16.04, você precisa corrigi-los tanto para que as coisas funcionem corretamente. Esse problema parece se aplicar a contêineres iniciados por um daemon, não por um usuário em um shell. Portanto, tudo parece bem, você adiciona @reboot lxc-autostartao seu crontab para iniciá-lo automaticamente na inicialização e, de repente, você recebe contêineres danificados após a reinicialização.
Qris 29/05

1

Depois de ler este tópico.

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

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.