Часть 1. Предпосылки и основы
Глава 4. Основы Docker
Содержание
В этой главе мы расширим фундаментальные понятия Docker. Мы начнем с рассмотрения общей архитектуры Docker, включая технологии, которые она выстраивает. Затем следуют более глубокие разделы по построению образов Docker, сетевых контейнеров и обработки данных в томах. Глава заканчивается обзором остальных команд Docker.
Совет | |
---|---|
Поскольку данная глава содержит большое количество справочного материала, вы можете предпочесть поверхностно пробежаться по ее основным моментам и перейти к Главе 5, возвращаясь к данной главе по мере необходимости. |
Чтобы понять как лучше применять Docker и некоторые из наиболее необычных режимов работы в Docker, будет неплохо получить представление о том, как платформа Docker собирается под покровом.
На Рисунке 4-1 мы можем увидеть основные компоненты установки Docker:
-
По центру находится демон Docker, который отвечает за создание, работу и мониторинг контейнеров, а также за построение и сохранение образов, что совместно представлено в правой части диаграммы. Демон Docker запускается выполнением
docker daemon
, о чем обычно заботится операционная система хоста. -
Клиент Docker располагается слева и используется для общения с демоном Docker посредством HTTP. По умолчанию это происходит через сокет домена Unix (UDS или, иначе: IPC, сокет межпроцессного взаимодействия), но также может использоваться сокет TCP, делая возможными удаленные клиенты, или дескриптор файла для сокетов, управляемых sytemd. Поскольку все взаимодействие должно выполняться в HTTP, достаточно легко подключаться к удаленным демонам Docker и разрабатывать связывание программного языка, но это также имеет последствия для того, как реализуется функциональность, например требования контекста сборки для Dockerfile, как описано в разделе "Встроенный контекст". Используемый для взаимодействия с демоном API хорошо определен и документирован, что позволяет разработчикам писать программы, которые напрямую взаимодействуют с демоном без использования клиента Docker. Клиент Docker и демон распространяются в виде исполняемого (двоичного) файла.
-
Реестры Docker хранят и распространяют образы. Реестром по умолчанию является Docker Hub, который размещает тысячи общедоступных образов а также курирует "официальные" образы. Многие организации имеют собственные реестры, которые могут применяться для хранения коммерческих или критически важных образов а также избегать перегруженности необходимостью загрузки образов из интернета. Для информации о работе ваших собственных реестров смотрите раздел "Работа вашего собственного реестра". Демон Docker загружает образы определяемые запросами
docker pull
. Он также автоматически загружает образы определенные запросомdocker run
и в инструкцииFROM
Dockerfile когда они не доступны локально.
Демон Docker использует "драйвер выполнения" для создания контейнера. По умолчанию это собственный драйвер Docker runc, однако также существует наследуемая поддержка для LXC. Runc очень тесно подогнан к следующей функциональности ядра:
-
cgroups, которые отвечают за управление используемыми контейнерами ресурсами (т.е. за использование ЦПУ и оперативной памяти). Они также отвечают за замораживание (freezing) и размораживание (unfreezing) контейнеров, которые используются в функциональности
docker pause
. -
namespaces (пространство имен) ответственно за изоляцию контейнеров; гарантирующую что файловая система, имя хоста, сетевая среда и процессы контейнера отделены от остальной части вашей системы.
Libcontainer также поддерживает SElinux и AppArmor, которые могут быть разрешены для более плотной безопасности. За дополнительной информацией обращайтесь к Главе 13.
Другой лежащей в основе Docker главной технологией является файловая система UFS (Union File System), используемая для хранения уровней для контейнеров. UFS обеспечивается одним из нескольких драйверов хранения из AUFS, devicemapper, BTRFS или Overlay. Отсылаем к предыдущему обсуждению в "Образы, контейнеры и UFS".
Движок Docker и его хаб не представляют сами по себе законченное решение для работы с контейнерами. Большинство пользователей обнаружат, что им требуется поддержка служб и программного обеспечения подобного средствам управления кластером, инструментарию служб обнаружения, а также развитым сетевым возможностям.
Как описано в "Плагины и прокладка труб", Docker Inc. планирует построить полное коробочное решение которое включает в себя эту функциональность, но при этом позволяет пользователям легко выгружать установленные по умолчанию компоненты в замен разработанных третьими фирмами. Стратегия "заменяемых батарей" прежде всего относится к уровню API - позволяя компонентам прицепляться к движку Docker - но также могут рассматриваться как делающие возможной поддержку технологий Docker упакованных в виде независимого исполняемого (двоичного) кода способного легко заменяться эквивалентами третьих сторон.
Текущий список предоставляемых Docker поддерживаемых технологий включает:
- Swarm
- Кластерное решение Docker. Swarm может объединять в группы различные хосты Docker, позволяя пользователям представлять их как о едином ресурсе. За дополнительной информацией обращайтесь к Главе 12.
- Compose
- Docker Compose является инструментом для построения и выполнения приложений состоящих из множества контейнеров Docker. Изначально он применялся при разработке и тестировании, а не в промышленной эксплуатации. Для ознакомления с подробностей отсылаем вас к разделу "Автоматизация при помощи Compose".
- Machine
- Docker Machine устанавливает и настраивает хосты Docker на локальных и удаленных ресурсах. Machine также настраивает клиента Docker, делая его легко перемещаемым между окружениями. За примером обращайтесь к Главе 9.
- Kitematic
- Kitematic является графическим интерфейсом Mac OS и Windows для работы контейнеров Docker и управления ими
- Docker Trusted Registry
- (Доверенный реестр Docker) это решение в рамках Docker для хранения и управления образами Docker. Это эффективная локальная версия Docker Hub, которая может интегрироваться с существующей инфраструктурой безопасности и помогать организациям соблюдать правила относительно хранения и безопасности данных. Функциональность содержит метрики, управление доступом на основе ролей (RBAC, Role-Based Access Control), а также журналы, причем все управляется с консоли администратора. В настоящее время это единственный продукт Docker Inc, не имеющий открытого исходного кода.
Уже существует большой список служб и приложений третьих сторон, который встроен в Docker и работает с ним. Некоторые решения уже появились в следующих областях:
- Сетевая среда
- Создание охватывающих хосты сетей контейнеров является нетривиальной задачей, которая может быть решена различными способами. В этой области появилось несколько решений, включающих Weave и Проект Calico. Кроме того, Docker вскоре получит интегрированное сетевое решение с названием Overlay. Пользователи получат возможность выгружать драйвер Overlay для других решений, использующих сетевые подключаемые структуры Docker.
- Обнаружение служб
- При поступлении контейнера Docker, ему нужен некий способ нахождения прочих служб, с которыми ему следует взаимодействовать и которые обычно также работают в виде контейнеров. Поскольку контейнерам динамично назначаются IP адреса, это не является тривиальной задачей в больших системах. Решения в этой сфере включают Consul, Registrator, SkyDNS и etcd
- Управление оркестровкой и кластеризацией
- В больших реализациях контейнеров для мониторинга и управления системой существенен инструментарий для этих целей. Каждый новый контейнер нуждается в размещении на хосте, в мониторинге и обновлении. Система должна реагировать на отказы или изменения нагрузки посредством соответствующих перемещений, запусков или остановок контейнеров. Существует ряд конкурирующих решений в этой отрасли, включающих Kubernetes от Google, Marathon (конструктив для Mesos), CoreOS Fleet и собственный инструментарий Docker Swarm.
Все эти темы обсуждаются в больших подробностях в Части III. Стоит также отметить альтернативы Docker Trusted Registry, включающие CoreOS Enterprise Registry и JFrog Artifactory.
В добавление к упомянутым ранее подключаемым сетевым драйверам Docker также поддерживает подключаемые тома (volume plugin) для интеграции с прочими системами хранения. Достойные упоминания подключаемые тома включают Flocker, инструмент множества хостов управления и миграции данных, а также GlusterFS для распределенного хранилища. Дополнительная информация по подключаемым конструктивам может быть найдена на веб- сайте Docker.
Интересный побочный эффект от роста популярности контейнеров заключается в новом поколении операционных систем, предназначенных для их хостинга. Хотя Docker успешно работает в большинстве современных дистрибутивов Linux, подобных Ubuntu и Red Hat, существует ряд проектов в стадии реализации для создания минимальных и простых в сопровождении дистрибутивов, сосредоточенных исключительно на работе контейнеров (или контейнеров и виртуальных машин), особенно в контексте насыщения цетнра обработки данных или кластера. Примеры включают Проект Atomic, CoreOS и RancherOS.
Мы обсудим хостинг Docker более подробно в Главе 9, но здесь стоит отметить некоторые из многих вариантов. Многие традиционные поставщики облачных решений, включающие Amazon, Google и Digital Ocean привнесли определенный уровень в продукцию Docker. Наиболее интересным из них, возможно, является Container Engine Google, поскольку он строится непосредственно поверх Kubernetes. Конечно, даже если поставщик облачных решений не имеет определенного предложения решений Docker, все еще стандартным будет предоставление виртуальных машин, которые могут выполнять контейнеры Docker.
Joyent также выходит в свет со своим собственным предложением контейнеров под названием Triton, построенным поверх SmartOS. Реализовав API Docker в своих собственных контейнере и технологии эмуляции Linux, Joуent смог создать общедоступное облако, которое взаимодействует со стандартным клиентом Docker. Важно отметить, что Joyent полагает, что его реализация контейнера достаточно безопасна чтобы работать непосредственно на голом железе вместо размещения его в виртуальные машины, что может повлечь значительную экономию эффективности, в особенности в плане операций ввода/ вывода.
Существуют также различные проекты построения платформ PaaS поверх Docker, в том числе Deis, Flynn и Paz.
В разделе "Построение образов
из Dockerfile" мы видели, что первоначальный вариант изготовления нового образа заключается в Dockerfile и команде
docker build
. Данный раздел рассмотрит что в этом случае
происходит слегка подробнее и завершится руководством по различным инструкциям, которые могут использоваться в Dockerfile. Полезно
иметь некое представление о том как работает команда построения изнутри, поскольку ее поведение порой выглядит загадочным.
Команде docker build
необходимы Dockerfile и контекст сборки
(build context, который может быть пустым). Контекст сборки является набором локальных файлов и
каталогов, на которые можно ссылаться в инструкциях ADD
и COPY
в Dockerfile и обычно определяются в виде пути и каталога. Например, в разделе "Построение образов из Dockerfile" мы применяем команду
построения docker build -t test/cowsay-dockerfile .
, которая устанавливает контекст в
'.'
, текущий рабочий каталог. Все файлы и каталоги в пути формируют контекст сборки и будут
отосланы демону Docker как часть процесса построения.
В случаях когда контекст не описан - если в Dockfile передается только URL или содержимое Dockfile передаётся в конвейере через STDIN - контекст сборки рассматривается как пустой.
Предостережение | |
---|---|
Не используйте После того как контекст сборки накоплен в tarball и отослан демону Docker, вы на самом деле не хотите использовать каталог с уже
имеющимся большим числом файлов. Например, использование |
Если задан URL, начинающийся с http или https, то он предполагается прямой ссылкой на Dockerfile. Вряд ли будет полезно не связывать никакой контекст с Dockerfile (и не принимать ссылки на архивы).
Репозиторий git также может быть определен в качестве контекста сборки. В таком случае клиент Docker клонирует репозиторий и все подмодули во временный каталог, который далее отсылается демону Docker в качестве контекста сборки. Docker воспринимает ваш контекст как репозиторий git если путь начинается с github.com/, _git@ или _git://. В общем случае я хотел бы предложить избегать такого метода и вместо этого проверять репозитории вручную, что является более гибким и оставляет меньше шансов для путаницы.
Клиент Docker также может получать входные данные через STDIN
, задавая
"-
" в качестве аргумента на месте контекста сборки. Входные данные также могут быть
Dockerfile-ом без какого бы то ни было контекста (т.е. docker build - < context.tar.gz
).
Файлы архива могут быть в формате tar.gz
, xz
или bzip2
.
Местонахождение Dockerfile внутри контекста может быть определено аргументом -f
, (т.е.
docker build -f dockerfiles/Dockerfile.debug
). Если он не определен явно, Docker будет искать
файл с названием Dockerfile
в корне контекста.
Совет | |
---|---|
Использование файла .dockerignore Чтобы удалить не нужные файлы из контекста сборки, вы можете воспользоваться файлом .dockerignore.
Этот файл должен содержать имена подлежащих исключению файлов, разделенные символами новой строки. Допускаются символы
подстановки * и ?. Например, у нас имеется следующий файл
.git1 */.git2 */*/.git3 *.sw?4
Отсутствует полная поддержка регулярных выражений наподобие На момент написания книги не существовало способа отметки соответствия файлов по всем каталогам (т.е. вы не можете игнорировать и test.tmp, и dir1/test.tmpв одном выражении). |
Новые пользователи Docker часто бросают как бы между прочим построенные образы. Каждая инструкция в Dockerfile имеет результатом новый
уровень образа, который может быть использован для запуска контейнера. Новый уровень создается запуском контейнера, применяющего образ
предыдущего уровня, выполнением инструкции Dockerfile и сохранением нового образа. После успешного завершения инструкции Dockerfile
промежуточный контейнер будет удален, если не был задан аргумент --rm=false
(Не отчаивайтесь если
я вас потерял в данном месте. Все встанет на свои места после просмотра вывода docker build
в
нашем отладочном примере). Поскольку результат каждой инструкции состоит в статичном образе - по существу лишь файловая система и некие
метаданные - все выполняемые в инструкции процессы будут остановлены. Это означает, что хотя вы можете запускать в инструкции
RUN
процессы с длительным временем жизни, например базы данных или демоны SSH, они уже не будут
исполняться при обработке следующей инструкции или запуске контейнера. Если вы хотите стартовать с контейнером службу или процесс,
они должны запускаться из инструкции ENTRYPOINT
или CMD
.
Вы можете посмотреть полный набор создавших образ уровней выполнив команду docker history
.
Например:
$ docker history mongo:latest IMAGE CREATED CREATED BY ... 278372cb22b2 4 days ago /bin/sh -c #(nop) CMD ["mongod"] 341d04fd3d27 4 days ago /bin/sh -c #(nop) EXPOSE 27017/tcp ebd34b5e9c37 4 days ago /bin/sh -c #(nop) ENTRYPOINT &{["/entrypoint. f3b2b8cf226c 4 days ago /bin/sh -c #(nop) COPY file:ef2883b33ed7ba0cc ba53e9f50f18 4 days ago /bin/sh -c #(nop) VOLUME [/data/db] c537910de5cc 4 days ago /bin/sh -c mkdir -p /data/db && chown -R mong f48ad436057a 4 days ago /bin/sh -c set -x df59596772ab 4 days ago /bin/sh -c echo "deb http://repo.mongodb.org/ 96de83c82d4b 4 days ago /bin/sh -c #(nop) ENV MONGO_VERSION=3.0.6 0dab801053d9 4 days ago /bin/sh -c #(nop) ENV MONGO_MAJOR=3.0 5e7b428dddf7 4 days ago /bin/sh -c apt-key adv --keyserver ha.pool.sk e81ad85ddfce 4 days ago /bin/sh -c curl -o /usr/local/bin/gosu -SL "h 7328803ca452 4 days ago /bin/sh -c gpg --keyserver ha.pool.sks-keyser ec5be38a3c65 4 days ago /bin/sh -c apt-get update 430e6598f55b 4 days ago /bin/sh -c groupadd -r mongodb && useradd -r 19de96c112fc 6 days ago /bin/sh -c #(nop) CMD ["/bin/bash"] ba249489d0b6 6 days ago /bin/sh -c #(nop) ADD file:b908886c97e2b96665
В случае неудачного построения может быть очень полезным запускать предшествующий отказу уровень. Например, если у нас имеется следующий Dockerfile:
FROM busybox:latest RUN echo "This should work" RUN /bin/bash -c echo "This won't"
и попытка его построения:
$ docker build -t echotest . Sending build context to Docker daemon 2.048 kB Step 0 : FROM busybox:latest ---> 4986bf8c1536 Step 1 : RUN echo "This should work" ---> Running in f63045cc086b1 This should work ---> 85b49a851fcc2 Removing intermediate container f63045cc086b3 Step 2 : RUN /bin/bash -c echo "This won't" ---> Running in e4b31d0550cd /bin/sh: /bin/bash: not found The command '/bin/sh -c /bin/bash -c echo "This won't"' returned a non-zero code: 127
- 1
- Идентификатор временного контейнера, запускаемого Docker-ом для выполнения нашей инструкции.
- 2
- Идентификатор образа, созданного из контейнера.
- 3
- Теперь временный контейнер удаляется.
Хотя в данном случае проблема совершенно очевидна из сообщения об ошибке, мы можем выполнить образ созданный на последнем успешном уровне для отладки данной инструкции. Отметим, что мы используем здесь последний идентификатор образа (85b49a851fcc), а не идентификатор последнего контейнера (e4b31d0550cd):
$ docker run -it 7831e2ca1809 / # /bin/bash -c "echo hmm" /bin/sh: /bin/bash: not found / # /bin/sh -c "echo ahh!" ahh! / #
И проблема становится даже ещё более очевидной: образ busybox
не содержит оболочку
bush
.
Docker также кэширует каждый уровень с целью ускорения построения образов. Такое кэширование очень важно эффективным рабочим потокам, но несколько безыскусно. Кэш применяется для инструкции если:
-
Предыдущая инструкция была найдена в кэше И
-
в кэше существует уровень, который имеет в точности те же инструкцию и родительский уровень (даже несущественные пробелы сделают кэш недействительным)
Помимо этого в случае инструкций ADD
и COPY
кэш будет
недействительным если были изменены контрольная сумма или метаданные для любого из файлов в кэше.
Это означает, что инструкция RUN
, которая не гарантирует получение одного и того же результата
при множестве исполнений все еще будет кэширована. Будьте особенно внимательны к этому обстоятельству
если вы загружаете файлы, запускает обновление apt-get или клонируете источник репозитория.
Если вам нужно отказать в кэшировании, вы можете выполнить docker build
с аргументом
--no-cache
. Вы также можете добавлять или изменять инструкцию перед точкой, в которой вы
хотите отвергнуть кэш; и по этой причине вы можете увидеть Dockerfile со строками наподобие:
ENV UPDATED_ON "14:12 17 February 2015" RUN git clone....
Я бы предостерег от применения подобной техники, поскольку она ведёт к запутыванию последующих пользователей образов, в особенности когда образ был построен в день, отличный от установленного в строке.
При создании собственных образов вам придется определиться с какого базового образа начинать. Существует множество вариантов выбора и стоит потратить определенное время чтобы понять различные преимущества и недостатки каждого.
Наилучшим выбором будет не создавать собственный образ совсем - вы можете просто воспользоваться уже существующим и смонтировать свои собственные файлы настройки и/ или данные в него. Возможно это будет лучшим выбором для распространенного прикладного программного обеспечения, такого как базы данных и веб-сервера, где существуют официальные доступные образы. В общем случае вам гораздо лучше воспользоваться официальным образом, чем обкатывать свой собственный - вы получите преимущество от чужих работы и опыта в выяснении того как лучше выполнять программное обеспечение в контейнере. Если существует конкретный довод почему официальный образ не подходит для вас, рассмотрите возможность открытия проблемы в родительском проекте, поскольку, скорее всего, и другие люди сталкиваются с аналогичными задачами или знают как обойти эту проблему.
Если вам требуется образ для хостинга вашего собственного приложения, вначале окиньте взглядом: существует ли образ на официальной основе
для поддержки используемого вами языка или инфраструктуры (например, Go или Ruby on Rails). Зачастую вы можете воспользоваться отдельными
образами для построения и распространения вашего программного обеспечения (например, вы можете применять образ
java:jdk
для построения приложения Java, однако затем распространять полученный в результате файл
JAR с применением более скромного в размерах образа java:jre
, который избавлен от ненужного
инструментария построения). Аналогично, некоторые официальные образы (например, node
) имеют
специальные "тонкие" построения, в которых удалено множество средств разработки и заголовков.
Иногда на практике вам нужен небольшой, но полный дистрибутив Linux. Если я собираюсь следовать истинному минимализму, я буду
применять образ alpine
, который требует размеров всего лишь в 5МБ, но все таки имеет значительный
менеджер пакетов для простой установки пакетов и инструментов. Если мне нужен более полный образ, я обычно применяю один из образов
debian
, который намного меньше чем также общеупотребимые образы
ubuntu
, но имеет доступ к тем же пакетам. Если ваша организация связана с определенным дистрибутивом
Linux, вам также следует найти для него образ Docker. Это может иметь больше смысла, чем переход на новый дистрибутив, который ваша
организация не поддерживает или с которым у нее нет опыта работы.
Большую часть времени не существует необходимости сильно беспокоиться о максимально возможном сокращении объёма образа. Помните, что
базовые образы совместно используются различными образами, поэтому если вы уже имеете образ ubuntu:14.04
,
и извлекаете из хаба (Hub) основанный на нем образ, вместо всего образа целиком вы вытащите только нужные вам изменения. Тем не менее,
минимизированные образы несомненно являются большим плюсом когда нам необходимо быстрое развертывание и простое распространение.
Можно брать с собой сверхминимизированные образы и поставлять их исключительно в двоичном виде. Чтобы сделать это следует написать
Dockerfile который наследуется из образа специальной рабочей области (полностью очищенная файловая система) с простой копией вашего исполняемого
кода и установить соответствующую инструкцию CMD
. Ваш исполняемый код должен содержать все необходимые
библиотеки (никаких динамических связываний) и не должен иметь возможности вызова внешних команд. Кроме того помните, что двоичный код должен
быть скомпилирован под архитектуру вашего контейнера, которая может отличаться от архитектуры машины, выполняющей клиента Docker. (На самом
деле можно продвинуть эту концепцию минимальности вычислений ещё дальше, отказавшись от Docker и полного ядра Linux в пользу подхода
микроядер - unikernel.
В архитектуре микроядра приложение объединяется с ядром, содержащим только ту функциональность, которая нужна этому приложению и далее
непосредственно запускается гипервизором. Это позволяет избавляться от ряда ненужных уровней кода и неиспользуемых драйверов, получая в
результате намного меньшее и более быстрое приложение - микроядра обычно загружаются в пределах секунд, т.е. они могут запускаться в качестве
непосредственного ответа на пользовательские запросы. Если вы хотите узнать больше об этом обратите внимание на Unikernels: Rise of the Virtual Library Operating System Anil Madhavapeddy
и David J. Scott, а также на MirageOs.)
Хотя минималистский подход может быть очень заманчивым, обратите внимание на то, что он может поставить вас в сложную ситуацию когда дело
доходит до отладки и сопровождения - busybox
не будет иметь большого числа инструментов для работы с
ним, а если вы применяете рабочий образ (scratch
), у вас даже не будет оболочки.
Ответ Phusion | |
---|---|
Другим интересным выбором основного образа является
Что касается меня лично, я рекомендовали бы применять базовый образ Phusion только если у вас имеется потребность выполнять множество процессов,
|
Предостережение | |
---|---|
Реконструкция образов Отметим, что при выполнении Это становится особенно актуальным когда выходят обновления безопасности общих базовых образов, например,
|
Данный раздел вкратце рассмотрит различные инструкции, доступные для применения в Dockerfile. Он не погружается вглубь деталей, частично из-за того что они все ещё изменяются и возможно быстро станут не современными, а частично потому,что существует всесторонняя и всегда актуальная документация, доступная на веб- сайте Docker. Комментарии в Dockerfile выделяются началом строки с символа #.
Сопоставление форматов exec и shell | |
---|---|
Некоторые инструкции ( |
В Dockerfile доступны следующие инструкции:
ADD
- Копирует файлы из контекста сборки или с удаленного URL в образ. Если файлы архива добавляются из локального пути, они будут автоматически
распаковываться. Поскольку диапазон функциональности, покрываемый
ADD
достаточно большой, обычно лучше предпочесть более простую командуCOPY
для копирования файлов и каталогов в контексте сборки и инструкцииRUN
ccurl
илиwget
для загрузки удаленных ресурсов (что оставляет возможность обработки и удаления загруженного в той же самой инструкции). CMD
- Выполняет данную инструкцию при запуске контейнера. Если была определена
ENTRYPOINT
, данная инструкция будет интерпретироваться как аргумент дляENTRYPOINT
(в этом случае убедитесь, что вы используете формат exec). ИнструкцияCMD
перекрывается любыми аргументами вdocker run
после имени данного образа. Эффект имеет только последняя инструкцияCMD
, а все предыдущие инструкции перекрываются (включая присутствующие в базовых образах). COPY
- Применяется для копирования файлов из контекста сборки в ваш образ. Она имеет две формы,
COPY src dest_
иCOPY ["src", "dest"]
, причем обе копируют файлы или каталоги src в dest внутри контейнера. Формат массива JSON требуется если пути имеют внутри пробелы. Для определения множества файлов или каталогов могут использоваться символы подстановки. Отметим, что вы не можете определять пути src вне вашего контекста сборки (т.е., ../another_dir/myfile не будет работать). ENTRYPOINT
- Устанавливает исполняемый код (и аргументы по умолчанию), которые должны быть выполнены при запуске контейнера. Все инструкции
CMD
или параметры дляdocker run
после имени данного образа будут передаваться в качестве параметров для ее исполнения. ИнструкцииENTRYPOINT
часто применяются для обеспечения "запускающих" сценариев, которые инициализируют переменные и службы до интерпретации всех заданных аргументов. ENV
- Устанавливает переменные окружения внутри образа. Она может служить ссылкой в последующих инструкциях. Например:
... ENV MY_VERSION 1.3 RUN apt-get install -y mypackage=$MY_VERSION ...
Эти переменные также будут доступны внутри образа. EXPOSE
- Указывает Docker, что данный контейнер будет иметь процесс, прослушивающий заданный порт или порты. Данная информация используется Docker
при соединении контейнеров (см. Связывание контейнеров) или публикуйте порты предоставляя
параметр
-P
вdocker run
; сама по себе инструкцияEXPOSE
не имеет влияния на сетевую среду. FROM
- Устанавливает базовый образ для Dockerfile; последующие инструкции выполняют построение поверх данного образа. Базовый образ определяется как
IMAGE:TAG
(например,debian:wheezy
). Если тег опущен, предполагается, что он будетlastest
, но я настоятельно рекомендую вам всегда устанавливать этот тег на определенную версию во избежание неожиданностей. Должна быть самой первой инструкцией в Dockerfile. MAINTAINER
- Устанавливает в вашем образе метаданные "Author" в значение данной строки. Вы можете извлекать его при помощи
span class="term">
docker inspect -f {{.Author}} IMAGE
. Обычно используется подробностей имен и контактных данных специалиста по сопровождению данного образа. ONBUILD
- Определяет инструкцию, которая должна быть выполнена позже, когда данный образ применяется в качестве базового уровня для другого образа. Это может быть полезным для обработки данных, которые будут добавлены в дочернем образе (т.е. эта инструкция может копировать в код из выбранного каталога и выполнять на текущих данных сценарий сборки).
RUN
- Выполняет заданную инструкцию внутри контейнера и фиксирует результат.
USER
- Устанавливает пользователя (через имя или UID) для использования во всех последующих инструкциях
RUN
,CMD
илиENTRYPOINT
. Отметим, что UID одни и те же и в хосте, и в контейнере, однако имена пользователей могут быть назначены для различных UID, что может сделать вещи мудрёными при установке разрешений. VOLUME
- Определяет описываемый файл иликаталог в качестве тома. Если этот файл или каталог уже существуют в вашем образе, они будут скопированы в том после запуска контейнера. Если задано множество параметров, они интерпретируются как множество определений томов. Вы не можете определять каталог хоста для тома внутри Dockerfile по причинам переносимости и безопасности. Для получения дополнительной информации ознакомьтесь с разделом "Управление данными томами и контейнерами данных".
WORKDIR
- Устанавливает рабочий каталог для всех последующих инструкций
RUN
,CMD
,ENTRYPOINT
иADD
,COPY
. Может применяться многократно. Могут быть использованы относительные пути, причем они разрешаются относительно предыдущегоWORKDIR
.
Допустим вы выполняете внутри контейнера веб сервер. Как вы обеспечите доступ во внешний мир? Ответ заключается в "публикации"
с командами -p
или -P
. Эти команды переадресовывают порты хоста
в контейнер. Например:
$ docker run -d -p 8000:80 nginx af9038e18360002ef3f3658f16094dadd4928c4b3e88e347c9a746b131db5444 $ curl localhost:8000 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> ...
Параметр -p 8000:80
предпишет Docker переадресовать порт хоста 8000 в порт 80 контейнера. В
качестве альтернативы параметр -P
может использоваться для сообщения Docker о необходимости
автоматического выбора свободного порта для переадресации в хосте. Например:
$ ID=$(docker run -d -P nginx) $ docker port $ID 80 0.0.0.0:32771 $ curl localhost:32771 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> ...
Основное преимущество команды -P
состоит в том, что вы больше не отвечаете за отслеживание
выделения портов, что становится важным если у вас есть различные порты публикации контейнеров. В этих случаях вы можете применять команду
docker port
для изучения выделения портов Docker.
Связи (link) Docker являются простейшим способом сделать возможным общение контейнеров на одном и том же хосте. При использовании сетевой модели Docker по умолчанию взаимодействие между контейнерами будет осуществляться через внутреннюю сетевую среду Docker, что означает, что взаимодействие не выходит за пределы сетевой среды вашего хоста.
Изменения сетевой среды Docker | |
---|---|
В последующих версиях Docker (вероятно, 1.9 и далее), идиомами средств сетевой среды контейнеров станут "службы публикации", (publish service), а не связи контейнеров. Тем не менее, поддержка связей будет продолжена в обозримом будущем и примеры из данной книги должны работать без изменений. С более подробной информацией о грядущих изменениях в сетевой среде можно ознакомится в разделе "Новая сетевая среда Docker". |
Связи инициализируются путем задания аргумента --link CONTAINER:ALIAS to docker run
,
где CONTAINER
является именем вашего связанного контейнера (в данном обсуждении и на протяжении всей
этой книги я буду ссылаться на подсоединяемый контейнер как на связанный контейнер -link container,
а запускавший связь контейнер как главный контейнер -master container- поскольку последний ответственен
за инициацию связи), а ALIAS
является локальным именем, используемым внутри главного контейнера для
ссылки на вашу связь контейнера.
Использование связей Docker также добавит псевдоним (алиас) и идентификатор связанного контейнера в /etc/hosts в вашем главном контейнере, делая возможной адресацию связанного контейнера по имени из главного контейнера.
Кроме того, Docker установит группу переменных окружения внутри главного контейнера, которые предназначены для осуществления более простого общения со связанным контейнером. Например, если мы создаем связь к контейнеру Redis:
$ docker run -d --name myredis redis c9148dee046a6fefac48806cd8ec0ce85492b71f25e97aae9a1a75027b1c8423 $ docker run --link myredis:redis debian env ATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=f015d58d53b5 REDIS_PORT=tcp://172.17.0.22:6379 REDIS_PORT_6379_TCP=tcp://172.17.0.22:6379 REDIS_PORT_6379_TCP_ADDR=172.17.0.22 REDIS_PORT_6379_TCP_PORT=6379 REDIS_PORT_6379_TCP_PROTO=tcp REDIS_NAME=/distracted_rosalind/redis REDIS_ENV_REDIS_VERSION=3.0.3 REDIS_ENV_REDIS_DOWNLOAD_URL=http://download.redis.io/releases/redis-3.0.3.tar.gz REDIS_ENV_REDIS_DOWNLOAD_SHA1=0e2d7707327986ae652df717059354b358b83358 HOME=/root
мы можем увидеть, что Docker установил переменные окружения с префиксом REDIS_PORT
, которые
содержат информацию о том как связаться с этим контейнером. Большинство из них выглядит несколько избыточными, поскольку информация в
их значениях содержится в имени переменной. Тем не менее, они полезны как форма документации, если больше ни для чего.
Docker также импортирует переменные окружения из связанного контейнера, причем они имеют префикс REDIS_ENV
.
Хотя такая функциональность может быть очень полезной, важно иметь ввиду, что именно это же происходит если вы используете переменные
для хранения секретной информации, например, токенов API или паролей баз данных.
По умолчанию контейнеры будут способны общаться друг с другом вне зависимости от того, связаны ли они в явном виде или нет. Если вы
хотите избежать взаимодействия контейнеров, которые не были связаны, применяйте параметры --icc=false
и
--iptables
при запуске демона Docker. Теперь, когда контейнеры связаны, Docker установит правила
Iptalles для разрешения взаимодействия контейнеров по всем портам, которые были объявлены как незащищенные (expose).
К сожалению, связи Docker, после их установления, имеют ряд недостатков. Возможно, самый существенный состоит в том что они статичны - хотя связи должны сохраняться после перезапуска работы контейнеров, они не обновляются если связанный контейнер заменен. Кроме того, связанный контейнер должен запускаться перед главным контейнером, что означает что вы не можете иметь двустороннюю связь.
Для получения дополнительной информации по сетевым контейнерам отсылаем вас к Главе 11.
Напомним, что тома Docker являются каталогами (технически каталогами или файлами, поскольку том может быть отдельным файлом), которые не являются частью UFS контейнера (подробнее: "Образы, контейнеры и UFS") - это просто находящиеся на хосте каталоги, которые закреплённо смонтированы (bind mount Закреплённое монтирование) в контейнер.
Существует три (хорошо, два с половиной, все зависит от способа подсчета) различных способа инициализации томов и важно понимать разницу между этими
методами. При первом мы можем объявить том во время выполнения при помощи флага -v
:
$ docker run -it --name container-test -h CONTAINER -v /data debian /bin/bash root@CONTAINER:/# ls /data root@CONTAINER:/#
Это создаст каталог /data внутри контейнера в томе. Все расположенные в каталоге /data
файлы будут скопированы в том. Мы можем найти место расположения тома на вашем хосте путём выполнения на этом хосте docker
inspect
из новой оболочки:
$ docker inspect -f {{.Mounts}} container-test [{5cad... /mnt/sda1/var/lib/docker/volumes/5cad.../_data /data local true}]
В этом случае том /data/
в контейнере это просто ссылка на каталог хоста
/var/lib/docker/volumes/5cad…/_data. Чтобы удостовериться в этом, мы можем добавить файл в каталог на нашем хосте (если вы
связаны с удаленным демоном Docker, вам придется выполнить данную команду на удаленном хосте через SSH. Если вы используете машину Docker - что будет
действительно так, если вы устанавливали Docker с помощью Docker Toolbox, вы можете сделать это с помощью docker-machine ssh default
):
$ sudo touch /var/lib/docker/volumes/5cad.../_data/test-file
И вы должны сразу увидеть внутри контейнера:
$ root@CONTAINER:/# ls /data test-file
Второй способ установить том заключается в применении инструкции VOLUME
в Dockerfile:
FROM debian:wheezy VOLUME /data
Это имеет в точности тот же эффект, что и определение -v /data
в docker run
.
Установка полномочий в Dockerfile | |
---|---|
Часто вам необходимо устанавливать полномочия и владельцев на какой-то том или инициализировать некий том с какими-то определенными по умолчанию данными или
файлами настройки. Здесь ключевым моментом, который вы должны знать, является то, что все инструкции в Dockerfile после инструкции
FROM debian:wheezy RUN useradd foo VOLUME /data RUN touch /data/x RUN chown -R foo:foo /data Мы хотим выполнить команды Следующий Dockerfile будет работать: FROM debian:wheezy RUN useradd foo RUN mkdir /data && touch /data/x RUN chown -R foo:foo /data VOLUME /data Когда в этом образе запускается контейнер, Docker скопирует все файлы из каталога тома в образ внутри тома контейнера. Этого не случится если вы опишите каталог хоста для данного тома (таким образом эти файлы хоста не будут случайно перезаписаны). Если по некоторой причине вы не можете установить полномочия и владельца в инструкции |
Третий (Эквивалентный второму?) способ заключается в расширении параметра -v
для
docker run
с явным закреплением каталога в хосте с применением формата -v HOST_DIR:CONTAINER_DIR
.
Это можно сделать в Dockerfile (что будет не портируемым и к тому же не безопасным). Например:
$ docker run -v /home/adrian/data:/data debian ls /data
Это смонтирует каталог /home/adrian/data на данном хосте в качестве /data
внутри вашего контейнера. Всё уже существующее в каталоге /home/adrian/data будет доступно внутри данного контейнера.
Если каталог /data уже существует в этом контейнере, его содержимое будет скрыто данным томом. В отличие от прочих
вызовов никакие файлы из рассматриваемого образа не будут копироваться в данный том, а том не будет удален Docker-ом (то есть
docker rm -v
не удалит том, который смонтирован в выбранном пользователем каталоге).
Синтаксис -v HOST_DIR:CONTAINER_DIR
очень полезен при совместном использовании файлов хостом и одним или более
контейнеров. Например, файлы настройки могут сохраняться на хосте и монтироваться в контейнер из общих образов.
Мы также совместно используем данные в контейнерах при помощи параметра --volumes-from CONTAINER
в
docker run
. Например, мы можем создать новый контейнер, который имеет доступ к вашим томам из контейнера в нашем
предыдущем примере примерно так:
$ docker run -it -h NEWCONTAINER --volumes-from container-test debian /bin/bash root@NEWCONTAINER:/# ls /data test-file root@NEWCONTAINER:/#
Важно отметить, что это работает вне зависимости от того, содержит или нет контейнер работающие в настоящий момент тома (в данном случае
container-test
). Пока существует по крайней мере одна связь с неким томом, он не может быть удален.
Общая практика состоит в создании контейнеров данных (data container) - контейнеров, чья основная роль
заключается в предоставлении совместного использования другим контейнерам. Главное преимущество такого подхода заключается в том, что он
поддерживает удобное пространство имен для томов которые легко могут загружаться с применением команды --volumes-from
.
Например, мы можем создать контейнер данных для базы данных PostgerSQL с помощью следующей команды:
$ docker run --name dbdata postgres echo "Data-only container for postgres"
Это создаст контейнер из образа postgres
и проведет инициализацию всех томов определенных в данном образе до
выполнения команды echo
и выхода (Мы могли бы применить любую команду, которая выйдет непосредственно здесь, однако
сообщение echo
будет служить нам напоминанием о цели данного контейнера при выполнении docker
ps -a
. Другим вариантом будет не запускать контейнер вообще, воспользовавшись командой docker create
вместо docker run
). Нет необходимости оставлять контейнеры данных исполняемыми, поскольку это будет пустой тратой
ресурсов.
Затем мы можем использовать этот том из других контейнеров при помощи параметра --volumes-from
. Например:
$ docker run -d --volumes-from dbdata --name db1 postgres
Тома могут быть удалены только если:
-
контейнер был удалён при помощи
docker rm -v
или -
В
docker run
был обеспечен флаг--rm
И
-
не существует связей контейнеров к данному тому
-
никакой каталог хоста не определено для этого тома (не применялся синтаксис
-v HOST_DIR:CONTAINER_DIR
)
На текущий момент это означает, что если вы не сильно беспокоитесь о том, чтобы всегда выполнять контейнеры описанным способом, то у вас, скорее всего, в каталоге установки Docker имеются бесхозные файлы и каталоги и не существует простого способа объяснения что они собой представляют. Docker работает над командой "volume" верхнего уровня, которая позволит вам перечислять, создавать, инспектировать и удалять тома независимых контейнеров. Ожидается ее появление в 1.9, который должен состояться к моменту публикации данной книги.
Данный раздел предоставляет короткий (по крайней мере в сравнении с официальной документацией) и не исчерпывающий обзор различных команд
Docker, в основном сосредотачиваясь на повседневно используемых командах. Поскольку Docker быстро меняется и эволюционирует, отсылаем вас к
официальной документации на веб- сайте Docker за исчерпывающими и
современными подробностями по данным командам. Я не описываю в подробностях параметры и синтаксис различных приводимых команд за исключением
docker run
. За этим отсылаю ко встроенному помощнику, к к торому можно получить доступ задав параметр
--help
в любой команде или посредством команды docker help
.
Мы уже видели команду docker run
в действии; это команда перехода для запуска новых контейнеров. В качестве
таковой она является на сегодня самой сложной командой и поддерживает большой список возможных параметров. Параметры позволяют пользователям
настраивать пользователям то, как должны работать образы, перезаписывать установки Dockerfile, настраивать сетевую среду, а также устанавливать
полномочия и ресурсы для определенного контейнера.
Следующие параметры управляют жизненным циклом определяемого контейнера и его основными режимами работы:
-a
,--attach
Подключает определяемый поток (
STDOUT
и т.п.) к вашему терминалу. Если не определен, подключаются иstdout
, иstderr
. В случае когда параметр не задан и контейнер запускается в интерактивном режиме (-i
), также подключаетсяstdin
.Несовместим с
-d
.-d
,--dettach
Выполняет контейнер в "отключённом режиме". Команда будет выполнять контейнер в фоновом режиме и вернёт идентификатор контейнера.
-i
,--interactive
Оставляет открытым
stdin
(даже когда он не подключен). Обычно используется совместно с-t
для запуска интерактивного сеанса контейнера. Например:$ docker run -it debian /bin/bash root@bd0f26f928bb:/# ls ...snip...
--restart
Определяет когда Docker попытается перезапустить исчезнувший контейнер. Параметр
no
никогда не будет пытаться повторно запускать какой бы то ни было контейнер, аalways
будет пытаться осуществлять повторный запуск вне зависимости от состояния выхода. Параметрon-failure
будет пытаться осуществлять повторный запуск контейнера, который вышел с ненулевым состоянием и может получать необязательный параметр, определяющий число попыток повторного запуска до прекращения (если не задан, будет пытаться без ограничений). Например,docker run --restart onfailure:10 postgres
будет запускать контейнерpostgres
и попытается повторно запустить его 10 раз, если он будет выходить с ненулевым кодом.--rm
Автоматически удаляет контейнер, если он существует. Не может применяться вместе с
-d
.-t
,--tty
Выделяет псевдо- TTY. Обычно применяется совместно с
-i
для запуска интерактивного контейнера
Следующие параметры выполняют установку имен и переменных контейнера:
-e
,--env
Устанавливает переменные внутри контейнера. Например:
$ docker run -e var1=val -e var2="val 2" debian env PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=b15f833d65d8 var1=val var2=val 2 HOME=/root
Также отметим параметр
--env-file
для передачи параметров через некий файл.-h
,--hostname
Устанавливает unix имя хоста контейнера в значение
NAME
. Например:$ docker run -h "myhost" debian hostname myhost
--name NAME
Назначает контейнеру имя
NAME
. Это имя затем может применяться для адресации контейнера в других командах Docker.
Следующие параметры позволяют пользователю настраивать тома. (за подробностями обращайтесь к "Управление данными томами и контейнерами данных"):
-v
,--volume
Существует две формы параметров для настройки тома (файла или каталога внутри контейнера, который является частью собственной файловой системы хоста, а не UFS контейнера). Первая форма только определяет каталог в пределах контейнера и будет закрепляться (bind) за каталогом хоста по выбору Docker. Вторая форма определяет каталог хоста для закрепления (bind).
--volumes-from
Монтирует том из определяемого контейнера. Часто применяется в ассоциации с контейнерами данных (см. "Контейнеры данных").
Существует также ряд параметров, влияющих на сетевую среду. Основные команды, которые вы можете предполагать для обычного применения:
--expose
Эквивалентна
EXPOSE
инструкции Dockerfile. Устанавливает порт или диапазон портов для применения в контейнере, однако не открывает порт. Имеет смысл только совместно с-P
и при связанных контейнерах.--link
Устанавливает частный сетевой интерфейс для определенного контейнера. Для дополнительной информации обращайтесь к "Связывание контейнеров".
-p
,--publish
"Публикует" порт контейнера, делая его доступным в хосте. Если порт хоста не определен, выбирается случайный порт с большим значением, который может быть обнаружен посредством команды
docker port
. Также может быть определен интерфейс хоста, на который проецируется данный порт.-P
,--publish-all
Публикует все выставленные (expose) в контейнере для хоста порты. Для каждого выставляемого порта будет выбираться случайный порт с большим числовым значением. Команда
docker port
может применяться для просмотра соответствий.
Существует ряд более углубленных параметров, которые вы можете найти полезными если вам нужно создавать более изощрённую сетевую среду. Имейте в виду, что ряд этих параметров потребует от вас наличия некоторого понимания сетевой среды и того, как она реализуется в Docker. За дополнительной информацией обращайтесь к Главе 11.
Команда docker run
также имеет большой набор параметров для управления правами и возможностями
контейнеров. За их подробностями обращайтесь к Главе 13.
Следующие параметры напрямую перезаписывают установки Dockerfile:
--entrypoint
Устанавливает точку входа для вашего контейнера на задаваемый параметр, перезаписывает любую инструкцию
ENTRYPOINT
в Dockerfile.-u
,--user
Устанавливает пользователя, от имени которого выполняется данная команда. Может определяться как именем пользователя, так и его UID. Перезаписывает инструкцию
USER
в Dockerfile.-w
,--workdir
Устанавливает рабочий каталог в контейнере в значение предоставляемого пути. Перекрывает любое значение из Dockerfile.
Помимо docker run
в процессе жизненного цикла контейнеров следующие команды
docker
применяются для управления ими:
docker attach [OPTIONS] CONTAINER
Команда
attach
позволяет пользователю наблюдать за главным процессом в вашем контейнере или взаимодействовать с ним. Например:$ ID=$(docker run -d debian sh -c "while true; do echo 'tick'; sleep 1; done;") $ docker attach $ID tick tick tick tick
Отметим, что применение
CTRL-C
для выхода завершит главный процесс и вызовет завершение работы контейнера.docker create
Создает контейнер из некого образа, но не запускает его. Получает большинство параметров аналогичных
docker run
. Чтобы запустить созданный контейнер воспользуйтесьdocker start
.docker cp
Копирует файлы и каталоги между контейнером и хостом.
docker exec
Выполняет команду внутри контейнера. Может быть использована для выполнения задач сопровождения или как замена
ssh
для регистрации в контейнере.Например:
$ ID=$(docker run -d debian sh -c "while true; do sleep 1; done;") $ docker exec $ID echo "Hello" Hello $ docker exec -it $ID /bin/bash root@5c6c32041d68:/# ls bin dev home lib64 mnt proc run selinux sys usr boot etc lib media opt root sbin srv tmp var root@5c6c32041d68:/# exit exit
docker kill
Отправляет сигнал главному процессу (PID 1) контейнера. По умолчанию отправляет
SIGKILL
, который вызывает немедленный выход из контейнера. В качестве альтернативы может быть определен другой сигнал при помощи параметра-s
. Возвращается идентификатор контейнера.Например:
$ ID=$(docker run -d debian bash -c \ "trap 'echo caught' SIGTRAP; while true; do sleep 1; done;") $ docker kill -s SIGTRAP $ID e33da73c275b56e734a4bbbefc0b41f6ba84967d09ba08314edd860ebd2da86c $ docker logs $ID caught $ docker kill $ID e33da73c275b56e734a4bbbefc0b41f6ba84967d09ba08314edd860ebd2da86c
docker pause
Приостанавливает все процессы в данном контейнере. Процессы не получают никакие сигналы, поскольку они были приостановлены и, следовательно, не могут быть выключены или вычищены. Процесс может быть запущен повторно при помощи
docker unpause
.docker pause
использует внутреннюю функциональностьcgroup freezer
Linux. Данная команда противопоставляетсяdocker stop
, которая останавливает процесс и посылает сигналы, наблюдаемые процессами.docker restart
Повторно запускает один или более контейнеров. Примерно эквивалентна вызову
docker stop
с последующимdocker start
в контейнерах. Принимает необязательный параметр-t
, который определяет промежуток времени для ожидания перед закрытием контейнера перед его уничтожением отправкой сигналаSIGTERM
.docker rm
Удаляет один или более контейнеров. Возвращает имена или идентификаторы успешно удаленных контейнеров. По умолчанию
docker rm
не удаляет никакие тома. Параметр-f
может применяться для удаления выполняемого контейнера, а параметр-v
удалит созданные контейнером тома (только если они не были закреплённо смонтированы или не используются другим контейнером).Например, чтобы удалить все остановленные контейнеры:
$ docker rm $(docker ps -aq) b7a4e94253b3 e33da73c275b f47074b60757
docker start
Запускает остановленный контейнер (или контейнеры). Может использоваться для повторного как запуска для контейнера, который завершил свою работу, так и для контейнера, который был создан при помощи
docker create
, но ещё никогда не запускался.docker stop
Останавливает (но не удаляет) один или более контейнеров. После вызова в контейнере
docker stop
, он перейдёт в состояние "выходящего". Принимает необязательный параметр-t
, который определяет промежуток времени для ожидания перед закрытием контейнера перед его уничтожением отправкой сигналаSIGTERM
.docker unpause
Повторно запускает контейнер, приостановленный перед этим при помощи
docker pause
.
Следующие подкоманды могут быть использованы для получения дополнительной информации по установке и применению Docker:
docker info
Выводит различную информацию о системе Docker и хосте.
docker help
Выводит информацию о применении и справочные сведения по определенной подкоманде. Идентична выполнению команды с флагом
--help
.docker info
Выдаёт информацию о версии Docker для клиента и сервера а также версию использовавшегося для компиляции Go.
Следующие команды предоставляют дополнительную информацию по запущенным и остановленным контейнерам.
docker diff
Отображает изменения, внесенные в файловую систему контейнеров по сравнению с образом, из которого он был запущен. Например:
$ ID=$(docker run -d debian touch /NEW-FILE) $ docker diff $ID A /NEW-FILE
docker events
Выводит события демона в реальном масштабе времени. Для выход используется
CTRL-C
. Для дополнительных сведений по этой теме обращайтесь к Главе 10.docker inspect
Предоставляет детализированную информацию по определенным контейнерам или образам. Информация содержит большую часть информации о настройках и охватывает сетевые установки, а также соответствия томов. Команда может принимать один параметр,
-f
, который применяется для поддержки шаблона Go, который может быть использован для форматирования и фильтрации вывода.docker logs
Выводит "журналы" контейнера. Это просто все, что было записано в
STDERR
иSTDOUT
внутри контейнера. За дополнительной информацией о регистрации обращайтесь к Главе 10.docker port
Выводит список соответствий раскрытых портов для данного контейнера. Опционально может определяться для поиска внутренним портом контейнера и протоколом. Часто применяется после
docker run -P <image>
для обнаружения назначенных портов.Например:
$ ID=$(docker run -P -d redis) $ docker port $ID 6379/tcp -> 0.0.0.0:32768 $ docker port $ID 6379 0.0.0.0:32768 $ docker port $ID 6379/tcp 0.0.0.0:32768
docker ps
Предоставляет информацию верхнего уровня по текущим контейнерам, например, имя, идентификатор и состояние. Принимает большое число дополнительных параметров, особенно отметим
-a
для получения всех контейнеров, а не только запущенных. Также отметим параметр-q
, который возвращает только идентификаторы контейнеров, что очень полезно в качестве входной информации для других команд, подобныхdocker rm
.docker top
Предоставляет информацию по выполняемым процессам в пределах заданного контейнера. На самом деле, данная команда выполняет на данном хосте утилиту Unix
ps
и фильтрует процессы для данного контейнера. Эта команда может быть определена с теми же параметрами, что и утилитаps
, а по умолчанию установлены-ef
(однако проверяйте, что поле идентификатора процесса, PID, все ещё сохраняется в выводе).Например:
$ ID=$(docker run -d redis) $ docker top $ID UID PID PPID C STIME TTY TIME CMD 999 9243 1836 0 15:44 ? 00:00:00 redis-server *:6379 $ ps -f -u 999 UID PID PPID C STIME TTY TIME CMD 999 9243 1836 0 15:44 ? 00:00:00 redis-server *:6379 $ docker top $ID -axZ LABEL PID TTY STAT TIME COMMAND docker-default 9243 ? Ssl 0:00 redis-server *:6379
Следующие команды предоставляют инструментарий для создания образов и работы с ними:
docker build
Строит образ из Dockerfile. За подробностями обращайтесь к разделам "Построение образов из Dockerfile" и "Как выполняется построение образов".
docker commit
Создаёт образ из заданного контейнера. Хотя
docker commit
может быть полезной, обычно предпочтительнее создавать образы с применениемdocker build
, которая легче повторяется. По умолчанию контейнеры приостанавливаются передcommit
, однако это может быть выключено при помощи параметра--pause=false
. Принимает параметры-a
и-m
для установки метаданных.Например:
$ ID=$(docker run -d redis touch /new-file) $ docker commit -a "Joe Bloggs" -m "Comment" $ID commit:test ac479108b0fa9a02a7fb290a22dacd5e20c867ec512d6813ed42e3517711a0cf $ docker images commit REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE commit test ac479108b0fa About a minute ago 111 MB $ docker run commit:test ls /new-file /new-file
docker export
Экспортирует содержимое файловой системы контейнера в виде архива tar в
STDOUT
. Получающийся в результате архив может загружаться при помощиdocker import
. Отметим, что экспортируется только файловая система; все метаданные, такие как раскрытые порты, установкиCMD
иENTRYPOINT
будут утрачены. Также отметим, что никакие тома не включаются в этот экспорт. Противопоставляетсяdocker save
.docker history
Выводит информацию по каждому уровню в образе.
docker images
Предоставляет список локальных образов, включая информацию подобную имени репозитория, имени тэга и размеру. По умолчанию промежуточные образы (используемые при создании образов верхнего уровня) не отображаются.
VIRTUAL SIZE
является общим размером образа, включающим все лежащие в его основе уровни. Поскольку эти уровни могут использоваться совместно с другими образами, простое сложение всех этих размеров не обеспечивает точную оценку использования диска. Кроме того, образы могут появляться много раз если они имеют более одного тэга; различные образы могут распознаваться по сравнению их идентификаторов. Принимает различные параметры; в частности, отметим-q
, возвращающий только идентификаторы образов, что очень полезно в качестве входной информации для прочих команд, например,docker rmi
.Например:
$ docker images | head -4 REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE identidock_identidock latest 9fc66b46a2e6 26 hours ago 839.8 MB redis latest 868be653dea3 6 days ago 110.8 MB containersol/pres-base latest 13919d434c95 2 weeks ago 401.8 MB
Чтобы удалить все подвисшие образы:
$ docker rmi $(docker images -q -f dangling=true) Deleted: a9979d5ace9af55a562b8436ba66a1538357bc2e0e43765b406f2cf0388fe062
docker import
Создает образ из файла архива, содержащего файловую систему, например, из созданного
docker export
. Архив может задаваться путем к файлу, или URL, или получаться из потока черезSTDIN
(при использовании флага-
). Возвращает идентификатор вновь созданного образа. Образ может быть помечен поддержкой репозитория и именем тэга. Отметим, что образ построенный изimport
будет состоять только из одного уровня и потеряет все установки настрое Docker такие как раскрытые порты и значенияCMD
. Противопоставляетсяdocker load
Пример "выровненного" посредством экспорта и импорта образа:
$ docker export 35d171091d78 | docker import - flatten:test 5a9bc529af25e2cf6411c6d87442e0805c066b96e561fbd1935122f988086009 $ docker history flatten:test IMAGE CREATED CREATED BY SIZE COMMENT 981804b0c2b2 59 seconds ago 317.7 MB Imported from -
docker load
Загружает репозиторий из архива tar, передаваемого через
STDIN
. Этот репозиторий может содержать различные образы и тэги. В отличие отdocker import
, данные образы будут содержать историю и метаданные. Продходящие файлы архива создаются командойdocker save
, делаяsave
иload
жизнеспособной альтернативой реестру для распространения образов и поддеживая резервные копирования. В качестве примера посмотритеdocker save
.docker rmi
Удаляет заданный образ или образы. Образы определяются идентификатором или именами репозитория или тэга. Если предоставляется имя репозитория без имени тэга, значение тэга предполагается установленным в
latest
. Чтобы удалить образы, которые существуют во множестве репозиториев, определите такой образ идентификатором и примените параметр-f
. Вам придется выполнить это по разу для каждого репозитория.docker save
Сохраняет поименованные образы или репозитории в архив tar, который передаётся в поток
STDOT
(для записи в файл используйте-o
). Образы могут определяться идентификатором или в видеrepository:tag
. Если задано только имя репозитория, в таком репозитории будут сохранены все образы, а не только помеченные тэгомlatest
. Может быть использован совместно сdocker load
для распространения образов или их резервного копирования.Например:
$ docker save -o /tmp/redis.tar redis:latest $ docker rmi redis:latest Untagged: redis:latest Deleted: 868be653dea3ff6082b043c0f34b95bb180cc82ab14a18d9d6b8e27b7929762c ... $ docker load -i /tmp/redis.tar $ docker images redis REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE redis latest 0f3059144681 3 months ago 111 MB
docker tag
Связывает имя репозитория и тэга с образом. Образ может определяться идентификатором или репозиторием и тэгом (если никакой не определен, предполагается тэг
latest
). Если никакой тэг не задан для нового имени, предполагаетсяlatest
.Например:
$ docker tag faa2b75ce09a newname1 $ docker tag newname:latest amouat/newname2 $ docker tag newname:latest amouat/newname:newtag3 $ docker tag newname:latest myregistry.com:5000/newname:newtag4
- 1
Добавляет образ с идентификатором
faa2b75ce09a
в репозиторийnewname
, используя тэгlatest
, поскольку никакой другой не определён.- 2
Добавляет образ
newname:latest
в репозиторийamouat/newname
, опять применяется тэгlatest
. Эта метка присутствует в формате удобном для размещения в Docker Hub в предположении, что пользователем являетсяamouat
.- 3
Аналогично предыдущему, за исключением замены тэга
latest
наnewtag
.- 4
Добавляет новый образ
newname:latest
в репозиторийamouat/newname
с тэгомnewtag
. Эта метка представляется в формате, удобном для размещения по адресу http://myregistry.com:5000.(((range="endofrange",startref="ix_04_docker_fundamentals-asciidoc23")))(((range="endofrange",startref="ix_04_docker_fundamentals-asciidoc22"))).
Следующие команды относятся к использованию реестра, включая Docking Hub. Убедитесь что Docker сохраняет мандаты в файл .dockercfg в вашем домашнем каталоге:
docker login
Регистрируется или входит на заданный сервер реестра. Если не определён никакой сервер, предполагается, что им будет Docker Hub. По мере необходимости процесс будет запрашивать подробности, либо они могут быть определены в качестве параметров.
docker logout
Выходит из реестра Docker. Если не определен никакой сервер, предполагается что это Docker Hub.
docker pull
Загружает заданные образы из реестра. Реестр определяется по имени образа и по умолчанию предполагается Docker Hub. Если не указано имя тэга, будет загружаться образ помеченный тэгом
latest
(если доступен). Для загрузки всех образов из репозитория применяйте параметр-a
.docker push
Выгружает образ или репозиторий в реестр. Если не задан никакой тэг, данная команда выгрузит в определённый реестр все образы вашего репозитория, а не только те, которые помечены как
latest
.docker search
Выводит список общедоступных репозиториев в Docker Hub соответствующих терминам поиска. Ограничивает выдачу до 25 репозиториев. Вы также можете фильтровать с помощью звёздочек и автоматизировать построения. Обычно легче применять веб- сайты.
В данной главе мы предоставили много информации! Даже если вы только пробежались по основным моментам, вы должны получить достаточно широкое понимание того как работает Docker и его основных команд. В Части 2 мы увидим как применять эти знания в проектах программных продуктов, причем начиная с их разработки до производства. Вы можете найти материалы данной главы более понятными после их рассмотрения на практике.