Поиск по сайту:
Бог — это газообразное позвоночное (А. Эйнштейн).

Как изменить образы Docker

09.03.2021
Установить Docker 1.11 на Ubuntu 16.04 LTS x64

Мы предполагаем, что вы немного знакомы с Docker и знаете основы, такие как запуск контейнеров докеров и т. д.

 

Что именно изменяет образ докера?

Образ контейнера строится по слоям (или это набор слоев), каждая инструкция Dockerfile создает слой изображения. Например, рассмотрим следующий файл Dockerfile:

FROM alpine:latest

RUN apk add --no-cache python3

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

 

Поскольку существует всего три команды Dockerfile, образ, созданный из этого Dockerfile, будет содержать в общей сложности три слоя.

Вы можете убедиться в этом, построив образ:

docker image built -t dummy:0.1 .

 

А затем с помощью команды docker image history на построенном образе.

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

 

Игнорируйте последний слой <missing>.

Каждый из этих слоев доступен только для чтения. Это полезно, потому что, поскольку эти слои доступны только для чтения, ни один процесс, связанный с запущенным экземпляром этого изображения, не сможет изменять содержимое этого изображения, поэтому эти слои могут использоваться многими контейнерами без необходимости сохранения копия для каждого экземпляра. Но для того, чтобы процессы контейнеров могли выполнять чтение/запись, при создании контейнеров поверх существующих слоев RO добавляется еще один слой, который доступен для записи и не используется другими контейнерами.

Обратной стороной этого слоя r/w является то, что изменения, сделанные в этом слое, не являются постоянными, хотя вы можете использовать тома для сохранения некоторых данных, иногда вам может потребоваться/вы захотите добавить слой перед каким-либо существующим слоем или удалить слой из изображение или просто замените слой. Это причины, по которым можно изменить существующее изображение docker.

В этой статье я собираюсь рассмотреть все упомянутые выше случаи, используя разные методы.

 

Способы изменения образа докера

Есть два способа изменить образ докера.

  1. Через Dockerfiles.
  2. Используя команду docker container commit.
Читать  Bash. Сон в 1 секунду

 

Мы объясним оба метода, а в конце добавим, какой вариант использования лучше подходит для этого метода в контексте.

 

Изменение образа докера через Dockerfile

Изменение образа докера по сути означает изменение слоев изображения. Теперь, поскольку каждая команда Dockerfile представляет один слой изображения, изменение каждой строки файла Dockerfile также изменит соответствующий образ.

Поэтому, если вы добавляете слой к изображению, вы можете просто добавить к нему еще одну инструкцию Dockerfile, чтобы удалить одну, вы удалили бы строку, а для изменения слоя вы бы изменили строку соответствующим образом.

Есть два способа использовать Dockerfile для изменения изображения.

  1. Используя образ, который вы хотите изменить, как базовый образ, и создайте дочерний образ.
  2. Изменение фактического файла Dockerfile образа, который вы хотите изменить.

Позвольте нам объяснить, какой метод следует использовать, когда и как.

 

1. Использование изображения в качестве базового.

Это когда вы берете изображение, которое хотите изменить, и добавляете к нему слои для создания нового дочернего изображения. Если образ не создается с нуля, каждое изображение является модификацией одного и того же родительского базового образа.

Рассмотрим предыдущий файл Dockerfile. Скажите, почему построение образа из этого образа названо dummy:0.1. А если мы захотели использовать Perl вместо Python3 для печати «Hello World», но мы не хотим удалять Python3, мы могли бы просто использовать изображение dummy:0.1 в качестве базового изображения (поскольку Python3 уже существует) и строить из этого, как показано ниже

FROM dummy:0.1

RUN apk add --no-cache perl

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

 

Здесь мы строим поверх dummy:0.1, добавляя к нему больше слоев, как считаем нужным.

Этот метод не будет очень полезным, если вы собираетесь изменить или удалить какой-либо существующий слой. Для этого вам нужно следовать следующему методу.

 

2. Изменение образа Dockerfile.

Поскольку существующие слои изображения доступны только для чтения, вы не можете напрямую изменять их с помощью нового файла Dockerfile. С помощью команды FROM в Dockerfile вы берете какое-то изображение в качестве основы и строите на нем или добавляете к нему слои.

Читать  Как взаимодействовать с Git из Ansible

Некоторые задачи могут потребовать от нас изменения существующего уровня, хотя вы можете сделать это, используя предыдущий метод с кучей противоречивых RUNинструкций (например, удаление файлов, удаление/замена пакетов, добавленных на каком-то предыдущем уровне), это не идеальное решение или что мы бы порекомендовали. Потому что он добавляет дополнительные слои и значительно увеличивает размер изображения.

Лучшим способом было бы не использовать образ в качестве базового, а изменить фактический файл Dockerfile этого образа. Вернемся к предыдущему Dockerfile, что, если бы мне не пришлось хранить Python3 в этом образе и заменить пакет Python3 и команду на Perl?

Следуя предыдущему методу, нам пришлось бы создать новый Dockerfile, например:

FROM dummy:0.1

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

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

 

При построении, в этом изображении будет всего пять слоев.

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

 

Также размер изображения составляет 83,8 МБ.

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

 

Теперь вместо этого возьмите исходный файл Dockerfile и измените файлы Python3 на Perl следующим образом

FROM alpine:latest

RUN apk add --no-cache perl

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

 

Количество слоев уменьшилось до 3, а размер теперь составляет 40,2 МБ.

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

 

Читать  Как перенести CentOS 8 на CentOS Stream

Изображение успешно изменено.

Предыдущий метод более полезен, когда вы собираетесь просто добавить слои поверх существующих, но не очень полезен при попытке изменить существующие слои, например удалить один, заменить один, изменить порядок существующих и так далее. Вот где сияет этот метод.

Метод 2: изменение образа с помощью фиксации докера

Есть еще один метод, с помощью которого вы можете сделать снимок работающего контейнера и превратить его в собственный образ.

Давайте создадим идентичный образ dummy:0.1, но на этот раз без использования Dockerfile. Поскольку мы использовали базу alpine:latestкак dummy:0.1, разверните контейнер с этим изображением.

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

 

Теперь внутри контейнера, добавьте пакет Python3, apk add –no-cache python3. После этого откройте новое окно терминала и выполните следующую команду (или что-то подобное)

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

 

С помощью флага –change мы добавляю к новому образу dummy:04 инструкцию Dockerfile (в данном случае инструкцию ENTRYPOINT).

С помощью команды docker container commit вы в основном конвертируете внешний слой r/w в слой ar/o, добавляете его к существующим слоям изображения и создаете новое изображение. Этот метод более интуитивно понятен/интерактивен, поэтому вы можете использовать его вместо Dockerfiles, но понимаете, что это не очень воспроизводимо. Также те же правила применяются к удалению или изменению любых существующих слоев, добавление слоя только для того, чтобы что-то удалить или изменить что-то, сделанное на предыдущем слое, не лучшая идея, по крайней мере, в большинстве случаев.

На этом статья завершается. Мы надеемся, что это статья была полезна для вас, если у вас есть какие-либо вопросы, оставьте комментарий ниже.

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.

1 Звезда2 Звезды3 Звезды4 Звезды5 Звезд (2 оценок, среднее: 5,00 из 5)
Загрузка...
Поделиться в соц. сетях:


0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

**ссылки nofollow

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии

Это может быть вам интересно


Рекомендуемое
C - отличный процедурный язык программирования для начинающих, которые хотят…

Спасибо!

Теперь редакторы в курсе.