Este blog explicará 10 antipatrones de contenedores que he visto en los últimos meses:
- Datos o registros en contenedores - Los contenedores son ideales para aplicaciones sin estado y están pensados para ser efímeros. Esto significa que no se deben almacenar datos o registros en el contenedor, ya que de lo contrario se perderán cuando el contenedor termine. En su lugar, utilice mapeo de volumen para que persistan fuera de los contenedores. Pila ELK podrían utilizarse para almacenar y procesar registros. Si se utilizan volúmenes gestionados durante el proceso de pruebas iniciales, elimínelos utilizando
-v
con el interruptordocker rm
mando. - Direcciones IP del contenedor - A cada contenedor se le asigna una dirección IP. Varios contenedores se comunican entre sí para crear una aplicación; por ejemplo, una aplicación desplegada en un servidor de aplicaciones tendrá que comunicarse con una base de datos. Los contenedores existentes se cierran y los nuevos se inician constantemente. Depender de la dirección IP del contenedor requerirá actualizar constantemente la configuración de la aplicación. Esto hará que la aplicación sea frágil. En su lugar, cree servicios. Esto proporcionará un nombre lógico que puede ser referido independientemente del número creciente y decreciente de contenedores. Y también proporciona un equilibrio de carga básico.
- Ejecutar un único proceso en un contenedor - A
Dockerfile
tiene uso unoCMD
yPUNTO DE ENTRADA
. A menudo, CMD utilizará un script que realizará alguna configuración de la imagen y luego iniciará el contenedor. No intentes iniciar múltiples procesos usando ese script. Es importante seguir separación de intereses al crear imágenes Docker. Esto hará que la gestión de sus contenedores, la recopilación de registros, la actualización de cada proceso individual mucho más difícil. Puedes considerar dividir la aplicación en varios contenedores y gestionarlos de forma independiente. - No utilice
docker exec
- Ladocker exec
inicia un nuevo comando en un contenedor en ejecución. Esto es útil para adjuntar un shell usando el comando docker exec -it {cid} bash. Pero aparte de eso, el contenedor ya está ejecutando el proceso que se supone que debe ejecutar. - Mantén una imagen esbelta - Crea un nuevo directorio e incluye Dockerfile y otros archivos relevantes en ese directorio. Considere también el uso de .dockerignore para eliminar cualquier registro, código fuente, logs, etc. antes de crear la imagen. Asegúrese de eliminar cualquier artefacto descargado después de descomprimirlo.
- Crear imagen a partir de un contenedor en ejecución - Se puede crear una nueva imagen utilizando la función
docker commit
comando. Esto es útil cuando se han realizado cambios en el contenedor. Pero las imágenes creadas usando esto no son reproducibles. En su lugar, realice cambios en el Dockerfile, finalice los contenedores existentes e inicie un nuevo contenedor con la imagen actualizada. - Credenciales de seguridad en la imagen Docker - No almacene las credenciales de seguridad en el Dockerfile. Están en texto claro y registradas en un repositorio. Esto las hace completamente vulnerables. Utilice
-e
para especificar contraseñas como variable de entorno en tiempo de ejecución. Alternativamente--env-file
puede utilizarse para leer variables de entorno de un archivo. Otro método consiste en utilizarCMD
oPUNTO DE ENTRADA
para especificar un script. Este script extraerá las credenciales de un tercero y luego configurará tu aplicación. última
etiqueta: A partir de una imagen comocouchbase
es tentador. Si no se especifican etiquetas, se inicia un contenedor utilizando la imagencouchbase:último
. Esta imagen puede no ser realmente la última y en su lugar referirse a una versión anterior. Llevar una aplicación a producción requiere un entorno totalmente controlador con la versión exacta de la imagen. Lea esto Docker: la última confusión post del compañero Docker Captain @adrianmouat. Asegúrese de utilizar siempre la etiqueta cuando ejecute un contenedor. Por ejemplo, utilicecouchbase:enterprise-4.5.1
en lugar decouchbase
.- Desajuste de impedancia - No utilice diferentes imágenes, o incluso diferentes etiquetas en dev, prueba, puesta en escena y entorno de producción. La imagen que es la "fuente de la verdad" debe ser creada una vez y enviada a un repositorio. Esa imagen debe ser utilizada para diferentes entornos en el futuro. En algunos casos, usted puede considerar la ejecución de sus pruebas unitarias en el archivo WAR como parte de maven construir y luego crear la imagen. Pero cualquier prueba de integración del sistema se debe hacer en la imagen que será empujado en la producción.
- Publicación de puertos - No utilice
-P
para publicar todos los puertos expuestos. Esto le permitirá ejecutar múltiples contenedores y publicar sus puertos expuestos. Pero esto también significa que todos los puertos serán publicados. En su lugar utilice-p
para publicar puertos específicos.
Añadir más basado en la discusión en twitter ...
- Usuario raíz - No ejecutes contenedores como usuario root. El host y el contenedor comparten el mismo kernel. Si el contenedor está comprometido, un usuario root puede hacer más daño a los hosts subyacentes. Utiliza
EJECUTAR groupadd -r couchbase && useradd -r -g couchbase couchbase
para crear un grupo y un usuario en él. Utilice la funciónUSUARIO
para cambiar a ese usuario. CadaUSUARIO
crea una nueva capa en la imagen. Evita que el usuario tenga que cambiar de una a otra para reducir el número de capas. Gracias a @Aleksandar_78 ¡por este consejo! - Dependencia entre contenedores - A menudo, las aplicaciones dependen de que los contenedores se inicien en un orden determinado. Por ejemplo, un contenedor de base de datos debe arrancar antes de que una aplicación pueda conectarse a él. La aplicación debe ser resistente a estos cambios, ya que los contenedores pueden terminar o iniciarse en cualquier momento. En este caso, haga que el contenedor de la aplicación espere a que la conexión a la base de datos tenga éxito antes de continuar. No utilice scripts wait-for en Dockerfile para que los contenedores se inicien en un orden específico. Particularmente esperar un cierto número de segundos para que un contenedor en particular se inicie es muy frágil. Gracias a @ratnopam ¡por este consejo!
¿Qué otros antipatrones sigue? Docker para desarrolladores Java es un taller práctico a su propio ritmo que explica cómo empezar con Docker para desarrolladores Java. ¿Le interesa un tutorial más detallado? Vea este tutorial de 2 horas de JavaOne. couchbase.com/contenedores muestra cómo ejecutar Couchbase en una variedad de frameworks.