Подробное объяснение Dockerfile серии Docker FROM|RUN|BUILD (3)

задняя часть Docker
Подробное объяснение Dockerfile серии Docker FROM|RUN|BUILD (3)

Эта статья участвовала в третьем этапе курса «Высокоэффективное обновление» тренировочного лагеря для создателей наггетсов. Подробнее см.:Dig Li Project | Идет третий этап тренировочного лагеря создателя, «написание» личного влияния.

1 FROM

1.1 FROM указывает базовый образ

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

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

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

В пустом каталоге создайте текстовый файл и назовите егоDockerfile:

$ mkdir mynginx
$ cd mynginx
$ touch Dockerfile

Его содержание:

FROM nginx
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html

Этот Dockerfile очень простой, всего две строки. Здесь задействованы две инструкции,FROMа такжеRUN.

1.2 FROM указывает базовый образ

Так называемый заказной образ должен быть основан на образе и настроен на нем. как мы побежалиnginxКонтейнер образа, а затем изменить его, необходимо указать базовый образ. а такжеFROMзаключается в том, чтобы указатьбазовое изображение, такDockerfileсерединаFROMявляется обязательной командой и должна быть первой командой.

существуетDocker HubНа сайте много качественных официальных изображений, а есть изображения служебного типа, которые можно использовать напрямую, напримерnginx,redis,mongo,mysql,httpd,php,tomcatи т. д., а также некоторые образы, удобные для разработки, сборки и запуска приложений на разных языках, напримерnode,openjdk,python,ruby,golangЖдать. Мы можем найти изображение, которое лучше всего соответствует нашей конечной цели, и настроить его как базовое изображение.

Если соответствующее служебное зеркало не найдено, официальное зеркало также предоставляет несколько основных зеркал операционной системы, таких какubuntu,debian,centos,fedora,alpineИ т. д., программные библиотеки этих операционных систем предоставляют нам более широкое пространство для расширения.

2 RUN

2.1 RUN выполнить команду

RUNДирективы используются для выполнения команд командной строки. Благодаря мощности командной строки,RUNДирективы — одна из наиболее часто используемых директив при настройке изображений. Есть два формата:

  • shellФормат:RUN <命令>, точно так же, как команда, введенная непосредственно в командной строке. В Dockerfile только что написаноRUNИнструкции в этом формате.
RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
  • execФормат:RUN ["可执行文件", "参数1", "参数2"], что больше похоже на формат вызова функции.

теперь, когдаRUNТочно так же, как сценарий оболочки, вы можете выполнять команды, поэтому можем ли мы сопоставить каждую команду с RUN, как сценарий оболочки? Например:

FROM debian:stretch
​
RUN apt-get update
RUN apt-get install -y gcc libc6-dev make wget
RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz"
RUN mkdir -p /usr/src/redis
RUN tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1
RUN make -C /usr/src/redis
RUN make -C /usr/src/redis install

Как упоминалось ранее, каждая инструкция в Dockerfile создает слой,RUNне исключено. КаждыйRUNПоведение такое же, как и процесс ручного создания зеркала только что: создайте новый слой, выполните на нем эти команды, и после завершения выполнения,commitМодификация этого слоя составляет новое изображение.

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

UnionFSСуществует максимальное количество слоев, напримерAUFS, раньше максимальное значение не превышало42слой, который теперь составляет не более127Этаж.\color{red}{Union FS имеет максимальное количество слоев. Например, в AUFS раньше было максимум 42 слоя, но теперь оно не может превышать 127 слоев. }

надDockerfileПравильное написание должно быть таким:

FROM debian:stretch
​
RUN buildDeps='gcc libc6-dev make wget' \
    && apt-get update \
    && apt-get install -y $buildDeps \
    && wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
    && mkdir -p /usr/src/redis \
    && tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1 \
    && make -C /usr/src/redis \
    && make -C /usr/src/redis install \
    && rm -rf /var/lib/apt/lists/* \
    && rm redis.tar.gz \
    && rm -r /usr/src/redis \
    && apt-get purge -y --auto-remove $buildDeps

Прежде всего, все предыдущие команды имеют только одну цель — скомпилировать и установить исполняемый файл redis. Так что нет необходимости создавать много слоев, это всего лишь один слой. Поэтому здесь используется не так многоRUNДля однозначного соответствия между разными командами используйте только одинRUNинструкция и использование&&Объедините отдельные желаемые команды. Упростите предыдущие 7 слоев до 1 слоя. При написании Dockerfile всегда напоминайте себе, что вы не пишете сценарии оболочки, а определяете, как должен быть построен каждый слой.

Кроме того, здесь также выполняются разрывы строк для форматирования. Dockerfile поддерживает метод переноса команд, добавляя `` в конец класса Shell, а также в начало строки#Формат комментариев. Хорошее форматирование, такое как разрывы строк, отступы, комментарии и т. д., облегчит обслуживание и устранение неполадок, что является хорошей привычкой.

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

3 BUILD

3.1 Создайте образ

существуетDockerfileВыполните каталог, в котором находится файл:

$ docker build -t nginx:v3 .
Sending build context to Docker daemon 2.048 kB
Step 1 : FROM nginx
 ---> e43d811ce2f4
Step 2 : RUN echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html
 ---> Running in 9cdc27646c7b
 ---> 44aa4490ce2c
Removing intermediate container 9cdc27646c7b
Successfully built 44aa4490ce2c

Из вывода команды вы можете ясно увидеть процесс сборки образа. существуетStep 2, как упоминалось ранее,RUNКоманда запускает контейнер9cdc27646c7b, выполняет запрошенную команду и, наконец, фиксирует слой44aa4490ce2c, затем удалите используемый контейнер9cdc27646c7b.

Здесь мы используемdocker buildкоманда для создания образа. Его формат:

docker build [选项] <上下文路径/URL/->

Здесь мы указываем имя конечного изображения-t nginx:v3, после успешной сборки можем запускать как раньшеnginx:v2Запустив изображение таким образом, результат будет таким же, какnginx:v2Такой же.