¿Cuál es el costo de rendimiento en tiempo de ejecución de un contenedor Docker?
Me gustaría comprender de manera integral el costo de rendimiento en tiempo de ejecución de un contenedor Docker. He encontrado referencias anecdóticamente a que las redes son ~100 µs más lentas .
También encontré referencias a que el costo del tiempo de ejecución es "insignificante" y "cercano a cero", pero me gustaría saber con mayor precisión cuáles son esos costos. Idealmente, me gustaría saber qué está abstrayendo Docker con un costo de rendimiento y qué cosas se abstraen sin un costo de rendimiento. Redes, CPU, memoria, etc.
Además, si existen costos de abstracción, ¿hay formas de evitarlos? Por ejemplo, quizás pueda montar un disco directamente en lugar de hacerlo virtualmente en Docker.
Un excelente artículo de investigación de IBM de 2014 “ Una comparación de rendimiento actualizada de máquinas virtuales y contenedores Linux ” de Felter et al. proporciona una comparación entre contenedores bare metal, KVM y Docker. El resultado general es: Docker tiene un rendimiento casi idéntico al nativo y más rápido que KVM en todas las categorías.
La excepción a esto es NAT de Docker: si utiliza el mapeo de puertos (por ejemplo, docker run -p 8080:8080
), puede esperar un pequeño impacto en la latencia, como se muestra a continuación. Sin embargo, ahora puede usar la pila de red del host (por ejemplo, docker run --net=host
) al iniciar un contenedor Docker, que funcionará de manera idéntica a la columna Nativa (como se muestra en los resultados de latencia de Redis más abajo).
También realizaron pruebas de latencia en algunos servicios específicos, como Redis. Puede ver que por encima de 20 subprocesos de cliente, la sobrecarga de latencia más alta es Docker NAT, luego KVM y luego un vínculo aproximado entre Docker host/nativo.
Sólo porque es un artículo realmente útil, aquí hay algunas otras cifras. Descárguelo para obtener acceso completo.
Echando un vistazo a la E/S del disco:
Ahora mirando la sobrecarga de la CPU:
Ahora algunos ejemplos de memoria (lea el artículo para obtener más detalles, la memoria puede ser muy complicada):
Docker no es virtualización como tal; en cambio, es una abstracción además del soporte del kernel para diferentes espacios de nombres de procesos, espacios de nombres de dispositivos, etc.; un espacio de nombres no es inherentemente más caro o ineficiente que otro, por lo que lo que realmente hace que Docker tenga un impacto en el rendimiento es una cuestión de lo que realmente hay en esos espacios de nombres.
Las opciones de Docker en términos de cómo configura los espacios de nombres para sus contenedores tienen costos, pero todos esos costos están directamente asociados con los beneficios: puede renunciar a ellos, pero al hacerlo también renuncia al beneficio asociado:
- Los sistemas de archivos en capas son costosos: los costos exactos varían con cada uno (y Docker admite múltiples backends) y con sus patrones de uso (fusionar varios directorios grandes o fusionar un conjunto muy profundo de sistemas de archivos será particularmente costoso), pero No eres libre. Por otro lado, gran parte de la funcionalidad de Docker (poder crear invitados a partir de otros invitados mediante copia en escritura y obtener las ventajas de almacenamiento implícitas en las mismas) depende del pago de este costo.
- DNAT resulta costoso a escala, pero le brinda el beneficio de poder configurar la red de sus invitados independientemente de la de su anfitrión y tener una interfaz conveniente para reenviar solo los puertos que desee entre ellos. Puede reemplazar esto con un puente a una interfaz física, pero nuevamente, perderá el beneficio.
- Poder ejecutar cada pila de software con sus dependencias instaladas de la manera más conveniente (independientemente de la distribución, libc y otras versiones de la biblioteca del host) es un gran beneficio, pero tener que cargar bibliotecas compartidas más de una vez (cuando sus versiones difieren) tiene el costo que esperarías.
Etcétera. El impacto real de estos costos en su entorno (con sus patrones de acceso a la red, sus limitaciones de memoria, etc.) es un elemento para el cual es difícil proporcionar una respuesta genérica.