¿Cómo diagnostico la causa de Docker en MacOS, específicamente com.docker.hyperkit
usando el 100% de la CPU?
Estadísticas de Docker
Las estadísticas de Docker muestran que todos los contenedores en ejecución tienen poca CPU, memoria, IO neto y IO bloqueado.
iosnoop
iosnoop muestra que com.docker.hyperkit
realiza alrededor de 50 escrituras por segundo con un total de 500 KB por segundo en el archivo Docker.qcow2
. De acuerdo con ¿Qué es Docker.qcow2? , Docker.qcow2
es un archivo disperso que es el almacenamiento persistente para todos los contenedores Docker.
En mi caso, el archivo no es tan escaso. El tamaño físico coincide con el tamaño lógico.
dtrace (dtruss)
dtruss sudo dtruss -p $DOCKER_PID
muestra una gran cantidad de psynch_cvsignal
y psynch_cvwait
llamadas.
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
Actualización: top
en el host Docker
Desde https://stackoverflow.com/a/58293240/30900 :
docker run -it --rm --pid host busybox top
El uso de CPU en el host integrado de Docker es de ~ 3%. El uso de la CPU en mi MacBook fue de ~ 100%. Por lo tanto, el host integrado docker no está causando el pico de uso de la CPU.
Actualización: ejecutar scripts dtrace de los seguimientos de pila más comunes
Apile las trazas de los scripts de dtrace en la respuesta a continuación: https://stackoverflow.com/a/58293035/30900 .
Estos rastros de la pila del kernel parecen inocuos.
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
Los rastros de pila más comunes en el espacio del usuario durante 17 segundos implican claramente com.docker.hyperkit. Hay 1365 seguimientos de pila en 17 segundos en los que se com.docker.hyperkit
crean hilos que promedian 80 hilos por segundo.
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
Asuntos relacionados
Github - docker / for-mac: com.docker.hyperkit El uso del 100% de la CPU está de vuelta nuevamente # 3499 . Un comentario sugiere agregar el almacenamiento en caché de volumen descrito aquí: https://www.docker.com/blog/user-guided-caching-in-docker-for-mac/ . Intenté esto y obtuve una pequeña reducción del 10% en el uso de la CPU.
Respuestas:
Tengo el mismo problema. Mi CPU% volvió a la normalidad después de que eliminé todos mis volúmenes.
También eliminé manualmente algunos volúmenes con nombre:
Eso no resuelve el problema general de no poder usar volúmenes con Docker para mac. En este momento solo estoy teniendo cuidado con la cantidad de volúmenes que uso y cerrando el escritorio de Docker cuando no estoy en uso.
fuente
Mi sospecha es que el problema está relacionado con IO. Con los volúmenes de MacOS, esto implica osxfs donde hay algunos ajustes de rendimiento que puede realizar. Principalmente, si puede aceptar menos comprobaciones de consistencia, puede configurar el modo de volumen
delegated
para un rendimiento más rápido. Consulte los documentos para obtener más detalles: https://docs.docker.com/docker-for-mac/osxfs-caching/ . Sin embargo, si su imagen contiene una gran cantidad de archivos pequeños, el rendimiento se verá afectado, especialmente si también tiene muchas capas de imágenes.También puede probar el siguiente comando para depurar cualquier problema de proceso dentro de la VM incorporada que utiliza la ventana acoplable:
(Para salir, use
<ctrl>-c
)Para rastrear si es IO, también puede intentar lo siguiente:
Eso se ejecutará dentro del contenedor alpino que se ejecuta en el espacio de nombres pid de VM, mostrando cualquier E / S que ocurra desde cualquier proceso, ya sea que ese proceso esté o no dentro de un contenedor. Las estadísticas son cada 5 segundos durante un minuto (12 veces) y luego le dará una tabla promedio por proceso. Entonces puedes
<ctrl>-d
destruir el contenedor alpino.De los comentarios y ediciones, estas estadísticas pueden ver. Un MBP de 4 núcleos tiene 8 subprocesos, por lo que la utilización total de la CPU debería ser del 800% si MacOS informa lo mismo que otros sistemas basados en Unix. Dentro de la VM hay más del 100% de carga que se muestra en el comando superior para el promedio en el último minuto (aunque menos de los promedios 5 y 15), que es aproximadamente lo que se ve para el proceso de hiperkit en el host. El uso instantáneo es superior al 12% desde la parte superior, no al 3%, ya que debe agregar el sistema y los porcentajes de usuario. Y los números IO que se muestran en pidstat se alinean aproximadamente con lo que ves escrito en la imagen qcow2.
Si el motor de la ventana acoplable se está agitando (por ejemplo, reiniciando contenedores o ejecutando muchas comprobaciones de estado), puede depurarlo observando la salida de:
fuente
delegated
pero no hubo mejora en el rendimiento. Ejecuté eltop
comando en la VM incorporada, pero el uso de la CPU rondaba el ~ 3%.pidstat
para rastrear mejor los problemas de E / S.pidstat
muestra lecturas para todos los PID son 0 kB / s. Para escrituras:logwrite
escribe 8.5kB / s en promedio yinfluxd
escribe 0.61kB / s en promedio. El resto de los procesos son 0.Este es un pequeño script de dTrace que uso para encontrar dónde el kernel pasa su tiempo (es de Solaris y se remonta a los primeros días de Solaris 10):
Simplemente muestra los rastros de la pila del núcleo y cuenta cada uno que encuentra en la
@hot
agregación.Ejecútelo como root:
Deje que se ejecute durante una cantidad de tiempo decente mientras tiene problemas con la CPU, luego presione
CTRL-C
para romper el script. Emitirá todos los rastros de la pila del núcleo que encontró, el último más común. Si necesita más (o menos) marcos de pila por defecto conEso mostrará un marco de pila de 15 llamadas de profundidad.
Las últimas trazas de la pila serán donde su núcleo pasa la mayor parte de su tiempo. Eso puede o no ser informativo.
Este script hará lo mismo para los seguimientos de pila de espacio de usuario:
Ejecútelo de manera similar:
ustack()
es un poco más lento: para emitir los nombres de funciones reales, dTrace tiene que hacer mucho más trabajo para obtenerlos de los espacios de direcciones de los procesos apropiados.Deshabilitar la Protección de integridad del sistema puede ayudarlo a obtener mejores rastros de pila.
Consulte DTrace Action Basics para obtener más detalles.
fuente