如何在MacOS上诊断Docker的原因,特别是com.docker.hyperkit
使用100%的CPU?
Docker统计数据显示所有正在运行的容器的CPU,内存,网络IO和块IO均较低。
iosnoop显示com.docker.hyperkit
每秒执行约50次写入文件Docker.qcow2
的操作,总计每秒500KB。根据{{3}},Docker.qcow2
是一个稀疏文件,是所有Docker容器的持久存储。
就我而言,文件不是那么稀疏。物理大小与逻辑大小匹配。
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
在Docker主机上docker run -it --rm --pid host busybox top
docker嵌入式主机上的CPU使用率为〜3%。 MacBook上的CPU使用率约为100%。因此,docker嵌入式主机不会导致CPU使用率激增。
https://stackoverflow.com/a/58293240/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。 com.docker.hyperkit
在17秒内创建了1365个堆栈跟踪,其中 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
创建了平均每秒80个线程的线程。
const initialState = {
allIds:[],
byId:{},
};
const allIds = (state = initialState.allIds, action) => {
switch (action.type) {
case FETCH_IMAGES_SUCCESS:
return action.images.reduce((nextState, image) => {
if (nextState.indexOf(image.id) === -1) {
nextState.push(image.id);
}
return nextState;
}, [...state]);
case UPLOAD_IMAGE_SUCCESS:
console.log(action.data)
return [action.data.id, ...state];
case POST_COMMENT_SUCCESS:
console.log(action)
return [action.data.id, ...state];
default:
return state;
}
}
const image = (state = {}, action) => {
switch (action.type) {
case POST_COMMENT_SUCCESS:
return [...state.comments, action.data, ...state.comments]
default:
return state;
}
}
const byId = (state = initialState.byId, action) => {
switch (action.type) {
case FETCH_IMAGES_SUCCESS:
return action.images.reduce((nextState, image) => {
nextState[image.id] = image;
return nextState;
}, {...state});
case POST_COMMENT_SUCCESS:
console.log(action.data) // renders new commnent
return {
...state,
...state.comments,
[action.data.id]: action.data,
}
case UPLOAD_IMAGE_SUCCESS:
console.log(action)
return {
...state,
[action.data.id]: action.data,
};
default:
return state;
}
}
Github-docker / for-mac:https://stackoverflow.com/a/58293035/30900。有一条评论建议添加此处描述的卷缓存:com.docker.hyperkit 100% cpu usage is back again #3499 。我尝试了一下,CPU使用率降低了约10%。
答案 0 :(得分:2)
更改卷以使用委派配置对我来说很有效,并且导致CPU使用率急剧下降。 请参阅文档:https://docs.docker.com/docker-for-mac/osxfs-caching/#delegated
如何在我的docker-compose.yml中进行设置:
version: "3"
services:
my_service:
image: python3.6
ports:
- "80:10000"
volumes:
- ./code:/www/code:cached
对于我来说,这是可行的,macOS 10.15.5,Docker Desktop 2.3.0
答案 1 :(得分: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必须做更多的工作才能从适当进程的地址空间中获取它们。
Disabling System Integrity Protection可能会帮助您获得更好的堆栈跟踪。
有关更多详细信息,请参见DTrace Action Basics。
答案 2 :(得分:1)
我怀疑该问题与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引擎本身发生故障(例如,重新启动容器或运行大量运行状况检查),则可以通过观察以下输出来调试它:
docker events
答案 3 :(得分:0)
我有同样的问题。删除所有卷后,CPU%恢复正常。
docker system prune --volumes
我还手动删除了一些命名卷:
docker volume rm NameOfVolumeHere
这不能解决无法在Mac的Docker上使用卷的整体问题。现在,我只是在小心我使用的卷数量,并在不使用时关闭Docker桌面。
答案 4 :(得分:0)
编辑:几周后,我的 CPU 问题又回来了 - 所以下面的解决方案可能不值得
我的 CPU 总是运行得非常快,而不是 I/O,这是使用 docker stats
我做了很多事情,但在执行以下操作后,它突然降低到合理水平并保持这种状态一个多星期:
Preferences | Resources
Preferences | Resources
、/private、/tmp/、/var/foldersuse gRPC FUSE for file sharing
- Preferences | Resources
答案 5 :(得分:0)
禁用 use gRPC FUSE for file sharing
可能不是一个好主意。我从 docker 社区提出的另一个问题中找到了反馈。见下图:
So we'll look into that. However,
osxfs will not be supported long term.
We can't maintain two solutions.
答案 6 :(得分:-1)