在Mac版Docker上诊断CPU使用率过高


20

如何在MacOS上诊断Docker的原因,特别是com.docker.hyperkit使用100%的CPU?

docker CPU使用率

Docker统计

Docker统计数据显示所有正在运行的容器的CPU,内存,网络IO和块IO均较低。

docker stats输出

iosnoop

iosnoop显示com.docker.hyperkit每秒执行约50次写入,总计每秒写入500KB Docker.qcow2。根据什么是Docker.qcow2?Docker.qcow2是一个稀疏文件,该文件是为所有Docker容器的持久存储。

就我而言,文件不是那么稀疏。物理大小与逻辑大小匹配。

docker.qcow实际大小

dtrace(dtruss)

dtruss sudo dtruss -p $DOCKER_PID显示大量的psynch_cvsignalpsynch_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在Docker主机上

https://stackoverflow.com/a/58293240/30900

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

Docker嵌入式主机上的CPU使用率约为3%。MacBook上的CPU使用率约为100%。因此,Docker嵌入式主机不会引起CPU使用率高峰。

docker主机顶部

更新:运行最常见的堆栈跟踪的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。在17秒内有1365个堆栈跟踪,其中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- docker / for-mac:com.docker.hyperkit 100%的CPU使用率再次返回#3499 。有一条评论建议添加此处描述的卷缓存:https : //www.docker.com/blog/user-guided-caching-in-docker-for-mac/。我尝试了一下,CPU使用率降低了约10%。


您正在建立图片吗?我还将关注执行大量块IO的容器。是否启用Kubernetes也很重要。
BMitch

1
构建集群并运行几分钟后,我收集了所有指标。Kubernetes已禁用。但是,没有一台机器执行很多块IO。容器什么也没做。我注意到CPU使用率似乎与容器数量大致相关。

您的计算机上有多少个内核/ cpu?
BMitch

另外,您是否尝试过重启docker,而不是容器,而是整个引擎和桌面客户端?
BMitch

我正在运行具有4个内核的2018 MBP 2.8 GHz Core i7。我尝试调整Docker引擎的CPU内核数。我尝试了1、3、4和6核。限制使用docker将CPU使用率从100%降低到60%。

Answers:


5

我也有同样的问题。删除所有卷后,CPU%恢复正常。

docker system prune --volumes

我还手动删除了一些命名卷:

docker volume rm NameOfVolumeHere

这不能解决无法在Mac的Docker上使用卷的整体问题。现在,我只是在小心我使用的卷数量,并在不使用时关闭Docker桌面。


3

我怀疑该问题与IO相关。对于MacOS卷,这涉及osxfs,您可以执行一些性能调整。主要是,如果您可以接受较少的一致性检查,则可以将音量模式设置为delegated获得更快的性能。请参阅文档以获取更多详细信息:https : //docs.docker.com/docker-for-mac/osxfs-caching/。但是,如果您的图像包含大量小文件,则性能会受到影响,尤其是在您还有很多图像层的情况下。

您也可以尝试使用以下命令来调试docker使用的嵌入式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核MBP具有8个线程,因此,如果MacOS报告与其他基于Unix的系统相同,则CPU的总利用率应为800%。在虚拟机内部,过去一分钟的平均值显示在top命令中的负载超过100%(尽管低于5和15的平均值),这与主机上的hyperkit进程大致相同。由于您需要添加系统百分比和用户百分比,因此瞬时使用率最高时超过12%,而不是3%。pidstat中显示的IO编号与您看到的写入qcow2映像的大致对齐。


如果泊坞窗引擎本身正在运行(例如重新启动容器或运行大量运行状况检查),则可以通过观察以下输出来调试该引擎:

docker events

我将所有卷安装更改为,delegated但性能没有改善。我top在嵌入式VM上运行了该命令,但CPU使用率徘徊在3%左右。

更新了pidstat以更好地跟踪IO问题。
BMitch

pidstat显示所有PID的读数均为0 kB / s。对于写入:logwrite平均influxd写入8.5kB / s,平均写入0.61kB / s。过程的其余部分是0。

1

这是一个小的dTrace脚本,我用它来查找内核在哪里花费时间(它来自Solaris,其历史可以追溯到Solaris 10的早期):

#!/usr/sbin/dtrace -s

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

它仅对内核堆栈跟踪进行采样,并对在@hot聚合中遇到的每个计数进行计数。

以root身份运行:

... # ./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


谢谢,我用脚本的结果更新了问题。用户空间堆栈跟踪显示com.docker.hyperkit创建了很多线程。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.