GNU/Linux >> Tutoriales Linux >  >> Panels >> Docker

Cómo modificar imágenes de Docker

Supongo que está un poco familiarizado con Docker y conoce conceptos básicos como ejecutar contenedores Docker, etc.

En artículos anteriores, hemos discutido la actualización del contenedor docker y la escritura de archivos docker.

¿Qué es exactamente modificar una imagen de docker?

Una imagen de contenedor se construye en capas (o es una colección de capas), cada instrucción de Dockerfile crea una capa de la imagen. Por ejemplo, considere el siguiente Dockerfile:

FROM alpine:latest

RUN apk add --no-cache python3

ENTRYPOINT ["python3", "-c", "print('Hello World')"]

Dado que hay un total de tres comandos de Dockerfile, la imagen creada a partir de este Dockerfile contendrá un total de tres capas.

Puede confirmarlo construyendo la imagen:

docker image built -t dummy:0.1 .

Y luego usando el comando docker image history en la imagen construida.

articles/Modify a Docker Image on  modify-docker-images [?] took 12s 
❯ docker image history dummy:0.1 
IMAGE          CREATED          CREATED BY                                      SIZE      COMMENT
b997f897c2db   10 seconds ago   /bin/sh -c #(nop)  ENTRYPOINT ["python3" "-c…   0B        
ee217b9fe4f7   10 seconds ago   /bin/sh -c apk add --no-cache python3           43.6MB    
28f6e2705743   35 hours ago     /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B        
<missing>      35 hours ago     /bin/sh -c #(nop) ADD file:80bf8bd014071345b…   5.61MB

Ignora la última capa ''.

Cada una de estas capas es de solo lectura. Esto es beneficioso porque dado que estas capas son de solo lectura, ningún proceso asociado con una instancia en ejecución de esta imagen podrá modificar el contenido de esta imagen, por lo tanto, estas capas pueden ser compartidas por muchos contenedores sin tener que mantener un copia para cada instancia. Pero para que los procesos de los contenedores puedan realizar r/w, se agrega otra capa encima de las capas de RO existentes cuando se crean los contenedores, esto se puede escribir y no se comparte con otros contenedores.

La desventaja de esta capa r/w es que los cambios realizados en esta capa no son persistentes, aunque puede usar volúmenes para conservar algunos datos, a veces puede necesitar/querer agregar una capa antes de alguna capa existente, o eliminar una capa de un imagen o simplemente reemplazar una capa. Estas son las razones por las que uno podría querer modificar un docker existente imagen.

En este artículo, cubriré todos los casos que mencioné anteriormente, usando diferentes métodos.

Métodos para modificar una imagen de docker

Hay dos formas de modificar una imagen acoplable.

  1. A través de Dockerfiles.
  2. Usando el comando docker container commit .

Explicaré ambos métodos y, al final, también agregaré qué caso de uso sería mejor para el método en contexto.

Método 1:modificar la imagen de la ventana acoplable a través de Dockerfile

Modificar una imagen acoplable esencialmente significa modificar las capas de una imagen. Ahora, dado que cada comando de Dockerfile representa una capa de la imagen, la modificación de cada línea de un Dockerfile también cambiará la imagen respectiva.

Entonces, si tuviera que agregar una capa a la imagen, simplemente puede agregarle otra instrucción Dockerfile, para eliminar una, eliminaría una línea y para cambiar una capa, cambiaría la línea en consecuencia.

Hay dos formas de usar un Dockerfile para modificar una imagen.

  1. Utilizar la imagen que desea modificar como imagen base y crear una imagen secundaria.
  2. Modificar el Dockerfile real de la imagen que desea cambiar.

Déjame explicarte qué método se debe usar, cuándo y cómo.

1. Usar una imagen como imagen base

Aquí es cuando toma la imagen que desea modificar y le agrega capas para crear una nueva imagen secundaria. A menos que una imagen se construya desde cero, cada imagen es una modificación de la misma imagen base principal.

Considere el Dockerfile anterior. Digamos que la creación de la imagen a partir de esa imagen se llama dummy:0.1 . Ahora, si tuviera que pensar que ahora necesito usar Perl en lugar de Python3 para imprimir "Hello World", pero tampoco quiero eliminar Python3, podría usar el dummy:0.1 image como la imagen base (dado que Python3 ya está allí) y construya a partir de eso como se muestra a continuación

FROM dummy:0.1

RUN apk add --no-cache perl

ENTRYPOINT ["perl", "-e", "print \"Hello World\n\""]

Aquí estoy construyendo sobre dummy:0.1 , añadiéndole más capas como mejor me parezca.

Este método no será de mucha ayuda si su intención es cambiar o eliminar alguna capa existente. Para eso, debes seguir el siguiente método.

2. Modificando el Dockerfile de la imagen

Dado que las capas existentes de una imagen son de solo lectura, no puede modificarlas directamente a través de un nuevo Dockerfile. Con el FROM comando en un Dockerfile, se toma una imagen como base y se construye sobre o agregarle capas.

Algunas tareas pueden requerir que alteremos una capa existente, aunque puede hacerlo usando el método anterior con un montón de RUN contradictorios instrucciones (como eliminar archivos, eliminar/reemplazar paquetes agregados en alguna capa anterior), no es una solución ideal o lo que recomendaría. Porque agrega capas adicionales y aumenta bastante el tamaño de la imagen.

Un mejor método sería no usar la imagen como imagen base, sino cambiar el Dockerfile real de esa imagen. Considere nuevamente el Dockerfile anterior, ¿y si no tuviera que mantener Python3 en esa imagen y reemplazar el paquete Python3 y el comando con los de Perl?

Si hubiera seguido el método anterior, habría tenido que crear un nuevo Dockerfile así -

FROM dummy:0.1

RUN apk del python3 && apk add --no-cache perl

ENTRYPOINT ["perl", "-e", "print \"Hello World\n\""]

Si se construye, habrá un total de cinco capas en esta imagen.

articles/Modify a Docker Image on  modify-docker-images [?] took 3s 
❯ docker image history dummy:0.2
IMAGE          CREATED          CREATED BY                                      SIZE      COMMENT
2792036ddc91   10 seconds ago   /bin/sh -c #(nop)  ENTRYPOINT ["perl" "-e" "…   0B        
b1b2ec1cf869   11 seconds ago   /bin/sh -c apk del python3 && apk add --no-c…   34.6MB    
ecb8694b5294   3 hours ago      /bin/sh -c #(nop)  ENTRYPOINT ["python3" "-c…   0B        
8017025d71f9   3 hours ago      /bin/sh -c apk add --no-cache python3 &&    …   43.6MB    
28f6e2705743   38 hours ago     /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B        
<missing>      38 hours ago     /bin/sh -c #(nop) ADD file:80bf8bd014071345b…   5.61MB

Además, el tamaño de la imagen es de 83,8 MB.

articles/Modify a Docker Image on  modify-docker-images [?] 
❯ docker images
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
dummy        0.2       2792036ddc91   19 seconds ago   83.8MB

Ahora, en lugar de hacer eso, tome el Dockerfile inicial y cambie los de Python3 a Perl así

FROM alpine:latest

RUN apk add --no-cache perl

ENTRYPOINT ["perl", "-e", "print \"Hello World\n\""]

El número de capas se ha reducido a 3 y el tamaño ahora es de 40,2 MB.

articles/Modify a Docker Image on  modify-docker-images [?] took 3s 
❯ docker image history dummy:0.3
IMAGE          CREATED         CREATED BY                                      SIZE      COMMENT
f35cd94c92bd   9 seconds ago   /bin/sh -c #(nop)  ENTRYPOINT ["perl" "-e" "…   0B        
053a6a6ba221   9 seconds ago   /bin/sh -c apk add --no-cache perl              34.6MB    
28f6e2705743   38 hours ago    /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B        
<missing>      38 hours ago    /bin/sh -c #(nop) ADD file:80bf8bd014071345b…   5.61MB    

articles/Modify a Docker Image on  modify-docker-images [?] 
❯ docker images
REPOSITORY   TAG       IMAGE ID       CREATED          SIZE
dummy        0.3       f35cd94c92bd   29 seconds ago   40.2MB

Imagen cambiada con éxito.

El método anterior es más útil cuando solo va a agregar capas encima de las existentes, pero no es muy útil cuando intenta modificar las capas existentes como eliminar una, reemplazar una, reordenar las existentes y pronto. Ahí es donde brilla este método.

Método 2:Modificar imagen usando docker commit

Existe otro método en el que puede tomar una instantánea de un contenedor en ejecución y convertirlo en una imagen propia.

Construyamos un dummy:0.1 imagen idéntica, pero esta vez sin usar un Dockerfile. Desde que usé alpine:latest como dummy:0.1 base de , haz girar un contenedor de esa imagen.

docker run --rm --name alpine -ti alpine ash

Ahora dentro del contenedor, agregue el paquete Python3, apk add --no-cache python3 . Una vez hecho esto, abra una nueva ventana de terminal y ejecute el siguiente comando (o algo similar)

docker container commit --change='ENTRYPOINT ["python3", "-c", "print(\"Hello World\")"]' alpine dummy:0.4

Con el --change flag Estoy agregando una instrucción Dockerfile al nuevo dummy:04 imagen (en este caso, el ENTRYPOINT instrucciones).

Con la docker container commit Básicamente, convierte la capa r/w más externa en una capa r/o, la agrega a las capas de la imagen existente y crea una nueva imagen. Este método es más intuitivo/interactivo, por lo que es posible que desee usarlo en lugar de Dockerfiles, pero comprenda que esto no es muy reproducible. También se aplican las mismas reglas para eliminar o alterar cualquier capa existente, agregar una capa solo para eliminar algo o modificar algo hecho en una capa anterior no es la mejor idea, al menos en la mayoría de los casos.

Eso concluye este artículo. Espero que esto te haya sido útil, si tienes alguna pregunta, haz un comentario a continuación.


Docker
  1. Cómo mover imágenes de Docker entre hosts

  2. Cómo reducir el tamaño de la imagen de Docker:6 métodos de optimización

  3. Cómo usar un Dockerfile para crear una imagen de Docker

  4. Cómo empaquetar y transferir imágenes de Docker de un servidor a otro

  5. Cómo compartir imágenes de Docker con otros

Cómo actualizar las imágenes de Docker a la última versión

Cómo usar Docker Commit para cambiar imágenes de contenedores

Guía completa para eliminar imágenes de Docker

Cómo crear una imagen Docker personalizada con Dockerfile

Compartir imágenes de Docker en Docker Hub

Cómo listar/buscar/extraer imágenes de la ventana acoplable en Linux