Сборка контейнера с помощью Containerfile

Создание Containerfile

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

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

$ mkdir container-demo && cd container-demo

Существует множество примеров сборки контейнеров с помощью Containerfile. Простой Containerfile будет содержать некоторые из следующих элементов:

  • Строка FROM указывает базовый, или начальный, контейнер, например, последний образ Fedora. Этот образ будет загружен, если он ещё не доступен локально. Указывайте детали того, какой образ использовать, так же, как и в команде podman pull.

  • Создаёт слои с каждой командой RUN. Старайтесь минимизировать количество слоёв, размещая несколько команд в одной строке с использованием && между командами. Также включайте любые команды очистки, такие как dnf clean all, чтобы уменьшить итоговый размер образа.

  • Копирует содержимое из рабочего каталога в контейнер.

  • Указывает порты для прослушивания с помощью EXPOSE

  • Запускает ваше приложение

    • CMD может быть перезаписана командой podman run

    • ENTRYPOINT часто является базовой командой и опциями по умолчанию. Может быть объединён с CMD для дополнительных опций.

Пример: веб-приложение

Создайте рабочий каталог с некоторым содержимым для веб-сервера:

$ mkdir demo-httpd && cd demo-httpd && echo 'sample container' > index.html

Начните Containerfile с команды FROM, чтобы указать базовый образ:

$ echo 'FROM fedora:latest' >> Containerfile

Добавьте команду RUN для обновления образа и добавления любых приложений и утилит:

$ echo 'RUN dnf -y update && dnf -y install httpd git  && dnf clean all' >> Containerfile

Приведённый выше пример устанавливает git. Если ваш веб-контент размещён в системе контроля версий, вы можете добавить оператор RUN для клонирования этих данных в контейнер. Если ваш контент доступен в рабочем каталоге сборки, вы можете использовать команду COPY, чтобы добавить его в контейнер.

Скопируйте образец файла index.html в контейнер:

$ echo 'COPY index.html /var/www/html/index.html' >> Containerfile

Строка EXPOSE указывает, что контейнер прослушивает указанные сетевые порты. Она используется опцией --publish-all в команде podman run.

Задокументируйте, какие порты доступны для публикации:

$ echo 'EXPOSE 80' >> Containerfile

Укажите команду для запуска при старте контейнера:

$ echo 'ENTRYPOINT /usr/sbin/httpd -DFOREGROUND' >> Containerfile
Привязка портов пока не поддерживается контейнерами без прав root. Если ваш контейнер должен быть доступен в сети, собирайте его в пространстве имён root. Привязка портов для контейнеров без прав root доступна в тестировании upstream для podman 1.1.0 с slirp4netns v0.3.0.

Соберите образ с описательным тегом:

$ sudo podman build --tag fedora:myhttpd -f ./Containerfile

Образ появится в локальном реестре:

$ sudo podman images
REPOSITORY                 TAG       IMAGE ID       CREATED         SIZE
localhost/fedora           myhttpd   223534b48a9c   3 minutes ago   474MB
docker.io/library/fedora   latest    8b38e3af7237   4 weeks ago     315MB

Чтобы сделать порт приложения доступным для хост-устройства, используйте опцию --publish или -p с номерами hostPort:containerPort. Также можно указать IP-адрес, а также диапазоны портов. Дополнительные опции см. на странице man.

Запустите контейнер и опубликуйте порт:

$ sudo podman run -p 8080:80 --name myhttpd --rm fedora:myhttpd

Просмотрите информацию о портах:

$ sudo podman port myhttpd
80/tcp -> 0.0.0.0:8080

Получите доступ к веб-странице с хост-устройства:

$ curl localhost:8080

Получите доступ к веб-странице из удалённого местоположения, используя IP-адрес хост-устройства и номер опубликованного порта.

Откройте порты, службы или источники брандмауэра по мере необходимости. Образ Fedora IoT по умолчанию разрешает любой источник в той же сети через опцию interfaces:

$ sudo firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: eth0
  sources:
  services: dhcpv6-client mdns ssh
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

Добавьте порт с помощью:

$ sudo firewall-cmd --add-port 8080/tcp

Дополнительную информацию о команде firewall-cmd можно найти на firewalld.org.

Пример: взаимодействие с интерфейсом GPIO

Чтобы взаимодействовать с интерфейсом GPIO, добавьте пакет libgpiod-utils поверх существующего образа или используйте его с контейнером.

Чтобы добавить пакет поверх:

$ sudo rpm-ostree install libgpiod-utils python3-libgpiod
$ sudo gpiodetect

Чтобы создать контейнер для приложения, работающего с интерфейсом GPIO в пространстве имён root.

Начните Containerfile с команды FROM, чтобы указать базовый образ:

$ echo 'FROM fedora:latest' >> Containerfile

Добавьте команду RUN для обновления образа и добавления любых приложений и утилит:

$ echo 'RUN dnf -y update && dnf -y install git libgpiod-utils python3-libgpiod && dnf clean all' >> Containerfile

Образ fedora:latest включает bash, поэтому мы можем сразу собрать контейнер без каких-либо конкретных приложений для запуска или портов для открытия. Команду можно указать при запуске контейнера.

Соберите образ с описательным тегом:

$ sudo podman build --tag fedora:gpio -f ./Containerfile

Образ появится в реестре localhost для пространства имён root:

$ sudo podman images
REPOSITORY                 TAG      IMAGE ID       CREATED         SIZE
localhost/fedora           gpio     655abf78e6b9   4 minutes ago   542MB
docker.io/library/fedora   latest   8b38e3af7237   4 weeks ago     315MB

Чтобы получить доступ к GPIO-устройству хоста из контейнера, используйте опцию --device при запуске контейнера:

$ sudo podman run -it --name demo-gpio --device=/dev/gpiochip0 localhost/fedora:gpio /bin/bash

Убедитесь, что вы видите GPIO-устройство:

[root@167f31750fdb /]# gpiodetect
gpiochip0 [pinctrl-bcm2835] (54 lines)

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

Примеры использования gpioset можно найти в статье Fedora Magazine 2018 года: How to turn on an LED with Fedora IoT

Автоматизируйте дополнительные шаги, изменив Containerfile и собрав новый контейнер.

Образы не обязательно должны быть собраны из контейнера Fedora. Этот Containerfile использует образ raspbian и клонирует проект lightshowpi:

$ cat Containerfile
FROM raspbian/stretch:latest
RUN apt-get -y update && apt-get -y install git-core && apt-get -y clean
WORKDIR /
RUN git clone https://togiles@bitbucket.org/togiles/lightshowpi.git && \
  cd lightshowpi && git fetch && git checkout stable

Документация Docker включает лучшие практики Containerfile.

Повторное использование и совместное использование контейнеров

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

Большинство реестров требуют соглашения об именовании «useraccount/description:tag», а значением по умолчанию для большинства команд pull является поиск контейнера с тегом «latest». Образ может иметь несколько тегов, и эти теги используются для помощи в идентификации совместимости архитектуры и контроля версий.

Чтобы переименовать или добавить тег к локальному образу:

$ podman tag fedora:myhttpd testuser/fedora-myhttpd:latest
$ podman tag fedora:myhttpd quay.io/testuser/fedora-myhttpd:latest

Оба имени появятся в списке образов, но идентификатор образа будет одинаковым для каждого:

$ podman images
REPOSITORY                               TAG       IMAGE ID       CREATED        SIZE
localhost/fedora                         myhttpd   d52cbe4136e8   24 hours ago   428 MB
localhost/testuser/fedora-myhttpd        latest    d52cbe4136e8   24 hours ago   428 MB
quay.io/testuser/fedora-myhttpd          latest    d52cbe4136e8   24 hours ago   428 MB
docker.io/library/fedora                 latest    26ffec5b4a8a   4 weeks ago    283 MB

Затем вы можете отправить образ в реестр с помощью podman push imageID destination.

Чтобы извлечь образ в локальный каталог в формате docker:

$ podman push quay.io/testuser/fedora-myhttpd dir:/tmp/fedora-myhttpd

Дополнительные опции экспорта см. на странице man podman-push.