run - docker tag example
Cómo actualizar el contenedor de la ventana acoplable después de cambiar su imagen (13)
Digamos que he sacado la imagen oficial de mysql: 5.6.21 .
He desplegado esta imagen creando varios contenedores docker.
Estos contenedores se han estado ejecutando durante algún tiempo hasta que se lance MySQL 5.6.22. La imagen oficial de mysql: 5.6 se actualiza con la nueva versión, pero mis contenedores siguen ejecutándose 5.6.21.
¿Cómo propagar los cambios en la imagen (es decir, actualizar la distribución MySQL) a todos mis contenedores existentes? ¿Cuál es la forma correcta de Docker de hacer esto?
Asegúrese de estar utilizando volúmenes para todos los datos persistentes (configuración, registros o datos de aplicación) que almacena en los contenedores relacionados con el estado de los procesos dentro de ese contenedor. Actualice su Dockerfile y reconstruya la imagen con los cambios que desea, y reinicie los contenedores con sus volúmenes montados en su lugar apropiado.
Considera para estas respuestas:
- El nombre de la base de datos es
app_schema
- El nombre del contenedor es
app_db
- La contraseña de root es
root123
Cómo actualizar MySQL al almacenar datos de la aplicación dentro del contenedor
Esto se considera una mala práctica , ya que si pierde el contenedor, perderá los datos. Aunque es una mala práctica, aquí hay una forma posible de hacerlo:
1) Hacer un volcado de base de datos como SQL:
docker exec app_db sh -c ''exec mysqldump app_schema -uroot -proot123'' > database_dump.sql
2) Actualizar la imagen:
docker pull mysql:5.6
3) Actualizar el contenedor:
docker rm -f app_db
docker run --name app_db --restart unless-stopped /
-e MYSQL_ROOT_PASSWORD=root123 /
-d mysql:5.6
4) Restaurar el volcado de base de datos:
docker exec app_db sh -c ''exec mysql -uroot -proot123'' < database_dump.sql
Cómo actualizar el contenedor MySQL usando un volumen externo
El uso de un volumen externo es una mejor manera de administrar los datos y facilita la actualización de MySQL. Perder el contenedor no perderá ningún dato. Puede utilizar la función de docker-compose para facilitar la administración de aplicaciones Docker de varios contenedores en un único host:
1) Cree el archivo docker-compose.yml
para administrar sus aplicaciones:
version: ''2''
services:
app_db:
image: mysql:5.6
restart: unless-stopped
volumes_from: app_db_data
app_db_data:
volumes: /my/data/dir:/var/lib/mysql
2) Actualice MySQL (desde la misma carpeta que el archivo docker-compose.yml
):
docker-compose pull
docker-compose up -d
Nota: el último comando anterior actualizará la imagen de MySQL, recreará e iniciará el contenedor con la nueva imagen.
Después de evaluar las respuestas y estudiar el tema, me gustaría resumirlo.
La forma Docker de actualizar contenedores parece ser la siguiente:
Los contenedores de aplicaciones no deben almacenar datos de aplicaciones . De esta manera, puede reemplazar el contenedor de aplicaciones con su versión más nueva en cualquier momento ejecutando algo como esto:
docker pull mysql
docker stop my-mysql-container
docker rm my-mysql-container
docker run --name=my-mysql-container --restart=always /
-e MYSQL_ROOT_PASSWORD=mypwd -v /my/data/dir:/var/lib/mysql -d mysql
Puede almacenar datos en el host (en el directorio montado como volumen) o en contenedores especiales de solo datos . Lea más sobre esto here , here y here .
Actualizar aplicaciones (por ejemplo, con yum / apt-get upgrade) dentro de contenedores se considera un antipatrón . Se supone que los contenedores de aplicación son inmutables , lo que garantizará un comportamiento reproducible. Algunas imágenes de aplicaciones oficiales (mysql: 5.6 en particular) ni siquiera están diseñadas para auto-actualizarse (apt-get upgrade no funcionará).
Me gustaría dar las gracias a todos los que dieron sus respuestas, para que podamos ver todos los enfoques diferentes.
Esto es algo con lo que también he estado luchando por mis propias imágenes. Tengo un entorno de servidor desde el que creo una imagen de Docker. Cuando actualice el servidor, me gustaría que todos los usuarios que ejecutan contenedores basados en mi imagen de Docker puedan actualizarse al último servidor.
Idealmente, preferiría generar una nueva versión de la imagen de Docker y tener todos los contenedores basados en una versión anterior de esa imagen que se actualice automáticamente a la nueva imagen "en su lugar". Pero este mecanismo no parece existir.
Por lo tanto, el siguiente mejor diseño que he podido encontrar hasta ahora es proporcionar una manera de actualizar el contenedor, de manera similar a como una aplicación de escritorio comprueba las actualizaciones y luego las actualiza. En mi caso, esto probablemente signifique crear un script que implique que Git extraiga de una etiqueta conocida.
La imagen / contenedor no cambia realmente, pero los "elementos internos" de ese contenedor cambian. Podría imaginar hacer lo mismo con apt-get, yum, o lo que sea apropiado para su entorno. Junto con esto, actualizaría myserver: la última imagen en el registro para que cualquier nuevo contenedor se base en la última imagen.
Me interesaría saber si existe alguna técnica anterior que aborde este escenario.
Esto es lo que parece usar la función docker-compose
cuando se construye un Dockerfile
personalizado.
- Primero construya su Dockerfile personalizado, agregando un número de versión siguiente para diferenciarlo. Ej:
docker build -t imagename:version .
Esto almacenará su nueva versión localmente. - Ejecutar
docker-compose down
- Edite su archivo
docker-compose.yml
para reflejar el nuevo nombre de imagen que estableció en el paso 1. - Ejecutar
docker-compose up -d
Buscará localmente la imagen y usará su imagen actualizada.
-EDITAR-
Mis pasos anteriores son más detallados de lo que deben ser. He optimizado mi flujo de trabajo incluyendo la build: .
parámetro a mi docker-componer archivo. Los pasos se ve esto ahora:
- Verifique que mi Dockerfile sea como quiero que se vea.
- Establezca el número de versión de mi nombre de imagen en mi archivo de composición acoplable.
- Si mi imagen no está construida todavía: ejecute
docker-compose build
- Ejecutar
docker-compose up -d
No me di cuenta en ese momento, pero la función docker-compose es lo suficientemente inteligente como para simplemente actualizar mi contenedor a la nueva imagen con el único comando, en lugar de tener que bajarlo primero.
Me gustaría agregar que si desea hacer este proceso automáticamente (descargue, detenga y reinicie un nuevo contenedor con la misma configuración que describe @Yaroslav), puede usar WatchTower. Un programa que actualiza automáticamente sus contenedores cuando se modifican https://github.com/v2tec/watchtower
Necesita reconstruir todas las imágenes y reiniciar todos los contenedores, o de alguna manera yum actualizar el software y reiniciar la base de datos. No hay una ruta de actualización sino que tú mismo te diseñas.
No me gusta montar volúmenes como un enlace a un directorio de host, por lo que se me ocurrió un patrón para actualizar los contenedores de la ventana acoplable con contenedores totalmente administrados por la ventana acoplable. La creación de un nuevo contenedor de --volumes-from <container>
acoplable con --volumes-from <container>
dará al nuevo contenedor con las imágenes actualizadas compartidas de los volúmenes administrados por la ventana acoplable.
docker pull mysql
docker create --volumes-from my_mysql_container [...] --name my_mysql_container_tmp mysql
Al no eliminar de inmediato el my_mysql_container
original, tiene la capacidad de volver al contenedor de trabajo conocido si el contenedor actualizado no tiene los datos correctos o falla una prueba de validez.
En este punto, normalmente ejecuto los scripts de copia de seguridad que tengo para que el contenedor me proporcione una red de seguridad en caso de que algo salga mal
docker stop my_mysql_container
docker start my_mysql_container_tmp
Ahora tiene la oportunidad de asegurarse de que los datos que espera que se encuentren en el nuevo contenedor estén allí y realizar una comprobación de validez.
docker rm my_mysql_container
docker rename my_mysql_container_tmp my_mysql_container
Los volúmenes de la ventana acoplable se mantendrán siempre que los contenga un contenedor, por lo que puede eliminar el contenedor original de forma segura. Una vez que se retira el contenedor original, el nuevo contenedor puede asumir el mismo nombre del original para hacer que todo sea tan bonito como era para comenzar.
Hay dos ventajas principales al usar este patrón para actualizar contenedores de ventana acoplable. En primer lugar, elimina la necesidad de montar volúmenes en directorios de host al permitir que los volúmenes se transfieran directamente a contenedores actualizados. En segundo lugar, nunca se encuentra en una posición en la que no haya un contenedor acoplable que funcione; por lo tanto, si la actualización falla, puede volver fácilmente a cómo estaba funcionando antes girando nuevamente el contenedor de la ventana acoplable original.
Respuesta similar a la anterior
docker images | awk ''{print $1}'' | grep -v ''none'' | grep -iv ''repo'' | xargs -n1 docker pull
Si no desea utilizar Docker Compose, le puedo recomendar un portainer . Tiene una función de recreación que le permite recrear una imagen mientras tira de la última imagen.
Solo por proporcionar una respuesta más general (no específica a mysql) ...
- En breve
Sincronice con el registro de imágenes de servicio ( https://docs.docker.com/compose/compose-file/#image ):
docker-compose pull
Vuelva a crear el contenedor si el archivo o la imagen de la ventana acoplable han cambiado:
docker-compose up -d
- Fondo
La administración de imágenes de contenedor es una de las razones para usar docker-compose (consulte https://docs.docker.com/compose/reference/up/ )
Si existen contenedores para un servicio y la configuración o la imagen del servicio se modificaron después de la creación del contenedor, la función docker-compose recoge los cambios deteniendo y volviendo a crear los contenedores (conservando los volúmenes montados). Para evitar que Compose capte cambios, use la marca --no-recreate.
El aspecto de gestión de datos también está cubierto por la ventana acoplable compuesta a través de "volúmenes" externos montados (consulte https://docs.docker.com/compose/compose-file/#volumes ) o el contenedor de datos.
Esto deja intactos los problemas potenciales de compatibilidad con versiones anteriores y de migración de datos, pero estos son problemas "aplicativos", no específicos de Docker, que se deben verificar en comparación con las notas de la versión y las pruebas ...
Tomando de http://blog.stefanxo.com/2014/08/update-all-docker-images-at-once/
Puedes actualizar todas tus imágenes existentes usando el siguiente canal de comando:
docker images | awk ''/^REPOSITORY|/<none/>/ {next} {print $1}'' | xargs -n 1 docker pull
Tuve el mismo problema, por lo que creé docker-run , una herramienta de línea de comandos muy simple que se ejecuta dentro de un contenedor docker para actualizar paquetes en otros contenedores en ejecución.
Utiliza docker-py para comunicarse con la ejecución de los contenedores de la ventana acoplable y los paquetes de actualización o ejecutar cualquier comando único arbitrario
Ejemplos:
docker run --rm -v /var/run/docker.sock:/tmp/docker.sock itech/docker-run exec
de forma predeterminada, ejecutará el comando de date
en todos los contenedores en ejecución y devolverá los resultados, pero puede emitir cualquier comando, por ejemplo docker-run exec "uname -a"
por docker-run exec "uname -a"
Para actualizar paquetes (actualmente solo usa apt-get):
docker run --rm -v /var/run/docker.sock:/tmp/docker.sock itech/docker-run update
Puede crear un alias y usarlo como una línea de comando regular, por ejemplo,
alias docker-run=''docker run --rm -v /var/run/docker.sock:/tmp/docker.sock itech/docker-run''