En muchas publicaciones de blog y opiniones generales, hay un dicho que dice "un proceso por contenedor".
¿Por qué existe esta regla? ¿Por qué no ejecutar ntp, nginx, uwsgi y más procesos en un solo contenedor que necesita tener todos los procesos para funcionar?
publicaciones de blog que mencionan esta regla:
- "El proceso único por contenedor es un patrón de diseño recomendado para aplicaciones Docker".
- "Docker es solo para crear contenedores de un solo proceso o de un solo servicio".
- "mejor usar un proceso por contenedor"
- "Ejecutar un solo servicio como contenedor"
- "Un proceso por contenedor"
- "un proceso por contenedor"
docker
containers
Evgeny
fuente
fuente
Respuestas:
Olvidemos los argumentos arquitectónicos y filosóficos de alto nivel por un momento. Si bien puede haber algunos casos extremos en los que varias funciones en un solo contenedor pueden tener sentido, existen razones muy prácticas por las que es posible que desee considerar seguir "una función por contenedor" como regla general:
Tenga en cuenta que estoy diciendo función, no proceso. Ese lenguaje está desactualizado. La documentación oficial de la ventana acoplable ha pasado de decir "un proceso" a recomendar "una preocupación" por contenedor.
fuente
Habiendo matado un contenedor de "dos procesos" hace unos días, hubo algunos puntos débiles para mí que me hicieron usar dos contenedores en lugar de un script de Python que inició dos procesos:
fuente
La recomendación proviene del objetivo y el diseño de la virtualización a nivel del sistema operativo
Los contenedores han sido diseñados para aislar un proceso para otros al darle su propio espacio de usuario y sistema de archivos.
Esta es la evolución lógica de
chroot
proporcionar un sistema de archivos aislado, el siguiente paso fue aislar los procesos de los demás para evitar sobrescrituras de memoria y permitir el uso del mismo recurso (por ejemplo, el puerto TCP 8080) de múltiples procesos sin conflictos.El interés principal en un contenedor es empaquetar la biblioteca necesaria para el proceso sin preocuparse por los conflictos de versión. Si ejecuta múltiples procesos que necesitan dos versiones de la misma biblioteca en el mismo espacio de usuario y sistema de archivos, tendría que ajustar al menos LDPATH para cada proceso para que la biblioteca adecuada se encuentre primero, y algunas bibliotecas no se pueden ajustar de esta manera, debido a que su ruta está codificada en el ejecutable en el momento de la compilación, vea esta pregunta SO para obtener más detalles.
A nivel de red, deberá configurar cada proceso para evitar el uso de los mismos puertos.
La ejecución de múltiples procesos en el mismo contenedor requiere algunos ajustes pesados y, al final del día, anula el propósito del aislamiento, si puede ejecutar múltiples procesos dentro del mismo espacio de usuario, compartiendo el mismo sistema de archivos y recursos de red, entonces ¿por qué no ejecutarlos? en el propio host?
Aquí está la lista no exhaustiva de los grandes ajustes / trampas que se me ocurren:
Manejando los troncos
Ya sea con un volumen montado o intercalado en stdout, esto trae algo de administración. Si usa un volumen montado, su contenedor debe tener su propio "lugar" en el host o dos mismos contenedores lucharán por el mismo recurso. Al intercalar en stdout para aprovecharlo
docker logs
, puede convertirse en una pesadilla para el análisis si las fuentes no se pueden identificar fácilmente.Cuidado con los procesos zombies
Si uno de los procesos en un contenedor se bloquea, es posible que el supervisor no pueda limpiar al niño en estado zombie, y el host init nunca los heredará. Una vez que haya agotado la cantidad de pids disponibles (2 ^ 22, aproximadamente 4 millones), un montón de cosas fallarán.
Separación de intereses
Si ejecuta dos cosas separadas, como un servidor apache y logstash dentro del mismo contenedor, eso puede facilitar el manejo de registros, pero debe apagar apache para actualizar logstash. (En realidad, debe usar el controlador de registro de Docker) ¿Será una parada elegante esperar a que finalicen las sesiones actuales o no? Si es una parada elegante, puede llevar algún tiempo y demorar mucho en lanzar la nueva versión. Si matas, afectarás a los usuarios de un cargador de troncos y eso debería evitarse en mi humilde opinión.
Finalmente, cuando tiene múltiples procesos, está reproduciendo un sistema operativo y, en este caso, usar una virtualización de hardware suena más acorde con esta necesidad.
fuente
Como en la mayoría de los casos, no es todo o nada. La guía de "un proceso por contenedor" se deriva de la idea de que los contenedores deben cumplir un propósito distinto. Por ejemplo, un contenedor no debe ser tanto una aplicación web como un servidor Redis.
Hay casos en los que tiene sentido ejecutar múltiples procesos en un solo contenedor, siempre que ambos procesos admitan una única función modular.
fuente
El proceso que llamaré como servicio aquí, 1 contenedor ~ 1 servicio , si alguno de mis servicios falla, entonces solo activaré ese contenedor respectivo y en cuestión de segundos todo volverá a funcionar. Por lo tanto, no habrá dependencias entre los servicios. Es una buena práctica mantener el tamaño de su contenedor por debajo de 200 MB y un máximo de 500 MB (la excepción a los contenedores nativos de Windows son más de 2 GB) de lo contrario, será similar a la máquina virtual, no exactamente, pero el rendimiento es suficiente. Además, tenga en cuenta algunos parámetros como el escalado, cómo podría hacer que mis servicios sean resistentes, se implementen automáticamente, etc.
Y es puramente su decisión cómo debe hacer sus patrones arquitectónicos como microservicio en un entorno polygot utilizando la tecnología de contenedores que mejor se adapta a su entorno y automatizará las cosas por usted.
fuente