¿Cómo diagnostico la causa de Docker en MacOS, específicamente com.docker.hyperkit usando el 100 % de la CPU?
Las estadísticas de Docker muestran que todos los contenedores en ejecución tienen poca CPU, memoria, E/S de red y E/S de bloque.
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 . Según ¿Qué es Docker.qcow2? , Docker.qcow2 es un archivo disperso que es el almacenamiento persistente para todos los contenedores de Docker.
En mi caso, el archivo no es tan escaso. El tamaño físico coincide con el tamaño lógico.
dtruss sudo dtruss -p $DOCKER_PID muestra una gran cantidad de llamadas psynch_cvsignal y 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#316top en el host DockerDesde https://stackoverflow.com/a/58293240/30900 :
docker run -it --rm --pid host busybox topEl uso de la CPU en el host integrado de la ventana acoplable es ~3 %. El uso de la CPU en mi MacBook fue ~100%. Por lo tanto, el host integrado de la ventana acoplable no está causando el pico de uso de la CPU.
Apile los seguimientos de los scripts de dtrace en la respuesta a continuación: https://stackoverflow.com/a/58293035/30900 .
Estos rastros de la pila del núcleo 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 seguimientos de pila más comunes en el espacio del usuario durante 17 segundos implican claramente a com.docker.hyperkit. Hay 1365 seguimientos de pila en 17 segundos en los que com.docker.hyperkit creó subprocesos con un promedio de 80 subprocesos 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 135Github - docker/for-mac: com.docker.hyperkit El 100 % del uso de la CPU está de regreso #3499 . Un comentario sugiere agregar 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 de ~10% en el uso de la CPU.
Tengo el mismo problema. Mi porcentaje de CPU volvió a la normalidad después de eliminar todos mis volúmenes.
docker system prune --volumesTambién eliminé manualmente algunos volúmenes con nombre:
docker volume rm NameOfVolumeHereEso 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 cierro el escritorio de Docker cuando no está en uso.
Esta es una pequeña secuencia de comandos de dTrace que utilizo para encontrar dónde pasa el tiempo el kernel (es de Solaris y se remonta a los primeros días de Solaris 10):
#!/usr/sbin/dtrace -s profile:::profile-1001hz /arg0/ { @[ stack() ] = count(); } Simplemente toma muestras de los rastros de la pila del kernel y cuenta cada uno que encuentra en la agregación @ .
Ejecutarlo como root:
... # ./kernelhotspots.d > /tmp/kernel_hot_spots.txt Deje que se ejecute durante un tiempo decente mientras tiene problemas con la CPU, luego presione CTRL-C para romper el script. Emitirá todos los rastros de la pila del kernel que encuentre, el último más común. Si necesita más (o menos) marcos de pila de los predeterminados con
@[ stack( 15 ) ] = count();Eso mostrará un marco de pila de 15 llamadas de profundidad.
Los últimos rastros de la pila serán donde su kernel pasa la mayor parte de su tiempo. Eso puede o no ser informativo.
Esta secuencia de comandos hará lo mismo para los seguimientos de la pila en el espacio del usuario:
#!/usr/sbin/dtrace -s profile:::profile-1001hz /arg1/ { @[ ustack() ] = count(); }Ejecútelo de manera similar:
... # ./userspacehotspots.d > /tmp/userspace_hot_spots.txt 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 podría ayudarlo a obtener mejores seguimientos de pila.
Consulte Conceptos básicos de la acción de DTrace para obtener más detalles.
Mi sospecha es que el problema está relacionado con IO. Con los volúmenes de MacOS, esto involucra osxfs donde hay algunos ajustes de rendimiento que puede realizar. Principalmente, si puede aceptar menos comprobaciones de coherencia, puede establecer el modo de volumen en 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 máquina virtual integrada que usa la ventana acoplable:
docker run -it --rm --pid host busybox top (Para salir, use <ctrl>-c )
Para rastrear si es IO, también puede probar lo siguiente:
$ docker run -it --rm --pid host alpine /bin/sh $ apk add sysstat $ pidstat -d 5 12 Eso se ejecutará dentro del contenedor alpine que se ejecuta en el espacio de nombres pid de VM, mostrando cualquier IO 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. Luego puede <ctrl>-d para destruir el contenedor alpino.
A partir de los comentarios y ediciones, estas estadísticas pueden comprobarse. 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 máquina virtual, se muestra más del 100 % de carga en el comando superior para el promedio en el último minuto (aunque menos de los promedios de 5 y 15), que es aproximadamente lo que ve para el proceso de hiperkit en el host. El uso instantáneo es superior al 12% desde arriba, no al 3%, ya que debe agregar los porcentajes del sistema y del usuario. Y los números de IO que se muestran en pidstat se alinean aproximadamente con lo que ve escrito en la imagen qcow2.
Si el propio motor de la ventana acoplable está fallando (p. ej., reiniciando contenedores o ejecutando muchas comprobaciones de estado), entonces puede depurarlo observando el resultado de:
docker eventsCambiar los volúmenes para usar una configuración delegada funcionó para mí y resultó en una caída drástica en el uso de la CPU. consulte el documento: https://docs.docker.com/docker-for-mac/osxfs-caching/#delegated
cómo configurar en mi docker-compose.yml:
version: "3" services: my_service: image: python3.6 ports: - "80:10000" volumes: - ./code:/www/code:cachedPara mí esto funcionó, macOS 10.15.5, Docker Desktop 2.3.0
deshabilitar use gRPC FUSE for file sharing podría no ser una buena idea. Encontré los comentarios de otro problema realizado por la comunidad docker. Ver abajo:
So we'll look into that. However, osxfs will not be supported long term. We can't maintain two solutions.Sin embargo,So we'll look into that. However, osxfs will not be supported long term. We can't maintain two solutions.
EDITAR: después de algunas semanas, mis problemas con la CPU han regresado, por lo que las soluciones a continuación probablemente no valgan la pena
Mi CPU siempre funcionaba a un nivel muy alto y no era E/S, según lo determinado mediante docker stats
Hice un montón de cosas, pero de repente disminuyó a niveles razonables y permaneció así durante más de una semana, después de hacer lo siguiente:
Preferences | ResourcesPreferences | Resources , /privado, /tmp/, /var/carpetasuse gRPC FUSE for file sharing - Preferences | ResourcesLa solución que encontré fue aumentar los recursos dados a Docker. Aumenté la memoria de 2 GB a 8 GB, el intercambio de 1 GB a 2 GB y el tamaño de la imagen del disco a 160 GB. Resolvió completamente el problema para mí, y es fácil de probar para los lectores.