Контейнеризация#
Контейнеры Linux стали ключевой технологией упаковки и доставки приложений с открытым исходным кодом, сочетающей облегченную изоляцию приложений с гибкостью методов развертывания на основе образов. SberLinux реализует контейнеры Linux с использованием основных технологий, таких как:
Группы управления (cgroups) для управления ресурсами.
Пространства имен для изоляции процессов.
SELinux для обеспечения безопасности.
Безопасное многопользовательское использование.
Эти технологии снижают вероятность взломов систем безопасности и предоставляют вам среду для создания и запуска контейнеров корпоративного качества.
SberLinux позволяет создавать отдельные контейнеры и образы контейнеров и управлять ими вне систем контейнеризации. В этом руководстве описываются инструменты, предоставляемые для выполнения тех задач, которые выполняются непосредственно в системах SLO.
Здесь описаны инструменты командной строки, которые могут работать без механизма создания контейнеров. К ним относятся:
podman - для непосредственного управления модулями и образами контейнеров (run, stopstart, ps attach, exec и так далее);
buildah - для создания, отправки и подписи образов контейнеров;
skopeo - для копирования, проверки, удаления и подписания образов;
runc - для предоставления возможностей запуска и сборки контейнеров podman и buildah;
crun - дополнительная среда выполнения, которую можно настроить и которая обеспечивает большую гибкость, контроль и безопасность для контейнеров без root.
Поскольку эти инструменты совместимы с Open Container Initiative (OCI), их можно использовать для управления теми же контейнерами Linux, которые создаются и управляются совместимыми с OCI контейнерными движками.
Можно использовать системную роль podman для управления конфигурацией Podman, контейнерами и службами systemd, которые запускают контейнеры Podman. Также Podman поддерживает события для аудита. Начиная с Podman версии 4.4, можно собирать всю необходимую информацию о контейнере из одного события записи journald. Чтобы включить аудит Podman, измените файл container.conf конфигурации и добавьте events_container_create_inspect_data=true опцию в [engine] раздел. Данные представлены в формате JSON, таком же, как из podman container inspect команды.
Также пользователю доступны обновленные пакеты Container Tools, которые содержат инструменты Podman, Buildah, Skopeo, crun и runc.
Характеристики Podman, Buildah и Skopeo#
Основные преимущества инструментов Podman, Skopeo и Buildah включают:
Запуск в режиме без root - контейнеры без root намного безопаснее, поскольку они запускаются без каких-либо дополнительных привилегий.
Демон не требуется - эти инструменты требуют гораздо меньших ресурсов в режиме ожидания, потому что, если вы не запускаете контейнеры, Podman не запускается. В Docker, наоборот, всегда работает демон.
Встроенная systemd интеграция - Podman позволяет создавать systemd модульные файлы и запускать контейнеры в качестве системных служб.
Обзор команд Podman#
В таблице ниже показан список основных команд, которые можно использовать с podman командой. Используйте podman -h, чтобы просмотреть список всех команд Podman.
Команда podman |
Описание |
|---|---|
|
Прикрепление к работающему контейнеру |
|
Создание образа, используя инструкции Containerfile |
|
Проверка изменений в файловых системах контейнера |
|
Экспорт содержимого файловой системы контейнера в виде архива tar |
|
Показ истории указанного образа |
|
Импорт архива для создания образа файловой системы |
|
Отображение конфигурации контейнера или образа |
|
Загрузка образа из архива |
|
Выход из реестра контейнеров |
|
Монтирование корневой файловой системы рабочего контейнера |
|
Создание списка контейнеров |
|
Извлечение образа из реестра |
|
Перезапуск одного или нескольких контейнеров |
|
Остановка одного или несколько контейнеров |
|
Отображение запущенных процессов контейнера |
|
Отключение процессов в одном или нескольких контейнерах |
|
Блокировка одного или нескольких контейнеров |
Получение инструментов для создания контейнеров#
В этом разделе показано, как можно установить container-tools модуль, содержащий Podman, Buildah, Skopeo, CRIU, Udica и все необходимые библиотеки.
Процедура:
Установите SLO.
Зарегистрируйтесь в SLO: введите свое имя пользователя и пароль.
Установите container-tools модуль:
yum module install -y container-toolsОпционально. Установите podman-docker пакет:
yum install podman-docker
Пакет podman-docker заменяет интерфейс командной строки Docker и docker-api соответствующие команды Podman.
Общие характеристики образов контейнеров SLO#
Следующие характеристики применимы как к базовым образам SLO, так и к образам UBI.
Образы контейнеров SLO представляют собой:
Поддерживается: поддерживается для использования с контейнерными приложениями. Они содержат те же защищенные, протестированные и сертифицированные пакеты программного обеспечения, что и SLO.
Каталогизируется: перечисляются в каталоге контейнеров с описаниями, техническими деталями и индексом работоспособности для каждого образа.
Обновляется: предлагается с четко определенным графиком обновления, для получения последнего программного обеспечения.
Отслеживается: отслеживается с помощью исправлений продукта, помогающих понять изменения, вносимые в каждое обновление.
Многократно используется: образы контейнеров необходимо загрузить и кешировать в производственной среде один раз. Каждый образ контейнера может быть повторно использован всеми контейнерами, которые включают его в качестве основы.
Работа с контейнерами#
Команда podman run запускает процесс в новом контейнере на основе образа контейнера. Если образ контейнера еще не загружен, то podman run извлекает образ контейнера и все зависимости от образа из репозитория тем же способом, что и запущенный podman pull image, перед запуском контейнера из этого образа. Контейнерный процесс имеет свою собственную файловую систему, свою собственную сеть и свое собственное изолированное дерево процессов.
Команда podman run имеет вид:
podman run [options] image [command [arg ...]]
Основными параметрами являются:
--detach (-d): Запуск контейнера в фоновом режиме и печать нового идентификатора контейнера.
--attach (-a) Запуск контейнера в режиме переднего плана.
--name (-n): Присвоение имени контейнеру. Если имя контейнеру не присвоено с помощью --name, то генерируется случайное строковое имя. Это работает как для режима фоновых контейнеров, так и для контейнеров в режиме переднего плана.
--rm: Автоматическое удаление контейнера при его завершении. Обратите внимание, что контейнер не будет удален, если его не удалось создать или запустить успешно.
--tty (-t): Выделение псевдотерминала и присоединение его к стандартному входному сигналу контейнера.
--interactive (-i): Использование интерактивных процессов -i и -t совместно для выделения терминала для процесса контейнера. Часто -i -t записывается как -it.
Выполнение команд внутри контейнера#
В этой процедуре показано, как можно использовать команду podman run для интерактивного запуска контейнера.
Необходимые требования:
Установлен инструмент Podman.
podman [options] [command]
Если запущенный контейнер, остановить, но не удалять, этот контейнер будет сохранен в локальной системе пользователя и готов к повторному запуску. Можно использовать команду podman start для повторного запуска контейнеров. Вы можете указать контейнеры по их идентификатору контейнера или имени.
Необходимые требования:
Установлен инструмент Podman.
yum module install -y container-tools
Минимум один контейнер был остановлен.
Процедура:
Запустите myubi контейнер в неинтерактивном режиме:
podman start myubiВ качестве альтернативы можно использовать
podman start id.В интерактивном режиме используйте
-a (--attach)и-t (--interactive)опции для работы с оболочкой bash контейнера:podman start -a -i myubiВ качестве альтернативы можно использовать
podman start -a -i id.Введите exit, чтобы выйти из контейнера и вернуться на хост:
[root@id /]# exit
Проверка контейнеров с хоста#
Используйте команду podman inspect для проверки метаданных существующего контейнера в формате JSON. Вы можете указать контейнеры по их идентификатору контейнера или имени.
Необходимые требования:
Установлен инструмент Podman.
yum module install -y container-tools
Процедура:
Проверьте контейнер, определенный по идентификатору id, чтобы получить все метаданные:
podman inspect id
[
{
"Id": "64ad95327c740a0000000000c50b6d906344027a0e000000000001049f681",
"Created": "2021-03-02T11:23:54.591685515+01:00",
"Path": "/bin/rsyslog.sh",
"Args": [
"/bin/rsyslog.sh"
],
"State": {
"OciVersion": "1.0.2-dev",
"Status": "running",
...
Примечание
ID приведен для примера и является несуществующим.
Для получения определенных элементов из файла JSON, например, метки времени StartedAt:
podman inspect --format='{{.State.StartedAt}}' 64ad95327c74
2021-03-02 11:23:54.945071961 +0100 CET
Информация хранится в иерархии. Чтобы просмотреть StartedAt временную метку контейнера (метка StartedAt находится под меткой State), используйте --format параметр и идентификатор или имя контейнера.
Проверка состояния контейнера#
Проверка состояния используется для определения работоспособности или готовности процесса, выполняющегося внутри контейнера.
Если проверка прошла успешно, контейнер получит один из следующих статусов:
healthy— исправен;unhealthy— не исправен.
Для настройки проверки можете использовать следующие параметры при запуске контейнера с помощью команды podman run:
--health-cmd— обязательный параметр, устанавливающий или изменяющий команду для проверки состояния. Необходим для применения других параметров;--health-retries— необязательный параметр, определяющий количество последовательных неудачных проверок, после которых контейнер получит статусunhealthy. Значение по умолчанию 3;--health-start-period— необязательный параметр, определяющий время, по истечению которого будет запущена проверка состояния контейнера. Значение параметра указывается в формате времени, например, 1m17s. Значение по умолчанию 0s;--health-timeout— необязательный параметр, определяющий время, в течение которого проверка состояния должна завершиться, иначе будет считаться неудачной. Значение параметра указывается в формате времени. Значение по умолчанию 30s;--health-interval— необязательный параметр, устанавливающий интервал проверок состояния. Значение параметра указывается в формате времени. Значение по умолчанию 30s;--health-on-failure— необязательный параметр, определяющий действия в случае, если статус контейнераunhealthy. Можете указать одно из следующих значений:none — никаких действий не предпринимается. Значение по умолчанию;
kill — останавливает контейнер;
restart — перезапускает контейнер. Обратите внимание, данное значение параметра не рекомендуется использовать вместе с параметром
--restartв команде;stop — приостанавливает контейнер.
После настройки проверки состояния можете проверить работоспособность контейнера следующими способами:
С помощью команды
podman inspect:podman inspect --format='{{json .State.Health.Status}}' container-name healthyС помощью команды
podman ps:podman ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a680c6919fe localhost/container-name:latest /usr/bin/run-http... 2 minutes ago Up 2 minutes (healthy) container-nameС помощью команды
podman healthcheck run:podman healthcheck run container-name healthy
Подключение каталога на локальном хостинге к контейнеру#
В этом разделе показано, как можно сделать сообщения журнала из контейнера доступными для хост-системы путем подключения хоста -/dev/log устройства внутри контейнера.
Необходимые требования:
Установлен инструмент Podman.
yum module install -y container-tools
Процедура:
Запустите контейнер с именем
log_testи смонтируйте основное/dev/logустройство внутри контейнера:podman run --name="log_test" -v /dev/log:/dev/log --rm \ registry/me/ubi8/ubi logger "Testing logging to the host"Опция
--rmудаляет контейнер при его завершении.Используйте утилиту journalctl для отображения журналов:
journalctl -b | grep Testing Dec 09 16:55:00 localhost.localdomain root[14634]: Testing logging to the host
Монтирование файловой системы контейнера#
Используйте команду podman mount для монтирования корневой файловой системы рабочего контейнера в месте, доступном с хоста.
Необходимые требования:
Установлен инструмент Podman.
yum module install -y container-tools
Процедура:
Запустите контейнер с именем
mysyslog:podman run -d --name=mysyslog registry/me/rsyslogОпционально можно перечислить все контейнеры:
podman ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES c56ef6a256f8 registry/me/rsyslog:latest /bin/rsyslog.sh 20 minutes ago Up 20 minutes ago mysyslogСмонтируйте контейнер
mysyslog:podman mount mysyslog /var/lib/containers/storage/overlay/990b5c6ddcdeed4bde7b245885ce450000000553d108310e0000000e4675089/mergedОтобразите содержимое точки монтирования с помощью
lsкоманды:ls /var/lib/containers/storage/overlay/990b5c6ddcdeed4bde7b245885ce450000000553d108310e0000000e4675089/merged bin boot dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr varОтображение версии операционной системы будет выглядеть следующим образом:
cat /var/lib/containers/storage/overlay/990b5c6ddcdeed4bde7b245885ce450000000553d108310e0000000e4675089/merged/etc/os-release NAME="sberLinux" VERSION="8 (Ootpa)" ID="slo" ID_LIKE="fedora" ...
Выполнение команд внутри запущенного контейнера#
Используйте команду podman exec для выполнения команды в работающем контейнере и исследования этого контейнера. Причина использования команды podman exec вместо podman run command команды заключается в том, что можно исследовать запущенный контейнер, не прерывая его работу.
Необходимые требования:
Установлен инструмент Podman.
yum module install -y container-tools
Процедура:
Выполните команду
rpm -qaвнутри myrsyslog контейнера, чтобы получить список всех установленных пакетов:podman exec -it myrsyslog rpm -qa tzdata-2020d-1.el8.noarch python3-pip-wheel-9.0.3-18.el8.noarch redhat-release-8.3-1.0.el8.x86_64 filesystem-3.8-3.el8.x86_64 ...Выполните
/bin/bashкоманду в myrsyslog контейнере:podman exec -it myrsyslog /bin/bashУстановите
procps-ngпакет, содержащий набор системных утилит (например, ps, top, uptime и так далее):yum install procps-ngПроверьте контейнер, чтобы перечислить каждый процесс в системе:
ps -ef UID PID PPID C STIME TTY TIME CMD root 1 0 0 10:23 ? 00:00:01 /usr/sbin/rsyslogd -n root 8 0 0 11:07 pts/0 00:00:00 /bin/bash root 47 8 0 11:13 pts/0 00:00:00 ps -efПроверьте контейнер для отображения использования дискового пространства файловой системы:
df -h Filesystem Size Used Avail Use% Mounted on fuse-overlayfs 27G 7.1G 20G 27% / tmpfs 64M 0 64M 0% /dev tmpfs 269M 936K 268M 1% /etc/hosts shm 63M 0 63M 0% /dev/shm ...Проверьте контейнер для отображения системной информации:
uname -r 4.18.0-240.10.1.el8_3.x86_64
Проверьте контейнер для отображения объема свободной и используемой памяти в мегабайтах:
free --mega
total used free shared buff/cache available
Mem: 2818 615 1183 12 1020 1957
Swap: 3124 0 3124
Совместное использование файлов между двумя контейнерами#
Тома можно использовать для сохранения данных в контейнерах, даже если контейнер удален. Тома можно использовать для совместного использования данных между несколькими контейнерами. Том - это папка, которая хранится на главном компьютере. Том может быть общим для контейнера и хоста.
Основными преимуществами являются:
Тома могут быть общими для контейнеров.
Резервное копирование или миграция томов упрощаются.
Объемы не увеличивают размер контейнеров.
Необходимые требования:
Установлен инструмент Podman.
yum module install -y container-tools
Процедура:
Создайте том:
podman volume create hostvolumeОтобразите информацию о томе:
podman volume inspect hostvolume [ { "name": "hostvolume", "labels": {}, "mountpoint": "/home/username/.local/share/containers/storage/volumes/hostvolume/_data", "driver": "local", "options": {}, "scope": "local" } ]Обратите внимание, что при этом создается том в каталоге
volumes. Можно сохранить путь к точке монтирования в переменной для упрощения манипуляций:$ mntPoint=$(podman volume inspect hostvolume --format {{.Mountpoint}}).Также при запуске
sudo podman volume create hostvolumeточка монтирования меняется на/var/lib/containers/storage/volumes/hostvolume/_data.Создайте текстовый файл внутри каталога, используя путь, который хранится в
mntPointпеременной:echo "Hello from host" >> $mntPoint/host.txtПеречислите все файлы в каталоге, определенном
mntPointпеременной:ls $mntPoint/ host.txtЗапустите контейнер с именем
myubi1и сопоставьте каталог, определенный поhostvolumeимени тома на хосте, с/containervolume1каталогом в контейнере:podman run -it --name myubi1 -v hostvolume:/containervolume1 registry.me/ubi8/ubi /bin/basОбратите внимание, что если используется путь к тому, определенному
mntPointпеременной(-v $mntPoint:/containervolume1), данные могут быть потеряны при выполненииpodman volume pruneкоманды, которая удаляет неиспользуемые тома. Всегда используйте-v hostvolume_name:/containervolume_name.Перечислите файлы в общем томе контейнера:
ls /containervolume1 host.txtМожно просмотреть
host.txtфайл, который создали на хосте.Создайте текстовый файл внутри
/containervolume1каталога:echo "Hello from container 1" >> /containervolume1/container1.txtОтсоединитесь от контейнера с помощью сочетания клавиш
CTRL+pиCTRL+q.Перечислите файлы в общем томе на хосте. Появится два файла:
ls $mntPoint container1.rxt host.txtНа этом этапе вы предоставляете общий доступ к файлам между контейнером и хостом. Чтобы предоставить общий доступ к файлам между двумя контейнерами, запустите другой контейнер с именем
myubi2.Запустите контейнер с именем
myubi2и сопоставьте каталог, определенный поhostvolumeимени тома на хосте, с/containervolume2каталогом в контейнере:
podman run -it --name myubi2 -v hostvolume:/containervolume2 registry.me/ubi8/ubi /bin/bash
Перечислите файлы в общем томе контейнера:
ls /containervolume2
container1.txt host.txt
Можно просмотреть host.txt файл, который был создан на хосте, и container1.txt, который был создан внутри myubi1 контейнера.
Создайте текстовый файл внутри
/containervolume2каталога:
echo "Hello from container 2" >> /containervolume2/container2.txt
Отсоединитесь от контейнера с помощью сочетания клавиш
CTRL+pиCTRL+q.Перечислите файлы в общем томе на хосте. Появится три файла:
ls $mntPoint
container1.rxt container2.txt host.txt
Создание Docker-образа для приложений node.js с помощью dockerfile#
В качестве примера рассматривается создание Docker-образа с помощью dockerfile для приложений node.js.
Необходимые требования:
Установлен инструмент Podman.
yum module install -y container-tools
Процедура:
Извлеките базовый образ:
podman pull <path>/nodejs-<version>Скопируйте код приложения из репозитория с помощью команды
git cloneв результирующий каталогapp-src.Настройте приложение внутри контейнера. Для этого создайте Dockerfile со следующим содержимым:
# Указать базовый образ FROM <path>/nodejs-<version> as builder # Добавить результирующий каталог с кодом приложения ADD app-src $HOME # Установить зависимости RUN npm install # Указать минимальный образ среды выполнения FROM <path>/nodejs-<version> # Скопировать код приложения и артефакты сборки из базового образа COPY --from=builder $HOME $HOME # Запустить скрипт CMD npm run -d startСоздайте новый образ, используя Dockerfile:
podman build -t node-appЗапустите созданный образ:
podman run -d node-app
Создание Docker-образа для Java-приложений с помощью dockerfile#
В качестве примера рассматривается создание Docker-образа с помощью dockerfile для Java-приложений с OpenJDK.
Необходимые требования:
Установлен инструмент Podman.
yum module install -y container-tools
Процедура:
Извлеките базовый образ:
podman pull <path>/openjdk-<version>Скопируйте код приложения из репозитория с помощью команды
git cloneв результирующий каталогmy-app.Настройте приложение внутри контейнера. Для этого создайте Dockerfile со следующим содержимым:
# Указать базовый образ FROM <path>/openjdk-<version> as builder # Добавить результирующий каталог с кодом приложения ADD my-app $HOME # Скомпилировать файл Main.java RUN javac Main.java # Указать минимальный образ среды выполнения FROM <path>/openjdk-<version>-runtime # Скопировать код приложения и артефакты сборки из базового образа COPY --from=builder $HOME $HOME # Запустить скрипт CMD ["java", "Main"]Создайте новый образ, используя Dockerfile:
podman build -t java-appЗапустите созданный образ, привязав порт в контейнере к порту в хосте с помощью параметра
-p:podman run -p 0000:0000 -d java-app
Создание юнит-файла systemd с использованием Quadlet#
Quadlet — инструмент для запуска контейнеров podman в формате юнит-файлов systemd.
В настоящее время создание юнит-файлов Quadlet доступно для пользователя с правами root в следующих директориях: /usr/share/containers/systemd/ или /etc/containers/systemd/.
Необходимые требования:
Установлен инструмент Podman.
yum module install -y container-tools
Процедура:
Создайте юнит-файл
mysleep.container:cat /etc/containers/systemd/Со следующим содержимым:
[Unit] Description=The sleep container After=local-fs.target [Container] Image=localhost/container-name:latest Exec=sleep 1000 [Install] # Запуск по умолчанию при загрузке WantedBy=multi-user.target default.targetОбратите внимание на поля в разделе [Container]:
Image- указывается путь к контейнеру, который будет запускаться в формате юнит-файла;Exec- команда, которая будет выполняться внутри контейнера.
Создайте
mysleep.serviceна основеmysleep.container:systemctl daemon-reloadОпционально. Проверьте статус
mysleep.service:systemctl status mysleep.service ○ mysleep.service - The sleep container Loaded: loaded (/etc/containers/systemd/mysleep.container; generated) Active: inactive (dead)Запустите
mysleep.service:systemctl start mysleep.serviceПроверьте статус
mysleep.service:systemctl status mysleep.service ● mysleep.service - The sleep container Loaded: loaded (/etc/containers/systemd/mysleep.container; generated) Active: active (running) since Thu 2023-01-01 11:00:00 EST; 2s ago Main PID: 265651 (conmon) Tasks: 3 (limit: 76815) Memory: 1.6M CPU: 94ms CGroup: ...Проверьте, что контейнер запущен, с помощью команды:
podman ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 421c8293fc1b localhost/container-name:latest sleep 1000 30 seconds ago Up 10 seconds ago systemd-mysleep
Оболочка входа Podmansh#
Podmansh позволяет запускать пользовательскую оболочку внутри контейнера, когда пользователь входит в систему, и заменяет стандартную оболочку, например, /usr/bin/bash на /usr/bin/podmansh.
Контейнер, внутри которого будет запущена оболочка, определяется с помощью юнит-файла Quadlet. Данный файл может быть создан в директориях:
/usr/share/containers/systemd/или/etc/containers/systemd/- systemd запустит юнит-файл для всех пользователей при входе в систему;/etc/containers/systemd/users/${UID}- systemd запустит юнит-файл для конкретного пользователя.
В качестве примера приведен сценарий создания юнит-файла Quadlet, когда создаваемый контейнер Podmansh не имеет доступа к операционной системе и все операции выполняются исключительно внутри контейнера.
Необходимые требования:
Установлено средство Podman.
yum module install -y container-tools
Процедура:
Запустите сеанс входа пользователя с помощью команд:
useradd -s /usr/bin/podmansh lockedu grep lockedu /etc/passwd lockedu:x:4008:4008::/home/lockedu:/usr/bin/podmanshСоздайте юнит-файл Quadlet
podmansh.containerв/etc/containers/systemd/users/${USER_ID}, используя команды:USER_ID=$(id -u lockedu) mkdir -p /etc/containers/systemd/users/${USER_ID} cat > /etc/containers/systemd/users/${USER_ID}/podmansh.containerСодержимое юнит-файла
podmansh.container:[Unit] Description=The podmansh container After=local-fs.target [Container] Image=localhost/container-name:latest ContainerName=podmansh RemapUsers=keep-id RunInit=yes DropCapability=all NoNewPrivileges=true Exec=sleep infinity [Install] RequiredBy=default.targetОбратите внимание на поля в разделе [Container]:
Image- указывается путь к контейнеру, который будет запускаться в формате юнит-файла;ContainerName- имя контейнера должно быть указано какpodmansh, так как/usr/bin/podmanshвыполняет командуpodman execв контейнерpodmansh;RemapUsers- отображает USER_ID пользователя внутри контейнера;RunInit- Podman запустит процесс инициализации внутри контейнера, который очистит все бездействующие процессы;DropCapability- Podman предотвращает получение контейнерным процессом каких-либо возможностей и прав в системе;NoNewPrivileges- Podman не позволяет контейнеру получать какие-либо новые привилегии в дополнение к существующим;Exec- команда, которая будет выполняться внутри контейнера.
Создайте
podmansh.serviceна основеpodmansh.container:systemctl daemon-reloadЗапустите
podmansh.service:systemctl start podmansh.service