การสร้างเธรดล้มเหลวด้วย“ ทรัพยากรไม่พร้อมใช้งานชั่วคราว” ด้วยเคอร์เนล 4.3


39

ฉันกำลังเรียกใช้เซิร์ฟเวอร์นักเทียบท่าบน Arch Linux (เคอร์เนล 4.3.3-2) พร้อมคอนเทนเนอร์หลายตัว ตั้งแต่รีบูตครั้งล่าสุดของฉันทั้งเซิร์ฟเวอร์นักเทียบท่าและโปรแกรมแบบสุ่มภายในคอนเทนเนอร์เกิดข้อผิดพลาดพร้อมกับข้อความว่าไม่สามารถสร้างเธรดหรือ (บ่อยกว่า) เพื่อแยก ข้อผิดพลาดที่เฉพาะเจาะจงจะแตกต่างกันขึ้นอยู่กับโปรแกรม Resource temporarily unavailableแต่ส่วนใหญ่ของพวกเขาดูเหมือนจะพูดถึงข้อผิดพลาดที่เฉพาะเจาะจง ดูที่ส่วนท้ายของโพสต์นี้เพื่อดูข้อความแสดงข้อผิดพลาด

ขณะนี้มีคนจำนวนมากที่ได้รับข้อความแสดงข้อผิดพลาดนี้และมีคำตอบมากมาย สิ่งที่น่าผิดหวังจริงๆคือทุกคนดูเหมือนจะคาดเดาว่าปัญหาจะสามารถแก้ไขได้อย่างไร แต่ดูเหมือนว่าไม่มีใครที่จะชี้ให้เห็นว่าจะระบุสาเหตุของปัญหาที่อาจเกิดขึ้นได้บ้าง

ฉันได้รวบรวมสาเหตุที่เป็นไปได้ 5 ข้อสำหรับข้อผิดพลาดและวิธีการตรวจสอบว่าไม่มีอยู่ในระบบของฉัน:

  1. มีข้อ จำกัด ทั้งระบบเกี่ยวกับจำนวนเธรดที่กำหนดค่าใน/proc/sys/kernel/threads-max( ซอร์ส ) 60613ในกรณีของฉันนี้ถูกตั้งค่า
  2. ทุกเธรดใช้พื้นที่บางส่วนในสแต็ก ขีด จำกัด ขนาดสแต็กถูกกำหนดค่าโดยใช้ulimit -s( แหล่งที่มา ) ข้อ จำกัด สำหรับเปลือกของฉันเคยเป็น8192แต่ฉันได้เพิ่มมันโดยใส่* soft stack 32768เข้าไป/etc/security/limits.confดังนั้นulimit -sตอนนี้มันกลับ32768มา ฉันได้เพิ่มมันสำหรับกระบวนการนักเทียบท่าด้วยการใส่LimitSTACK=33554432ลงไป/etc/systemd/system/docker.service( แหล่งที่มาและฉันตรวจสอบว่าข้อ จำกัด ที่ใช้โดยการดู/proc/<pid of docker>/limitsและโดยการทำงานulimit -sภายในคอนเทนเนอร์นักเทียบท่า
  3. ทุกเธรดใช้หน่วยความจำบางส่วน ulimit -vวงเงินหน่วยความจำเสมือนมีการกำหนดค่าการใช้ ในระบบของฉันมีการตั้งค่าunlimitedและ 80% ของหน่วยความจำ 3 GB ของฉันว่าง
  4. มีการ จำกัด ulimit -uจำนวนของกระบวนการที่ใช้คือ หัวข้อนับเป็นกระบวนการในกรณีนี้ (ที่มา ) ในระบบของฉัน จำกัด การตั้งค่าไป30306และสำหรับภูตนักเทียบท่าและภาชนะบรรจุนักเทียบท่าอยู่ภายในขีด จำกัด 1048576คือ จำนวนเธรดที่รันอยู่ในปัจจุบันสามารถพบได้โดยการรันls -1d /proc/*/task/* | wc -lหรือโดยการรันps -elfT | wc -l( ซอร์ส ) ในระบบของฉันที่พวกเขาอยู่ระหว่างและ700800
  5. มีข้อ จำกัด เกี่ยวกับจำนวนไฟล์ที่เปิดซึ่งตามแหล่งที่มาบางส่วนก็มีความเกี่ยวข้องเมื่อสร้างเธรด ขีด จำกัด ulimit -nการกำหนดค่าการใช้ ในระบบและนักเทียบท่าภายในของฉัน จำกัด 1048576การตั้งค่าไป จำนวนไฟล์ที่เปิดที่สามารถพบได้ออกมาใช้lsof | wc -l( แหล่งที่มา ) 30000ในระบบของฉันมันเป็นเรื่องเกี่ยวกับ

ดูเหมือนว่าก่อนที่จะรีบูตครั้งล่าสุดที่ฉันใช้เคอร์เนล 4.2.5-1 ตอนนี้ฉันกำลังใช้ 4.3.3-2 การลดระดับเป็น 4.2.5-1 ช่วยแก้ไขปัญหาทั้งหมด โพสต์อื่น ๆ กล่าวขวัญปัญหาอยู่นี้และนี้ ผมได้เปิดรายงานข้อผิดพลาดสำหรับ Arch ลินุกซ์

มีการเปลี่ยนแปลงอะไรในเคอร์เนลที่อาจทำให้เกิดปัญหานี้?


นี่คือตัวอย่างข้อความผิดพลาด:

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

1
คุณเพิ่งอัพเกรดเป็นเคอร์เนล 4.3 หรือไม่?
Roni Choudhury

เป็นไปได้มาก ทำไม?
cdauth

1
น่าทึ่งฉันลดระดับเป็นเคอร์เนล 4.2.5-1 และทุกอย่างทำงานได้อีกครั้ง! คุณมีเงื่อนงำอะไรที่ทำให้เกิดปัญหานี้และวิธีแก้ไขด้วย 4.3?
cdauth

ไม่มีเงื่อนงำสิ่งที่ทำให้เกิด วิธีการแก้ไขของฉันกำลังรอให้หัวข้อฟอรัม Arch Linux ในหัวข้อถูกทำเครื่องหมาย "แก้ไข" :-P
Roni Choudhury

1
+1 สำหรับการเป็นคำถามที่ยอดเยี่ยมและค้นคว้าแม้ว่าฉันจะไม่ได้มีปัญหาเดียวกัน
Roy Truelove

คำตอบ:


47

ปัญหาเกิดจากTasksMaxแอตทริบิวต์ systemd มันถูกนำมาใช้ใน systemd 228 และใช้ประโยชน์จากระบบย่อย cgroups pid ซึ่งถูกนำมาใช้ในเคอร์เนลลินุกซ์ 4.3 ข้อ จำกัด ของภารกิจ512ถูกเปิดใช้งานใน systemd หากเคอร์เนล 4.3 หรือใหม่กว่ากำลังทำงาน คุณลักษณะถูกประกาศที่นี่และได้รับการแนะนำในคำขอดึงนี้และค่าเริ่มต้นถูกตั้งค่าโดยคำขอดึงนี้ หลังจากอัพเกรดเคอร์เนลของฉันเป็น 4.3 systemctl status dockerแสดง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

การตั้งค่าTasksMax=infinityใน[Service]ส่วนของการdocker.serviceแก้ไขปัญหา docker.serviceมักจะอยู่ใน/usr/share/systemd/systemแต่ก็สามารถใส่ / คัดลอก/etc/systemd/systemเพื่อหลีกเลี่ยงการถูกแทนที่โดยผู้จัดการแพคเกจ

คำขอดึงจะเพิ่มขึ้นTasksMaxเช่นนักเทียบท่า systemd ไฟล์และรายงานข้อผิดพลาด Arch Linuxพยายามที่จะบรรลุเดียวกันสำหรับแพคเกจ มีบางอภิปรายเพิ่มเติมที่เกิดขึ้นในโค้งลินุกซ์ฟอรั่มและในรายงานข้อผิดพลาดเกี่ยวกับ Arch Linux LXC

DefaultTasksMaxสามารถนำมาใช้ใน[Manager]ส่วนใน/etc/systemd/system.conf(หรือ/etc/systemd/user.confสำหรับการให้บริการที่ผู้ใช้เรียกใช้) TasksMaxเพื่อควบคุมค่าเริ่มต้นสำหรับ

Systemd ยังใช้ข้อ จำกัด สำหรับโปรแกรมที่รันจาก login-shell เริ่มต้นเหล่านี้เพื่อ4096ต่อผู้ใช้ (จะเพิ่มขึ้น12288 ) และมีการกำหนดค่าเป็นUserTasksMaxในส่วนของ[Login]/etc/systemd/logind.conf


1
FWIW ไฟล์บริการอยู่/lib/systemd/system/docker.serviceในการทดสอบ Debian ของฉัน
คอมไพเลอ

2
FWIW การพูดsystemctl set-property docker.service TasksMax=4096จะตั้งค่าคุณสมบัติสำหรับบริการที่กำลังทำงานอยู่และยืนยันการตั้งค่าสำหรับการรีบูตครั้งต่อไปในตำแหน่งที่ถูกต้องสำหรับการติดตั้งตัวเทียบท่า
Nakedible

นี้เป็นวิธีการที่พบบ่อย แต่โปรดทราบว่าการเปลี่ยนแปลงนักเทียบท่าที่คุณเสนอนั้นถูกเปลี่ยนกลับหลังจากที่คุณโพสต์คำตอบนี้ในวันที่ 2016-02-09 การพลิกกลับนี้จะถูกเผยแพร่สู่โลกใน Docker เวอร์ชัน 1.10.1
JdeBP

คนขอบคุณขอบคุณขอบคุณ! ฉันได้รับการมองหา tooooo นานสำหรับเรื่องนี้
achabahe

หากคุณเปลี่ยนแปลงไฟล์ config (เหมืองอยู่ใน/etc/systemd/system/docker.service.d/50-TasksMax.confบน Ubuntu 16) systemctl daemon-reloadคุณจะต้องวิ่ง การทำsudo service docker restartจะไม่ทำงาน
osman

4

คำตอบของ cdauth นั้นถูกต้อง แต่มีรายละเอียดเพิ่มเติมที่จะเพิ่ม

บนระบบ Ubuntu 16.04 ของฉันที่มี systemd 229 และ 4.3 เคอร์เนลมีการบังคับใช้ขีด จำกัด 512 pid บนขอบเขตการใช้งานตามค่าเริ่มต้นแม้ว่า UserTasksMax จะถูกตั้งค่าเป็นค่าเริ่มต้นใหม่ที่เพิ่มขึ้น 12288 ดังนั้นขอบเขตเซสชันผู้ใช้จึง จำกัด อยู่ที่ 512 เธรด

วิธีเดียวที่ฉันพบว่าลบข้อ จำกัด คือการตั้งค่าDefaultTasksMax=unlimitedใน/etc/systemd/system.confและsystemctl daemon-reexec(หรือรีบูต)

คุณสามารถตรวจสอบว่านี้เกิดขึ้นโดยการออกยกขอบเขตเซสชั่นและsystemctl statuscat /sys/fs/cgroup/pids/user.slice/user-${UID}.slice/session-FOO.scope/pids.max


ฉันทำการเปลี่ยนแปลงเป็น /etc/systemd/system.conf และทำการรีบูท นักเทียบท่ายังคงแสดงรายการขีด จำกัด ของงานเป็น 512 การใช้ความคิดเห็นของ @ Nakedible จากด้านบนได้อัปเดตงานที่มีอยู่
Ben Mathews

1
ขอบคุณ Ryan! @BenMathews อาจเป็นเพราะทั้งคู่เป็นปัญหาที่ถูกต้องใน Ubuntu 16.04 คุณต้องแก้ไขทั้งสองอย่างเพื่อให้สิ่งต่าง ๆ ทำงานได้อย่างถูกต้อง ปัญหานี้ดูเหมือนว่าจะนำไปใช้กับคอนเทนเนอร์ที่เริ่มต้นโดย daemon ไม่ใช่โดยผู้ใช้ในเชลล์ ดังนั้นทุกอย่างดูเหมือนจะดีคุณเพิ่ม@reboot lxc-autostartcrontab ของคุณเพื่อเริ่มต้นโดยอัตโนมัติเมื่อบูตและคุณก็จะได้รับภาชนะบรรจุพิการหลังจากรีบูต
qris

1

หลังจากที่ได้อ่านนี้ด้าย

วิธีนี้ใช้ได้ผลสำหรับฉัน: docker -d --exec-opt native.cgroupdriver=cgroupfs. ฉันเพิ่มลงOPTIONSใน/etc/sysconfig/docker...

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.