¿Cómo manejar las actualizaciones de seguridad dentro de los contenedores Docker?

Al implementar aplicaciones en servidores, normalmente hay una separación entre lo que la aplicación empaqueta consigo misma y lo que espera de la plataforma (sistema operativo y paquetes instalados) para proporcionar. Un punto de esto es que la plataforma se puede actualizar independientemente de la aplicación. Esto es útil, por ejemplo, cuando las actualizaciones de seguridad deben aplicarse con urgencia a los paquetes proporcionados por la plataforma sin reconstruir toda la aplicación.

Tradicionalmente, las actualizaciones de seguridad se han aplicado simplemente ejecutando un comando de administrador de paquetes para instalar versiones actualizadas de paquetes en el sistema operativo (por ejemplo, "yum update" en RHEL). Pero con el advenimiento de la tecnología de contenedores, como Docker, donde las imágenes de contenedores esencialmente agrupan la aplicación y la plataforma, ¿cuál es la forma canónica de mantener actualizado un sistema con contenedores? Tanto el host como los contenedores tienen sus propios conjuntos de paquetes independientes que necesitan actualizarse y la actualización en el host no actualizará ningún paquete dentro de los contenedores. Con el lanzamiento de RHEL 7, donde los contenedores Docker se presentan especialmente, sería interesante escuchar cuál es la forma recomendada por Redhat de manejar las actualizaciones de seguridad de los contenedores.

Reflexiones sobre algunas de las opciones:

  • Dejar que el administrador de paquetes actualice los paquetes en el host no actualizará los paquetes dentro de los contenedores.
  • Tener que regenerar todas las imágenes de contenedor para aplicar actualizaciones parece romper la separación entre la aplicación y la plataforma (la actualización de la plataforma requiere acceso al proceso de compilación de la aplicación que genera las imágenes de Docker).
  • La ejecución de comandos manuales dentro de cada uno de los contenedores en ejecución parece engorrosa y los cambios corren el riesgo de sobrescribirse la próxima vez que se actualicen los contenedores desde los artefactos de versión de la aplicación.

Por lo tanto, ninguno de estos enfoques parece satisfactorio.

Una imagen de Docker agrupa la aplicación y la "plataforma", eso es correcto. Pero, por lo general, la imagen se compone de una imagen base y la aplicación real.

Por lo tanto, la forma canónica de manejar las actualizaciones de seguridad es actualizar la imagen base y luego reconstruir la imagen de la aplicación.

Se supone que los recipientes son ligeros e intercambiables. Si el contenedor tiene un problema de seguridad, debe reconstruir una versión del contenedor parcheada e implementar el nuevo contenedor. (muchos contenedores usan una imagen base estándar que usa herramientas de administración de paquetes estándar como apt-get para instalar sus dependencias, la reconstrucción extraerá las actualizaciones de los repositorios)

Si bien puede parchear dentro de los contenedores, eso no se escalará bien.

Esto se gestiona automáticamente en SUSE Enterprise Linux mediante zypper-docker(1)

SUSE / zypper-docker

Inicio Rápido de Docker

En primer lugar, muchas de las actualizaciones que ejecutó tradicionalmente en el pasado simplemente no estarán dentro del contenedor en sí. El contenedor debe ser un subconjunto bastante ligero y pequeño del sistema de archivos completo que estaba acostumbrado a ver en el pasado. Los paquetes que debería tener que actualizar serían aquellos que forman parte de su DockerFile, y dado que tiene el DockerFile, debería poder realizar un seguimiento de los paquetes y los ID de contenedor que necesitan actualizaciones. La interfaz de usuario de Cloudstein que se lanzará pronto realiza un seguimiento de estos ingredientes de DockerFile para que pueda crear el esquema de actualización que mejor se adapte a sus contenedores. Espero que esto ayude

La mejor respuesta here ayuda mucho porque hay un script que contiene líneas de comandos principales para hacer exactamente lo que dijo Johannes Ziemke:

La mejor idea para esto que he visto hasta ahora es Project Atomic. Sin embargo, no creo que esté bastante listo para el horario estelar.

Valko, ¿con qué flujo de trabajo terminaste? Estoy ejecutando contenedores a largo plazo(alojando php-cgi, por ejemplo) y lo que he encontrado hasta ahora es: docker pull debian/jessie para actualizar la imagen, luego reconstruir mis imágenes existentes, luego detener los contenedores y ejecutarlos de nuevo (con la nueva imagen). Las imágenes que construyo tienen el mismo nombre que las anteriores, por lo que el inicio se realiza a través del script. Luego elimino las imágenes “sin nombre”. Seguramente agradecería un mejor flujo de trabajo.

Interesante pregunta. Me lo pregunto yo mismo. Si tiene 20 aplicaciones ejecutándose en un host docker, debe actualizar las imágenes base, reconstruir y reiniciar. 20 aplicaciones y ni siquiera sabes si la actualización de seguridad las afectó a todas o solo a una de ellas. Debe reconstruir la imagen para, por ejemplo, Apache cuando la actualización de seguridad solo afectó a libpng, por ejemplo. Así que terminas con reconstrucciones y reinicios innecesarios…

miha: Eso suena similar a lo que he terminado haciendo. Básicamente, actualizar y reconstruir continuamente todas las imágenes como parte de la realización de nuevas versiones. Y reiniciar los contenedores con las nuevas imágenes.

No tengo la respuesta, pero en caso de que alguien quiera un script simple que pueda ayudar a automatizar la verificación de actualizaciones de imágenes base: dockcheck