Docker

Содержание

Терминология

Перечень пакетов

Перечень файлов

Перечень команд

Перечень иструкций Dockerfile

Контейнеры

Образы

Dockerfile

Примеры

Ссылки

Терминология

Docker

Система управления контейнерами

Программная платформа для запуска приложений в контейнерах

контейнер (container)

Изолированное окружение для запуска приложений из образов

образ (image)

Пакет с программой и всеми необходимыми зависимостями

Операционное окружение плюс программное приложение

реестр (registry)

Хранилище репозиториев образов

репозиторий (repository)

Хранилище образов приложения в реестре

ссылка (image reference)

Уникальный идентификатор образа

Перечень пакетов

docker

Pack, ship and run any application as a lightweight container

https://www.docker.com

docker-compose

Fast, isolated development environments using Docker

https://www.docker.com

Перечень файлов

~/.docker/config.json

Файл с настройками Docker’а

/usr/lib/systemd/system/docker.service

Юнит-файл SystemD

Перечень команд

docker version

Вывести сводку по Docker’у

docker-compose version

Вывести сводку по Docker Compose

Образы

docker image ls
docker images

Вывести список всех локальных образов

docker image ls -a|--all

Вывести список всех локальных образов, включая промежуточные (intermediate)

docker image ls -q|--quiet

Вывести список идентификаторов локальных образов

docker image ls --filter repository='rabbit' --filter repository='*/rabbit'

Вывести список локальных образов, отфильтровав его по указанным критериям

docker image rm IMAGE_ID...

Удалить один или несколько локальных образов

docker image rm $(docker image ls -aq)

Удалить все локальные образы

docker image save -o|--output image.tar.gz IMAGE

Сохранить образ в архив

docker image load -i|--input image.tar.gz

Внести образ из архива в локальный реестр

docker image build -t|--tag IMAGE_NAME:TAG DOCKERFILE_LOCATION

docker image build \
  --progress {auto|plain|tty} \
  {-t|--tag} IMAGE_NAME[:TAG] \
    DOCKERFILE_LOCATION

docker image history --no-trunc IMAGE

docker image tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]

Создать ссылку на образ

Контейнеры

docker container run IMAGE COMMAND

docker container run -i|--interactive -t|--tty 387f84126dbc 'sh'

docker container run --rm IMAGE

Удалить контейнер по завершению его работы

docker container run -i|--interactive -t|--tty --entrypoint sh 387f84126dbc

docker container run --rm alpine watch -tn 1 'ping google.com'

Цикличиски выполнять команду ping в созданном контейнере

docker container run -d|--detach -p|--publish 8088:80 3a29d4fe4767

docker container create IMAGE_ID

Создать контейнер

docker container create -p|--publish 8088:80 3a29d4fe4767

docker container create -e|--env 'METHOD=HEAD' -e|--env 'HOST=linux.org.ru' 7a6ec9807bdd

docker container create --network rabbit 7a6ec9807bdd

docker container ls

Вывести список запущенных контейнеров

docker container ls -a|--all

Вывести список всех локальных контейнеров как запущенных, так и незапущенных

docker container ls -q|--quiet

Вывести список идентификаторов запущенных контейнеров

docker container rm CONTAINER_ID...

Удалить один или несколько локальных контейнеров

docker container rm $(docker container ls -aq)

Удалить все локальные контейнеры

docker container rm -f|--force $(docker container ls -aq)

Удалить все локальные контейнеры, включая запущенные

docker container start CONTAINER_ID...

Запустить один или несколько контейнеров

docker container stop CONTAINER_ID...

Остановить один или несколько контейнеров

Сети

docker network ls

Вывести перечень сетей

docker network create NETWORK

Создать сеть

docker network rm NETWORK...

Удалить одну или несколько сетей

docker network inspect NETWORK...

Отобразить детализированную информацию (в формате JSON) по одной или нескольким сетям

Журналирование

docker container logs CONTAINER_ID

Вывести журнал контейнера

docker container logs -f|--follow CONTAINER_ID

Вывести журнал контейнера и остаться в режиме отслеживания

Нажать <Ctrl>+C для выхода из режима отслеживания.

docker container stats CONTAINER_ID

Вывести живую информацию о ресурсах, потребляемых контейнером

docker container inspect CONTAINER_ID...

Отобразить детализированную информацию (в формате JSON) по одному или нескольким контейнерам

Взаимодействие с контейнером

docker container exec CONTAINER_ID COMMAND

Выполнить команду в запущенном контейнере

docker exec | Docker Documentation

docker container exec -i|--interactive -t|--tty 2d83314c9a66 sh

Создать интерактивную (-i) сессию командной оболочки (sh) в выделенном терминале (-t) в заданном контейнере (2d83314c9a66)

docker container cp SOURCE DESTINATION

Скопировать файл из SOURCE в DESTINATION

docker container cp src/index.html 2d83314c9a66:/usr/local/apache2/htdocs

Скопировать файл из локальной файловой системы в файловую систему контейнера

docker container cp 2d83314c9a66:/usr/local/apache2/htdocs/index.html src

Скопировать файл из файловой системы контейнера в локальную файловую систему

docker container cp | Docker Documentation

docker container commit CONTAINER [NAME:TAG]

Создать образ из контейнера

Реестры

docker login -u|--username -p|password [REGISTRY]

Внести регистрационные данные для указанного реестра (по умолчанию — docker.io)

docker logout [REGISTRY]

Удалить регистрационные данные для указанного реестра (по умолчанию — docker.io)

docker image pull IMAGE

Скачать образ из удаленного репозитория и сохранить в локальном

docker image push IMAGE

Загрузить образ в удаленный репозиторий

Системные команды

docker system df

Вывести информацию по использованию Docker’ом ресурсов файловой системы

Перечень инструкций Dockerfile

CMD

Установить команду, выполняемую при запуске контейнера

Установленная команда будет полностью перезаписана как command -a -b -c при запуске docker container run NAME command -a -b -c.

COPY

Скопировать файлы из исходного каталога локальной файловой системы в целевой каталог файловой системы контейнера

ENTRYPOINT

Установить команду, выполняемую при запуске контейнера

К установленной команде будут добавлены аргументы -a -b -c при запуске docker container run NAME -a -b -c.

К установленной команде будут добавлены аргументы -a -b -c если в файле Dockerfile для сборки текущего образа будет дополнительно присутствовать запись CMD ["-a", "-b", "-c"].

К установленной команде будут добавлены аргумены -d -e при запуске docker container run NAME -d -e, несмотря на наличие в файле Dockerfile записи CMD ["-a", "-b", "-c"]. То есть аргументы, указанные в данной записи будут перезаписаны.

К установленной команде будут добавлены аргументы -a -b -c если в файле Dockerfile для сборки образа основанного на текущем образе будет присутствовать запись CMD ["-a", "-b", "-c"].

FROM

WORKDIR

Установить текущий рабочий каталог для последующих инструкций RUN, CMD, ENTRYPOINT, COPY, ADD

Контейнеры

Контейнер — это изолированное окружение для запуска образов. Контейнер обеспечивает выделение виртуальных вычислительных ресурсов таких как имя хоста, сетевой интерфейс, файловая система. Эти ресурсы уникальны для каждого контейнера. Однако, каждый контейнер использует вычислительный ресурс ЦПУ, память хоста и ядро ОС в разделяемом режиме. То есть, часть ресурсов выделенная и часть ресурсов разделяемая. Подобное разделение обеспечивает максимальную утилизацию ресурсов — если процессу в контейнере требуется некоторый ресурс (например, память), он выдляется, если же некоторый ресурс не требуется, он не выделяется или высвобождается после использования и никоим образом не резервируется за контейнером, и таким образом данный ресурс может быть использован где-то ещё, например в процессе, запущенном в другом контейнере.

Контейнеры используют операционную систему хоста. Отсутствие своей собственной операционной системы в контейнере позволяет высвобождать значительное количество ресурсов, требуемых для обеспечения работы операционной системы (процессерное время и память).

Контейнеры обеспечивают плотность и изолированность.

[Stoneman: Learn Docker in a month of lunches; 2.2]

Свойства контейнеров

Модуляризация

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

Унификация

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

Портируемость

Единая основа для запуска в различных окружениях.

Изолированность

Возможность иметь изолированные друг от друга окружения.

Легковесность

Потребление минимального количества ресурсов.

Образы

Образ — это пакет с программой и всеми зависимостями.

Образ содержит метаинформацию и полезную нагрузку. Метаинформация, в числе прочего, содержит профиль сборки образа.

docker image history IMAGE вывести информацию по профилю сборки образа

Образ состоит из слоев. Каждая строка вывода docker image history содержит информацию о том, как создавался конкретный слой указанного образа.

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

Физически, слой это отдельный файл, хранящийся в файловой системе.

Разбиение образа на слои позволяет повторно использовать один и тот же слой в нескольких образах (потенциально в достаточно большом их количестве), тем самым экономя ресурсы файловой системы.

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

При изменении слоя с приложением и пересборки образа будет создан новый слой.

При изменении инструкции в сборочном файле Dockerfile будет создан новый слой для результата данной инструкции.

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

Рассмотрим пример.

Sending build context to Docker daemon  4.096kB
Step 1/7 : FROM node
 ---> 1d88d89c7230
Step 2/7 : ENV TARGET="linux.org.ru"
 ---> Using cache
 ---> eebac6754c54
Step 3/7 : ENV METHOD="HEAD"
 ---> Using cache
 ---> 8b723b3a219e
Step 4/7 : ENV INTERVAL="2000"
 ---> Using cache
 ---> 98d9640d707a
Step 5/7 : WORKDIR /web-ping
 ---> Using cache
 ---> 715c587a041b
Step 6/7 : COPY app.mjs .
 ---> f6ef9cf8f3dd
Step 7/7 : CMD ["node", "/web-ping/app.mjs"]
 ---> Running in 0b5d885988bd
Removing intermediate container 0b5d885988bd
 ---> 28b468469edd
Successfully built 28b468469edd
Successfully tagged web-ping:v9

В примере, шаги 2—5 используют уже имеющиеся слои, а шаги 6 и 7 создают новые.

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

Существуют промежуточные сборочные слои. Эти слои содержат результаты выполнения инструкций из Dockerfile’а. При сборке, в определенных обстоятельствах эти слои будут повторно использованы. Тем самым экономятся ресурсы при проведении сборки. (В особенности это значимо при многократных пересборках.)

Какие слои используются повторно, какие слои удаляются, какие слои воссоздаются заново — всё это отображается в отладочном выводе в процессе проведения сборки.

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

Если инструкция изменилась, то изменяется и её хэш. Например, инструкции ENV HOST="google.com" и ENV HOST="yandex.ru" будут иметь разные хэши. Соответственно, слой с данной инструкцией будет воссоздан заново.

Если изменилось содержимое файла в инструкции COPY app.js ., то слой также будет воссоздан заново.

Каждый раз в момент воссоздания слоя-образа будет нарушена целостность кэша слоев-образов. В этом случае слои-образы всех последующих инструкций также будут воссозданы заново вне зависимости от того изменилась ли инструкция (её хэш) или нет. Таким образом, кэш слоев-образов будет обновлен.

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

[Stoneman: Learn Docker in a month of lunches; 3.4, 3.5]

Ссылка на образ

docker.io¹/shamaoke²/murasaki³:latest⁴

  1. Домен реестра образов (по умолчанию — docker.io)

  2. Имя учетной записи владельца образа (человек, либо организация)

  3. Название репозитория для хранения образов приложения

  4. Тэг, маркирующий версию образа приложения (по умолчанию ­ latest)

Мультиэтапная сборка

Docker позволяет осуществлять мультиэтапную сборку образов. Такой вид сборки осуществляется посредством использования нескольких инструкций FROM.

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

Файл сборки может содержать несколько инструкций FROM. Каждой такой инструкции может быть передано имя. В дальнейшем данное имя может быть использовано как ссылка.

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

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

FROM java AS build
# A set of instructions for building a Java application
# Create the `rabbit` Java executable at the end

FROM java AS test # this name isn't actually used as a reference; it's here just for clearance
COPY --from=build /app/rabbit /app/rabbit
# A set of instructions for creating a testing environment and testing the Java application
# If tests fail the build process will fail as well

FROM java AS release
COPY --from=build /app/rabbit /app/rabbit
# The final image won't contain testing tools and we will have an executable
# which successfully passed tests

CMD /usr/bin/java /app/rabbit

[Stoneman: Learn Docker in a month of lunches; 4.1]

Для каждого этапа мультиэтапной сборки создается свой собственный кэш. При нарушении целостности кэша (в связи с изменением в командах Dockerfile’а) пересборка образов для последующих команд происходит только для данного этапа, поскольку целостность кэшей других этапов не нарушается.

Мультиэтапная сборка позволяет изолировать финальный образ от вспомогательного инструментария, используемого для его создания (загрузочные утилиты, утилиты сборки, тестирования и т. п.). Этим во-первых экономятся вычислительные ресурсы (как при сборке образа, так и в продакшене) и во-вторых — обеспечивается более высокий уровень безопасности, поскольку вспомогательный инструментарий может иметь соответствующие изъяны.

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

[Stoneman: Learn Docker in a month of lunches, 4.5]

Dockerfile

Основные идеи

[Stoneman: Learn docker in a month of lunches; 3.2]

Разбиение команд

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

Рассмотрим пример.

RUN mvn dependency
RUN mvn package

В примере ресурснозатратная команда mvn dependency была извлечена из команды сборки mvn package. При следующем запуске docker build она не будет выполняться заново, вместо этого её результат будет извлечен из кэша.

[Stoneman: Learn Docker in a month of lunches, 4.2]

Примеры

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

# base stage
FROM alpine AS builder

RUN apk --update-cache add openjdk11-jdk
RUN apk --update-cache add maven

WORKDIR /build
COPY pom.xml .

# first reference to the base stage
FROM builder AS build1
COPY . /build
RUN mvn package service1

# second reference to the base stage
FROM builder AS build2
COPY . /build
RUN mvn package service2

# final stage
FROM alpine

RUN apk --update-cache add openjdk11-jre

WORKDIR /app

ENTRYPOINT ["/usr/bin/java", "-jar", "..."]

# using the artifact from the first build stage
COPY --from=build1 /build/service1.jar .

# using the artifact from the second build stage
COPY --from=build2 /build/service2.jar .

Использование индекса для ссылки на неименованный этап в инструкции COPY.

FROM alpine
...

FROM alpine
COPY --from=0 ...

Прерывание процесса сборки на определенном этапе посредством опции --target команды build.

# :::base:::
FROM alpine AS base

RUN apk --update-cache add zsh

WORKDIR /app
ENTRYPOINT ["/app/greeting"]

# :::rabbit:::
FROM base AS rabbit
COPY rabbit/rabbit greeting
RUN chmod 744 greeting

# :::fox:::
FROM base AS fox
COPY fox/fox greeting
RUN chmod 744 greeting

# :::wolf:::
FROM base AS wolf
COPY wolf/wolf greeting
RUN chmod 744 greeting

docker image build --target fox .

Сылки

Документация