Создание образов контейнеров
Образы контейнеров в Fedora собираются с использованием Dockerfile примерно так же, как RPM собирается с использованием spec-файла. В этом разделе приведены рекомендации Fedora по созданию образов контейнеров с использованием Dockerfile.
Пример Dockerfile
FROM registry.fedoraproject.org/fedora:rawhide
ARG NAME=mycontainer
ARG VERSION=0
ARG ARCH=x86_64
LABEL com.redhat.component="$NAME" \
name="$FGC/$NAME" \
version="$VERSION" \
architecture="$ARCH" \
run="podman run -p 1337:1337 IMAGE" \
summary="mycontainer exposes something on port 1337." \
maintainer="Christian Glombek <lorbus@fedoraproject.org>"
EXPOSE 1337
RUN dnf -y --setopt=tsflags=nodocs install mypackage && \
dnf clean all
COPY root/help.1 /
COPY script.sh /usr/bin/
CMD ["/usr/bin/script.sh"]
FROM
Согласно справочнику по Dockerfile, инструкция FROM '''должна''' быть первой строкой Dockerfile. Инструкция FROM '''должна''' быть полностью определена с указанием имени реестра Fedora, имени образа и тега, как показано в этом примере:
Это гарантирует, откуда берётся базовый образ при сборке сервисом сборки или при пересборке пользователем.
Для большинства многослойных образов, собираемых https://docs.pagure.org/releng/layered_image_build_service.html[сервисом сборки слоёных образов Docker Fedora], строка FROM будет использовать один из базовых образов Fedora, существующих в https://registry.fedoraproject.org/[реестре контейнеров Fedora]:
``` FROM registry.fedoraproject.org/fedora:latest ```
Также можно использовать другой слоёный образ в качестве базового слоя, как в этом примере:
``` FROM registry.fedoraproject.org/f25/kubernetes-master:latest ```
=== Метки
Dockerfile имеют концепцию https://docs.docker.com/engine/reference/builder/#label[LABEL], которая может добавлять произвольные метаданные к образу в виде пары ключ-значение. Рекомендации Fedora по теме LABEL следуют стандартам http://www.projectatomic.io/[Project Atomic] https://github.com/projectatomic/ContainerApplicationGenericLabels[Container Application Generic Labels] для определения LABEL.
'''Обязательные''' LABEL для слоёного образа Fedora следующие:
[cols="2*", options"header"]
|===
|Имя
|Описание
|com.redhat.component
|Имя компонента в Bugzilla, куда пользователи должны сообщать об ошибках в этом контейнере.
|name
|Имя образа
|version
|Версия образа
|architecture
|Архитектура, для которой предназначено программное обеспечение в образе (Необязательно: если опущено, будет собрано для всех поддерживаемых архитектур Fedora)
|maintainer
|Имя и адрес электронной почты сопровождающего (обычно отправителя)
|run или usage
|Либо предоставляет строку запуска Atomic, либо понятный человеку пример выполнения контейнера
|summary
|Краткое описание образа.
|===
'''Необязательные''' метки для слоёных образов Fedora
[cols="2*", options"header"]
|===
|Имя
|Описание
|install
|Обеспечивает работу команды "atomic install". Не используется для системных контейнеров.
|uninstall
|Обеспечивает работу команды "atomic uninstall". Обязателен, если присутствует Install.
|url
|URL-адрес, где пользователь может найти дополнительную информацию об образе.
|help
|Выполняемая команда, которая приводит к отображению справочной информации.
|atomic.type
|Используется для системных контейнеров, см. ниже.
|Общие
|Любые из https://github.com/projectatomic/ContainerApplicationGenericLabels[Container Application Generic Labels], которые подходят для контейнера, например "stop", "debug" или "changelog-url"
|===
См. СПЕЦИФИКАЦИЮ LABEL ниже для получения более подробной информации о том, что требуется для каждой из этих меток.
{{admon/note|Рекомендации по меткам Dockerfile вышестоящего проекта| Используемые здесь LABEL являются адаптацией Fedora усилий вышестоящего проекта https://projectatomic.io[Project Atomic] по определению https://github.com/projectatomic/ContainerApplicationGenericLabels[Container Application Generic Labels], а также http://docs.projectatomic.io/container-best-practices/[Container Best Practices]. }}
В прошлом эти LABEL должны были определяться в одной строке Dockerfile, чтобы не приводить к появлению дополнительных слоёв при сборке. Последние версии OSBS сжимают все слои, собранные поверх родительского образа, в один слой, что означает отсутствие необходимости размещать все LABEL или команды RUN в одной строке.
Ниже приведён очень простой пример Dockerfile, содержащий обязательные LABEL:
[source]
----
FROM registry.fedoraproject.org/fedora:rawhide
ARG NAME=mycontainer
ARG VERSION=0
ARG ARCH=x86_64
LABEL com.redhat.component="$NAME" \
name="$FGC/$NAME" \
version="$VERSION" \
architecture="$ARCH" \
run="podman run -p 1337:1337 IMAGE" \
summary="mycontainer exposes something on port 1337." \
maintainer="Christian Glombek <lorbus@fedoraproject.org>"
EXPOSE 1337
RUN dnf -y --setopt=tsflags=nodocs install mypackage && \
dnf clean all
COPY root/help.1 /
COPY script.sh /usr/bin/
CMD ["/usr/bin/script.sh"]
----
=== СПЕЦИФИКАЦИЯ LABEL
Некоторые дополнительные сведения о том, как заполнять каждую метку.
'''com.redhat.component''': Существующий компонент Bugzilla, в который следует сообщать об ошибках в этом образе.
'''name''': Имя образа. Если образ заменяет стандартный RPM, он должен иметь точно такое же имя, как и этот RPM. В противном случае см. рекомендации по именованию выше.
'''version''': Обычно 0. Заполняется из переменной ARG. См. "ВЕРСИОНИРОВАНИЕ" ниже для объяснения.
'''architecture''': обычно "x86_64", если только образ контейнера не поддерживает другие/все архитектуры.
'''usage''': понятная человеку примерная командная строка для запуска контейнера. Обязателен, если отсутствует run. Должен включать все возможные параметры, такие как порты, тома и любые обязательные параметры командной строки. Вы можете использовать любую среду выполнения контейнеров в качестве примера. Пример из контейнера OwnCloud:
usage="docker run -d -P -v owncloud-data:/var/lib/owncloud -v owncloud-config:/etc/owncloud owncloud"
'''summary''': Краткое описание образа, предназначенное для поиска, когда у нас будет реестр с функцией поиска. Пожалуйста, включайте соответствующие ключевые слова.
'''run''': командная строка для запуска контейнера, подходящая для использования https://github.com/projectatomic/atomic[Atomic CLI], включая заполнители и встроенный код atomic-run. Должна успешно выполняться на подходящей системе Fedora Atomic. Обязателен, если отсутствует "usage". Пример для контейнера Cockpit:
run="/usr/bin/docker run -d --privileged --pid=host -v /:/host IMAGE /container/atomic-run --local-ssh"
'''install''': Контейнер может потребовать подготовки хост-системы перед запуском контейнера. В этом случае метка install полезна для определения того, какие операции должны быть выполнены на хосте для его подготовки. Набор операций должен быть максимально минимальным и не должен включать никаких операций, которые не полезны для подготовки хоста к запуску контейнера. Если предоставлена метка install, она должна быть протестирована и работать с https://github.com/projectatomic/atomic[Atomic CLI]. При необходимости также должна быть предоставлена метка uninstall, которая позволит очистить любые операции, выполненные install. Пожалуйста, обратитесь к https://github.com/projectatomic/atomic#atomic-install[документации вышестоящего проекта] для получения дополнительной информации. Пример для контейнера Cockpit:
install="/usr/bin/docker run --rm --privileged -v /:/host IMAGE /container/atomic-install"
'''uninstall''': Если контейнер имеет метку install, то, скорее всего, потребуется метка uninstall для удаления любых файлов и/или очистки любой конфигурации, которая была выполнена на хост-системе. Не требуется удалять файлы, которые могут содержать пользовательские данные. В необычных случаях может не быть файлов или конфигурации для очистки от метки install, поэтому метка uninstall может не потребоваться. Если предоставлена метка uninstall, она должна быть протестирована и работать с https://github.com/projectatomic/atomic[Atomic CLI]. Пожалуйста, обратитесь к https://github.com/projectatomic/atomic#atomic-uninstall[документации вышестоящего проекта] для получения дополнительной информации.
uninstall="/usr/bin/docker run --rm --privileged -v /:/host IMAGE /container/atomic-uninstall"
'''url''': URL-адрес, где пользователи могут получить дополнительную информацию об образе, например, репозиторий на github или pagure, или документацию по программному обеспечению.
'''help''': Выполняемая команда, которая выводит man-страницу или другую справочную информацию. Если предоставлена, должна быть протестирована с помощью `atomic help`. Если у вас есть команда help, вам не нужно также предоставлять справочный файл (см. ниже).
=== Версионирование
В предыдущем разделе рассматривались LABEL, одной из которых является версия, устанавливаемая в примере с помощью переменной `ENV` `VERSION`, которая на данный момент должна быть `0`. OSBS автоматически обрабатывает увеличение номера выпуска для данной версии образа контейнера.
На данный момент нет способа автоматически заполнять значение `Version`/`VERSION` значением последней версии основного RPM, принадлежащего образу контейнера. Это то, что в настоящее время https://pagure.io/atomic-wg/issue/249[находится в планах].
Зачем это нужно?
Если мы установим метку `Version` в версию соответствующего RPM на момент проверки образа контейнера, то сопровождающему придётся постоянно обновлять её вручную при каждом обновлении RPM, что неудобно и чревато ошибками. Кроме того, существует вероятность того, что версия RPM может быть обновлена при автоматической пересборке слоёного образа, и сопровождающий не сможет своевременно обновить `Dockerfile` (автоматические пересборки выполняются https://docs.pagure.org/releng/[Release Engineering] для включения обновлений безопасности для всех слоёных образов). Если это произойдёт, то версия образа контейнера не будет соответствовать версии программного обеспечения, которое он должен предоставлять, что приведёт к путанице и, возможно, к неожиданным негативным побочным эффектам для пользователей. Поэтому в настоящее время мы считаем, что номер версии контейнера не имеет значения, но это будет исправлено как можно скорее.
=== CMD / ENTRYPOINT
Ещё одним обязательным элементом является запись CMD или ENTRYPOINT, чтобы при выполнении пользователем следующей команды (например) происходило ожидаемое поведение:
``` docker run registry.fedoraproject.org/f25/myawesomecontainer ```
Для получения дополнительной информации об этих записях, пожалуйста, обратитесь к вышестоящей https://docs.docker.com/engine/reference/builder/[документации по Dockerfile].
=== Тома
Использование томов контейнеров для постоянных данных разрешается и поощряется, но необходимо следовать следующим рекомендациям:
* Любые пользовательские данные, которые могут быть потеряны при обновлении, '''должны''' находиться в томе.
* Любые данные конфигурации приложения, требующие постоянства, '''должны''' находиться в томе. Также разрешена конфигурация с помощью переменных среды, как вместе с томами конфигурации, так и вместо них.
* Все тома, перечисленные в Dockerfile, '''должны''' быть перечислены в справочном файле.
* Пример команды run '''должен''' иметь том с постоянным именем (например, "docker run -d -v owncloud-data:/var/lib/owncloud -v owncloud-config:/etc/owncloud owncloud")
* Тома '''должны''' быть определены как можно более узко. В частности, если образ не предназначен для использования в качестве системного контейнера для системного администрирования, тома должны быть определены таким образом, чтобы монтировать системные каталоги, которые являются исключительными для контейнера. Например, контейнер должен монтировать /etc/application-name/ для файлов конфигурации, а ''не'' /etc/.
Каждый том в справочном файле '''должен''' иметь следующее:
* Полный путь к тому
* Почему он помечен как том (например, почему этой конфигурации требуется постоянство или указание на то, что там находятся пользовательские данные)
Тома, перечисленные в справочном файле, '''должны''' также включать информацию о требованиях к пространству, разрешениям и производительности.
Файл readme '''может''' содержать предлагаемые дополнительные тома, которые не являются обязательными по Dockerfile, например, места для сгенерированных, а не самоподписанных SSL-сертификатов.
Want to help? Learn how to contribute to Fedora Docs ›