¿Cuál es el costo de rendimiento de tiempo de ejecución de un contenedor Docker?

512

Me gustaría comprender exhaustivamente el costo de rendimiento en tiempo de ejecución de un contenedor Docker. He encontrado referencias a redes que anecdóticamente son ~ 100 µs más lentas .

También he encontrado referencias a que el costo de 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 cosas que se resumen sin un costo de rendimiento. Redes, CPU, memoria, etc.

Además, si hay costos de abstracción, ¿hay formas de evitar el costo de abstracción? Por ejemplo, quizás pueda montar un disco directamente vs. virtualmente en Docker.

Luke Hoersten
fuente
1
@GoloRoden esa pregunta es similar pero no exactamente la misma. Estoy buscando costos de latencia con razones como "la red se está pasando a través de una capa adicional", mientras que la respuesta aceptada de esa pregunta es más sobre la medición de los costos de la aplicación contenedor +.
Luke Hoersten
1
De acuerdo, eso es correcto. Me retracté de mi voto cercano.
Golo Roden
8
Aunque me alegra que lo hayas publicado. Esa pregunta no apareció en mi búsqueda. El artículo sobre medidas / métricas es muy útil: blog.docker.io/2013/10/gathering-lxc-docker-containers-metrics
Luke Hoersten
1
Esta es una buena sesión titulada "Contenedores de Linux: virtualización de NextGen para la nube" que cuenta las métricas de rendimiento comparando docker, KVM VM y bare metal: youtube.com/watch?v=a4oOAVhNLjU
shawmzhu

Respuestas:

449

Un excelente trabajo de investigación de IBM 2014 " Una comparación de rendimiento actualizada de máquinas virtuales y contenedores de Linux " por Felter et al. proporciona una comparación entre los contenedores de metal desnudo, KVM y Docker. El resultado general es: Docker es casi idéntico al rendimiento nativo y más rápido que KVM en todas las categorías.

La excepción a esto es el NAT de Docker: si usa la asignación de puertos (por ejemplo, docker run -p 8080:8080), puede esperar un golpe menor en la latencia, como se muestra a continuación. Sin embargo, ahora puede usar la pila de red del host (p. Ej. 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).

Docker NAT sobrecarga

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 va a Docker NAT, luego a KVM, luego a un vínculo aproximado entre el host Docker / nativo.

Docker Redis Latencia de arriba

Solo porque es un documento realmente útil, aquí hay algunas otras figuras. Descárguelo para tener acceso completo.

Echando un vistazo a Disk I / O:

Docker vs. KVM vs. Rendimiento de E / S nativas

Ahora mirando la sobrecarga de la CPU:

Docker CPU Overhead

Ahora, algunos ejemplos de memoria (lea el documento para más detalles, la memoria puede ser muy complicada):

Comparación de memoria de Docker

Hamy
fuente
20
En cuanto a los números de linpack que figuran en el documento ... francamente, me resulta difícil de creer (no es que no crea que son lo que emitió linpack, sino que no creo que la prueba realmente no midiera nada más que el rendimiento de coma flotante). realizado). La mayor sobrecarga de KVM está en los componentes de emulación de hardware del espacio de usuario (que solo se aplican al hardware sin CPU ); hay una sobrecarga significativa alrededor de la paginación de memoria ... pero ¿punto flotante sin procesar? Me gustaría ver lo que realmente estaba sucediendo allí, tal vez cambios de contexto excesivos.
Charles Duffy
2
Corrección para la sintaxis actual de Docker CLI: --net=host(dos guiones) y -p 8080:8080(minúscula 'p') para NAT.
bk0
66
El documento de IBM citado parece demasiado centrado en la red IO. Nunca trata los cambios de contexto. Examinamos LXC y tuvimos que abandonarlo rápidamente debido al aumento de los cambios de contexto no voluntarios que da como resultado un procesamiento degradado de la aplicación.
Eric
3
También tengo curiosidad sobre las operaciones del sistema de archivos: las búsquedas de directorios, por ejemplo, son un lugar donde esperaría ver sobrecarga; las lecturas, escrituras y búsquedas a nivel de bloque (en las que los gráficos dados se centran en gran medida) no lo son .
Charles Duffy
12
Me encantan los gráficos con el mismo color de sombra. Es tan fácil de distinguir
Viktor Joras,
104

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 costoso 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 esos costos están directamente asociados con los beneficios: puede renunciar a ellos, pero al hacerlo también renuncia a los beneficios asociados:

  • Los sistemas de archivos en capas son caros: los costos varían exactamente con cada uno (y Docker admite múltiples backends), y con sus patrones de uso (fusionar múltiples directorios grandes o fusionar un conjunto muy profundo de sistemas de archivos será particularmente costoso), pero No eres libre. Por otro lado, una gran parte de la funcionalidad de Docker, que es capaz de construir invitados a partir de otros invitados de una manera copia y escritura, y obtener las ventajas de almacenamiento implícitas en el mismo, depende de pagar este costo.
  • DNAT se vuelve caro a gran escala, pero le brinda la ventaja de poder configurar la red de su invitado independientemente de la de su host y tener una interfaz conveniente para reenviar solo los puertos que desea entre ellos. Puede reemplazar esto con un puente a una interfaz física, pero nuevamente, pierda el beneficio.
  • Poder ejecutar cada pila de software con sus dependencias instaladas de la manera más conveniente, independientemente de la distribución, la biblioteca y otras versiones de la biblioteca del host, es un gran beneficio, pero necesita cargar las bibliotecas compartidas más de una vez (cuando sus versiones diferir) tiene el costo que esperarías.

Etcétera. Cuánto cuestan realmente estos costos en su entorno, con sus patrones de acceso a la red, sus limitaciones de memoria, etc., es un elemento para el que es difícil proporcionar una respuesta genérica.

Charles Duffy
fuente
2
Esta es una buena respuesta, pero estoy buscando números y puntos de referencia más específicos. Estoy familiarizado con el costo de cgroups, pero Docker es más que eso, como has señalado. Muchas gracias por la respuesta.
Luke Hoersten
66
Por supuesto. Mi punto es que cualquier punto de referencia generalizado que encuentre será de aplicabilidad muy limitada a cualquier aplicación específica, pero eso no quiere decir que no esté de acuerdo con la gente que intenta proporcionarlos, sino simplemente que deben tomarse con una cucharada colmada de sal.
Charles Duffy
1
De esa manera se podría decir que KVM "no es una virtualización, es simplemente una abstracción sobre las llamadas de tecnología virtual x86".
Vad
10
@Vad, existe un acuerdo de consenso, desde hace décadas (¡hasta las primeras implementaciones de hardware no x86 de IBM!), Que proporcionar abstracción directamente en la capa de hardware es una virtualización inequívoca. El consenso para la terminología en torno al espacio de nombres a nivel del núcleo está considerablemente más fragmentado (podríamos señalar fuentes que favorecen nuestras opiniones individuales), pero, francamente, existen distinciones técnicas útiles (en torno a las características de seguridad y rendimiento) que oscurecer a un solo término oscurecería , así que mantengo mi posición hasta que se llegue a un consenso contrario de la industria.
Charles Duffy el
@LukeHoersten, ... cierto, no son los cgroups los que tienen un costo significativo, es mucho más el contenido de la red y los espacios de nombres del sistema de archivos. Pero cuánto son esos costos depende casi por completo de cómo está configurado Docker, qué backends específicos está utilizando. Bridging es mucho, mucho más barato que el NAT predeterminado de Docker, por ejemplo; y la sobrecarga del rendimiento de los diversos sistemas de archivos también varía enormemente (y en algunos casos, la cantidad de sobrecarga depende de los patrones de uso; las variantes de superposición pueden ser mucho más caras con grandes directorios modificados a través de múltiples capas f / e).
Charles Duffy
20

Aquí hay algunos puntos de referencia más en Docker based memcached servercomparación host native memcached servercon el uso de la herramienta de referencia Twemperf https://github.com/twitter/twemperf con 5000 conexiones y una velocidad de conexión de 20k

La sobrecarga de tiempo de conexión para Memcached basada en Docker parece estar de acuerdo con el documento técnico anterior a aproximadamente el doble de la velocidad nativa.

Twemperf Docker Memcached

Connection rate: 9817.9 conn/s
Connection time [ms]: avg 341.1 min 73.7 max 396.2 stddev 52.11
Connect time [ms]: avg 55.0 min 1.1 max 103.1 stddev 28.14
Request rate: 83942.7 req/s (0.0 ms/req)
Request size [B]: avg 129.0 min 129.0 max 129.0 stddev 0.00
Response rate: 83942.7 rsp/s (0.0 ms/rsp)
Response size [B]: avg 8.0 min 8.0 max 8.0 stddev 0.00
Response time [ms]: avg 28.6 min 1.2 max 65.0 stddev 0.01
Response time [ms]: p25 24.0 p50 27.0 p75 29.0
Response time [ms]: p95 58.0 p99 62.0 p999 65.0

Twemperf Centmin Mod Memcached

Connection rate: 11419.3 conn/s
Connection time [ms]: avg 200.5 min 0.6 max 263.2 stddev 73.85
Connect time [ms]: avg 26.2 min 0.0 max 53.5 stddev 14.59
Request rate: 114192.6 req/s (0.0 ms/req)
Request size [B]: avg 129.0 min 129.0 max 129.0 stddev 0.00
Response rate: 114192.6 rsp/s (0.0 ms/rsp)
Response size [B]: avg 8.0 min 8.0 max 8.0 stddev 0.00
Response time [ms]: avg 17.4 min 0.0 max 28.8 stddev 0.01
Response time [ms]: p25 12.0 p50 20.0 p75 23.0
Response time [ms]: p95 28.0 p99 28.0 p999 29.0

Aquí hay puntos de referencia utilizando la herramienta de referencia memtier

memtier_benchmark docker Memcached

4         Threads
50        Connections per thread
10000     Requests per thread
Type        Ops/sec     Hits/sec   Misses/sec      Latency       KB/sec
------------------------------------------------------------------------
Sets       16821.99          ---          ---      1.12600      2271.79
Gets      168035.07    159636.00      8399.07      1.12000     23884.00
Totals    184857.06    159636.00      8399.07      1.12100     26155.79

memtier_benchmark Centmin Mod Memcached

4         Threads
50        Connections per thread
10000     Requests per thread
Type        Ops/sec     Hits/sec   Misses/sec      Latency       KB/sec
------------------------------------------------------------------------
Sets       28468.13          ---          ---      0.62300      3844.59
Gets      284368.51    266547.14     17821.36      0.62200     39964.31
Totals    312836.64    266547.14     17821.36      0.62200     43808.90
p4guru
fuente
1
Comparan dos compilaciones diferentes de memcached, y también una de ellas en docker, otra fuera de docker, ¿no es así?
San
44
¿Son estos resultados con redes de host o redes de puente en Docker?
akaHuman
13
Con tan grandes estándares, estas mediciones no muestran ningún dato representableavg 200.5 min 0.6 max 263.2 stddev 73.85
Sergey Zhukov