การวินิจฉัยการใช้งาน CPU สูงใน Docker สำหรับ Mac


20

ฉันจะวินิจฉัยสาเหตุของ Docker บน MacOS ได้อย่างไรโดยเฉพาะการcom.docker.hyperkitใช้ CPU 100%

การใช้งาน CPU นักเทียบท่า

สถิตินักเทียบท่า

สถิตินักเทียบท่าแสดงให้เห็นว่าคอนเทนเนอร์ที่ใช้งานอยู่ทั้งหมดมี CPU, หน่วยความจำ, Net IO และ Block IO ต่ำ

เอาต์พุตสถิตินักเทียบท่า

iosnoop

iosnoop แสดงให้เห็นว่าcom.docker.hyperkitการดำเนินการประมาณ 50 เขียนต่อวินาทีรวมเป็นเงินทั้งสิ้น 500 Docker.qcow2กิโลไบต์ต่อวินาทีไปยังแฟ้ม ตามDocker.qcow2 คืออะไร , Docker.qcow2เป็นไฟล์เบาบางที่จัดเก็บข้อมูลถาวรสำหรับทุกตู้คอนเทนเนอร์หาง

ในกรณีของฉันไฟล์ไม่กระจัดกระจาย ขนาดฟิสิคัลตรงกับขนาดโลจิคัล

ขนาดที่แท้จริง docker.qcow

dtrace (dtruss)

dtruss sudo dtruss -p $DOCKER_PIDแสดงจำนวนpsynch_cvsignalและการpsynch_cvwaitโทรจำนวนมาก

psynch_cvsignal(0x7F9946002408, 0x4EA701004EA70200, 0x4EA70100)          = 257 0
psynch_mutexdrop(0x7F9946002318, 0x5554700, 0x5554700)           = 0 0
psynch_mutexwait(0x7F9946002318, 0x5554702, 0x5554600)           = 89474819 0
psynch_cvsignal(0x10BF7B470, 0x4C8095004C809600, 0x4C809300)             = 257 0
psynch_cvwait(0x10BF7B470, 0x4C8095014C809600, 0x4C809300)               = 0 0
psynch_cvwait(0x10BF7B470, 0x4C8096014C809700, 0x4C809600)               = -1 Err#316
psynch_cvsignal(0x7F9946002408, 0x4EA702004EA70300, 0x4EA70200)          = 257 0
psynch_cvwait(0x7F9946002408, 0x4EA702014EA70300, 0x4EA70200)            = 0 0
psynch_cvsignal(0x10BF7B470, 0x4C8097004C809800, 0x4C809600)             = 257 0
psynch_cvwait(0x10BF7B470, 0x4C8097014C809800, 0x4C809600)               = 0 0
psynch_cvwait(0x10BF7B470, 0x4C8098014C809900, 0x4C809800)               = -1 Err#316

อัพเดท: topบนโฮสต์นักเทียบท่า

จากhttps://stackoverflow.com/a/58293240/30900 :

docker run -it --rm --pid host busybox top

การใช้งาน CPU บนโฮสต์ที่ฝังตัวนักเทียบท่าคือ ~ 3% การใช้ CPU ใน MacBook ของฉันคือ ~ 100% ดังนั้นโฮสต์ที่ฝังตัวนักเทียบท่าจะไม่ทำให้การใช้งาน CPU สูงขึ้น

นักโฮสต์ด้านบนโฮสต์

อัพเดต: การรันสคริปต์ dtrace ของการติดตามสแต็กทั่วไป

ร่องรอยสแต็คจากสคริปต์ DTrace ในคำตอบดังต่อไปนี้: https://stackoverflow.com/a/58293035/30900

การติดตามสแต็กเคอร์เนลเหล่านี้ดูไม่เป็นอันตราย

              AppleIntelLpssGspi`AppleIntelLpssGspi::regRead(unsigned int)+0x1f
              AppleIntelLpssGspi`AppleIntelLpssGspi::transferMmioDuplexMulti(void*, void*, unsigned long long, unsigned int)+0x91
              AppleIntelLpssSpiController`AppleIntelLpssSpiController::transferDataMmioDuplexMulti(void*, void*, unsigned int, unsigned int)+0xb2
              AppleIntelLpssSpiController`AppleIntelLpssSpiController::_transferDataSubr(AppleInfoLpssSpiControllerTransferDataRequest*)+0x5bc
              AppleIntelLpssSpiController`AppleIntelLpssSpiController::_transferData(AppleInfoLpssSpiControllerTransferDataRequest*)+0x24f
              kernel`IOCommandGate::runAction(int (*)(OSObject*, void*, void*, void*, void*), void*, void*, void*, void*)+0x138
              AppleIntelLpssSpiController`AppleIntelLpssSpiDevice::transferData(IOMemoryDescriptor*, void*, unsigned long long, unsigned long long, IOMemoryDescriptor*, void*, unsigned long long, unsigned long long, unsigned int, AppleIntelSPICompletion*)+0x151
              AppleHSSPISupport`AppleHSSPIController::transferData(IOMemoryDescriptor*, void*, unsigned long long, unsigned long long, IOMemoryDescriptor*, void*, unsigned long long, unsigned long long, unsigned int, AppleIntelSPICompletion*)+0xcc
              AppleHSSPISupport`AppleHSSPIController::doSPITransfer(bool, AppleHSSPITransferRetryReason*)+0x97
              AppleHSSPISupport`AppleHSSPIController::InterruptOccurred(IOInterruptEventSource*, int)+0xf8
              kernel`IOInterruptEventSource::checkForWork()+0x13c
              kernel`IOWorkLoop::runEventSources()+0x1e2
              kernel`IOWorkLoop::threadMain()+0x2c
              kernel`call_continuation+0x2e
               53

              kernel`waitq_wakeup64_thread+0xa7
              pthread`__psynch_cvsignal+0x495
              pthread`_psynch_cvsignal+0x28
              kernel`psynch_cvsignal+0x38
              kernel`unix_syscall64+0x27d
              kernel`hndl_unix_scall64+0x16
               60

              kernel`hndl_mdep_scall64+0x4
              113

              kernel`ml_set_interrupts_enabled+0x19
              524

              kernel`ml_set_interrupts_enabled+0x19
              kernel`hndl_mdep_scall64+0x10
             5890

              kernel`machine_idle+0x2f8
              kernel`call_continuation+0x2e
            43395

การติดตามสแต็กที่พบบ่อยที่สุดในพื้นที่ของผู้ใช้ในช่วง 17 วินาทีแสดงให้เห็นอย่างชัดเจนว่า com.docker.hyperkit มีการติดตามสแต็ก 1365 ครั้งใน 17 วินาทีซึ่งcom.docker.hyperkitสร้างเธรดซึ่งเฉลี่ยถึง 80 เธรดต่อวินาที

              com.docker.hyperkit`0x000000010cbd20db+0x19f9
              com.docker.hyperkit`0x000000010cbdb98c+0x157
              com.docker.hyperkit`0x000000010cbf6c2d+0x4bd
              libsystem_pthread.dylib`_pthread_body+0x7e
              libsystem_pthread.dylib`_pthread_start+0x42
              libsystem_pthread.dylib`thread_start+0xd
               19

              Hypervisor`hv_vmx_vcpu_read_vmcs+0x1
              com.docker.hyperkit`0x000000010cbd4c4f+0x2a
              com.docker.hyperkit`0x000000010cbd20db+0x174a
              com.docker.hyperkit`0x000000010cbdb98c+0x157
              com.docker.hyperkit`0x000000010cbf6c2d+0x4bd
              libsystem_pthread.dylib`_pthread_body+0x7e
              libsystem_pthread.dylib`_pthread_start+0x42
              libsystem_pthread.dylib`thread_start+0xd
               22

              Hypervisor`hv_vmx_vcpu_read_vmcs
              com.docker.hyperkit`0x000000010cbdb98c+0x157
              com.docker.hyperkit`0x000000010cbf6c2d+0x4bd
              libsystem_pthread.dylib`_pthread_body+0x7e
              libsystem_pthread.dylib`_pthread_start+0x42
              libsystem_pthread.dylib`thread_start+0xd
               34

              com.docker.hyperkit`0x000000010cbd878d+0x36
              com.docker.hyperkit`0x000000010cbd20db+0x42f
              com.docker.hyperkit`0x000000010cbdb98c+0x157
              com.docker.hyperkit`0x000000010cbf6c2d+0x4bd
              libsystem_pthread.dylib`_pthread_body+0x7e
              libsystem_pthread.dylib`_pthread_start+0x42
              libsystem_pthread.dylib`thread_start+0xd
               47

              Hypervisor`hv_vcpu_run+0xd
              com.docker.hyperkit`0x000000010cbd20db+0x6b6
              com.docker.hyperkit`0x000000010cbdb98c+0x157
              com.docker.hyperkit`0x000000010cbf6c2d+0x4bd
              libsystem_pthread.dylib`_pthread_body+0x7e
              libsystem_pthread.dylib`_pthread_start+0x42
              libsystem_pthread.dylib`thread_start+0xd
              135

ประเด็นที่เกี่ยวข้อง

Github - นักเทียบท่า / สำหรับ Mac: com.docker.hyperkit การใช้งาน CPU 100% กลับมาอีกครั้ง # ความคิดเห็นหนึ่งที่แสดงให้เห็นการเพิ่มปริมาณการแคชอธิบายไว้ที่นี่: https://www.docker.com/blog/user-guided-caching-in-docker-for-mac/ ฉันลองสิ่งนี้และลดการใช้งาน CPU ลงเล็กน้อย ~ 10%


คุณกำลังสร้างภาพหรือไม่ ฉันยังมุ่งเน้นไปที่ภาชนะบรรจุที่มีประสิทธิภาพเป็นจำนวนมากบล็อก IO นอกจากนี้ยังสำคัญว่าคุณเปิดใช้งาน Kubernetes หรือไม่
BMitch

1
ฉันรวบรวมการวัดทั้งหมดหลังจากสร้างและเรียกใช้คลัสเตอร์เป็นเวลาสองสามนาที Kubernetes ถูกปิดใช้งาน ไม่มีเครื่องจักรใดทำการบล็อก IO ได้มากมาย ภาชนะไม่ได้ทำอะไรเลย ฉันสังเกตว่าการใช้งาน CPU นั้นสัมพันธ์กับจำนวนของคอนเทนเนอร์อย่างเกะกะ
โจ

คุณมีแกน / cpu กี่ตัวบนเครื่อง?
BMitch

นอกจากนี้คุณได้ลองรีสตาร์ทเครื่องเทียบท่าไม่ใช่คอนเทนเนอร์ แต่เป็นเอ็นจิ้นและเดสก์ท็อปไคลเอ็นต์ทั้งหมด
BMitch

ฉันใช้ 2018 MBP 2.8 GHz Core i7 ที่มี 4 คอร์ ฉันพยายามปรับแต่งจำนวนแกน CPU สำหรับเอ็นจิ้น Docker ฉันลอง 1, 3, 4 และ 6 แกน การ จำกัด ให้นักเทียบท่าลดการใช้งาน CPU จาก 100% เป็น 60%
Joe

คำตอบ:


5

ผมมีปัญหาเดียวกัน. CPU% ของฉันกลับมาเป็นปกติหลังจากลบโวลุ่มทั้งหมดของฉัน

docker system prune --volumes

ฉันยังลบโวลุ่มที่มีชื่อบางส่วนออกด้วยตนเอง:

docker volume rm NameOfVolumeHere

แต่นั่นไม่ได้แก้ปัญหาโดยรวมของการไม่สามารถใช้งานไดรฟ์กับ Docker สำหรับ mac ตอนนี้ฉันแค่ระวังปริมาณที่ฉันใช้และปิดเดสก์ท็อป Docker เมื่อไม่ใช้งาน


3

ความสงสัยของฉันคือปัญหาเกี่ยวข้องกับ IO ด้วยโวลุ่ม MacOS สิ่งนี้เกี่ยวข้องกับ osxfs ซึ่งมีการปรับแต่งประสิทธิภาพบางอย่างที่คุณสามารถทำได้ หากคุณยอมรับการตรวจสอบความสอดคล้องน้อยลงคุณสามารถตั้งค่าโหมดเสียงให้delegatedมีประสิทธิภาพเร็วขึ้น ดูเอกสารเพื่อดูรายละเอียดเพิ่มเติมได้ที่: https://docs.docker.com/docker-for-mac/osxfs-caching/ อย่างไรก็ตามหากรูปภาพของคุณมีไฟล์ขนาดเล็กจำนวนมากประสิทธิภาพจะลดลงโดยเฉพาะถ้าคุณมีเลเยอร์รูปภาพจำนวนมาก

คุณยังสามารถลองใช้คำสั่งต่อไปนี้เพื่อตรวจแก้จุดบกพร่องปัญหากระบวนการใด ๆ ภายใน VM แบบฝังที่นักเทียบท่าใช้:

docker run -it --rm --pid host busybox top

(หากต้องการออกให้ใช้<ctrl>-c)


หากต้องการติดตามว่าเป็น IO คุณสามารถลองทำสิ่งต่อไปนี้:

$ docker run -it --rm --pid host alpine /bin/sh
$ apk add sysstat
$ pidstat -d 5 12

ที่จะทำงานภายในอัลไพน์คอนเทนเนอร์ที่ทำงานในเนมสเปซ VM pid แสดง IO ใด ๆ ที่เกิดขึ้นจากกระบวนการใด ๆ ไม่ว่ากระบวนการนั้นจะอยู่ภายในคอนเทนเนอร์หรือไม่ สถิติทุกๆ 5 วินาทีเป็นเวลาหนึ่งนาที (12 ครั้ง) จากนั้นจะให้ตารางเฉลี่ยต่อกระบวนการ จากนั้นคุณสามารถ<ctrl>-dทำลายภาชนะอัลไพน์


จากความคิดเห็นและการแก้ไขสถิติเหล่านี้อาจตรวจสอบ 4 core MBP มี 8 เธรดดังนั้นการใช้งาน CPU อย่างเต็มรูปแบบควรเป็น 800% หาก MacOS รายงานเช่นเดียวกับระบบที่ใช้ Unix อื่น ๆ ภายใน VM มีโหลดมากกว่า 100% ที่แสดงในคำสั่งด้านบนสำหรับค่าเฉลี่ยในนาทีที่ผ่านมา (แม้ว่าจะน้อยกว่าค่าเฉลี่ย 5 และ 15) ซึ่งเป็นสิ่งที่คุณเห็นสำหรับกระบวนการไฮเปอร์คิตบนโฮสต์ การใช้งานทันทีมากกว่า 12% จากด้านบนไม่ใช่ 3% เนื่องจากคุณต้องเพิ่มระบบและเปอร์เซ็นต์ผู้ใช้ และหมายเลข IO ที่แสดงใน pidstat จะจัดตำแหน่งให้ตรงกับสิ่งที่คุณเห็นในภาพ qcow2


หากเครื่องยนต์ของนักเทียบท่าเองกำลังฟาดฟัน (เช่นการรีสตาร์ทคอนเทนเนอร์หรือวิ่งเฮลช์เช็คจำนวนมาก) คุณสามารถทำการดีบั๊กได้โดยดูผลลัพธ์จาก:

docker events

ฉันเปลี่ยนไดรฟ์ข้อมูลทั้งหมดเป็นdelegatedแต่ไม่มีการปรับปรุงประสิทธิภาพ ฉันรันtopคำสั่งบน VM ที่ฝังไว้ แต่การใช้ CPU วนเวียนอยู่รอบ ๆ ~ 3%
โจ

อัปเดตด้วยpidstatเพื่อติดตามปัญหา IO ที่ดีขึ้น
BMitch

pidstatแสดงการอ่านสำหรับ PID ทั้งหมดคือ 0 kB / s สำหรับการเขียน: logwriteเขียนโดยเฉลี่ยinfluxd8.5kB / s และเขียน 0.61kB / s โดยเฉลี่ย กระบวนการที่เหลือคือ 0
Joe

1

นี่เป็นสคริปต์ dTrace ขนาดเล็กที่ฉันใช้เพื่อค้นหาว่าเคอร์เนลใช้เวลาที่ไหน (มาจากโซลาริสและย้อนกลับไปในยุคแรก ๆ ของโซลาริส 10):

#!/usr/sbin/dtrace -s

profile:::profile-1001hz
/arg0/
{
    @[ stack() ] = count();
}

มันเพียงแค่ตัวอย่างการติดตามเคอร์เนลสแต็กและนับแต่ละรายการที่พบในการ@hotรวม

เรียกใช้เป็นราก:

... # ./kernelhotspots.d > /tmp/kernel_hot_spots.txt

ปล่อยให้มันทำงานในช่วงเวลาที่เหมาะสมในขณะที่คุณมีปัญหาเกี่ยวกับ CPU จากนั้นกดCTRL-Cเพื่อหยุดสคริปต์ มันจะปล่อยเคอร์เนลสแต็กทั้งหมดตามที่พบบ่อยครั้งล่าสุด หากคุณต้องการเฟรมสแต็กมากกว่า (หรือน้อยกว่า) จากค่าเริ่มต้นด้วย

    @[ stack( 15 ) ] = count();

ที่จะแสดงสแต็กเฟรม 15 สายลึก

การติดตามสแต็กไม่กี่ครั้งล่าสุดจะเป็นที่ที่เคอร์เนลของคุณใช้เวลาส่วนใหญ่ นั่นอาจจะใช่หรือไม่ใช่ก็ได้

สคริปต์นี้จะทำเช่นเดียวกันสำหรับการติดตามสแต็กพื้นที่ผู้ใช้:

#!/usr/sbin/dtrace -s

profile:::profile-1001hz
/arg1/
{
    @[ ustack() ] = count();
}

เรียกใช้ในทำนองเดียวกัน:

... # ./userspacehotspots.d > /tmp/userspace_hot_spots.txt

ustack() ช้าลงเล็กน้อย - เพื่อปล่อยชื่อฟังก์ชั่นที่แท้จริง dTrace ต้องทำงานให้มากขึ้นเพื่อให้ได้มาจากช่องว่างที่อยู่ของกระบวนการที่เหมาะสม

การปิดใช้งานการป้องกันความสมบูรณ์ของระบบอาจช่วยให้คุณได้รับการติดตามสแต็กที่ดีขึ้น

ดูDTrace Action Basicsสำหรับรายละเอียดเพิ่มเติม


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