Лабораторная работа 1. Основы контейнеризации, Docker и Podman

Цель

Вы разберётесь, как устроены образы и контейнеры, и попробуете разные способы хранения данных.

Задачи

  1. Запустите контейнер и выполните в нём команды.
  2. Соберите собственный образ веб-сервера.
  3. Опубликуйте порт и проверьте HTTP-запрос.
  4. Сравните слой контейнера, volume и bind mount.
  5. Удалите только ресурсы своей работы.

Рабочее окружение

Вам понадобятся навыки из ЛБ0 и каталог containers/lab1. Укажите в отчёте, сколько времени заняла работа. Выберите один движок. Второй нужен только для дополнительного задания.

СредаПодготовкаКоманда движка
Ubuntu-ВМ или Linux, Docker EngineПроверьте sudo docker versionsudo docker
Linux, Podman от своего пользователяПроверьте podman infopodman
Windows, Docker DesktopВключите Linux containers и интеграцию своего WSL-дистрибутива; откройте Bash в нёмdocker
macOS, Docker DesktopДождитесь запуска Docker Desktop; откройте Terminal, выполните bashdocker
Windows/macOS, Podman machineСоздайте машину и войдите в неё по инструкции нижеpodman внутри машины

Для Podman на Windows в PowerShell, на macOS в Terminal выполните:

podman machine init
podman machine start
podman machine ssh

init нужен только при первом создании машины. Далее команды работы вводите в Bash внутри Podman machine. Проверьте podman info. Так вы будете работать в одной среде и не перепутаете Windows CLI с Linux CLI другого WSL-дистрибутива.

Каталог проекта должен быть доступен движку:

  • Ubuntu-ВМ/Linux: cd ~/labs-mag/containers/lab1;
  • Docker Desktop в Windows: скопируйте проект в домашний каталог своего WSL, выполните cd ~/labs-mag/containers/lab1;
  • Docker Desktop на macOS: тот же путь под домашней директорией;
  • Podman machine в Windows с WSL-провайдером: проект храните в каталоге пользователя Windows; внутри машины перейдите в /mnt/c/Users/ИМЯ_ПОЛЬЗОВАТЕЛЯ/labs-mag/containers/lab1;
  • Podman machine на macOS: проверьте общий каталог /Users, перейдите в /Users/ИМЯ_ПОЛЬЗОВАТЕЛЯ/labs-mag/containers/lab1.

Замените имя пользователя своим, пути с пробелами заключайте в кавычки. Если используете другой провайдер Podman machine, отдельно проверьте, какие каталоги подключены к машине. Если каталог недоступен, используйте Ubuntu-ВМ. На Apple Silicon нужны arm64-образы.

Перейдите в каталог работы и проверьте выбранный движок. В каждом задании выполняйте только один блок: Docker или Podman.

В примерах Docker используется sudo docker для Ubuntu-ВМ/Linux. В Docker Desktop на Windows/macOS вводите docker без sudo: например, docker info и docker image inspect nginx:1.26-alpine.

Docker:

sudo docker info
sudo docker image inspect nginx:1.26-alpine

Podman:

podman info
podman image inspect nginx:1.26-alpine

Если образ отсутствует, при наличии интернета выполните команду своего движка: sudo docker pull nginx:1.26-alpine или podman pull nginx:1.26-alpine. Для Docker Desktop: docker pull nginx:1.26-alpine. В подготовленной Ubuntu-ВМ Docker-образ уже загружен. Для rootless Podman заранее выполните pull отдельно: хранилища Docker и Podman независимы.

Задание 1. Образ и контейнер

1. Запустите контейнер с переменной окружения:

Docker:

sudo docker run -d --name lab1-web -e COURSE=linux -p 127.0.0.1:8080:80 nginx:1.26-alpine
sudo docker ps
sudo docker exec lab1-web sh -c 'echo "$COURSE"; uname -r; cat /etc/os-release'
curl -f http://127.0.0.1:8080/
sudo docker logs lab1-web

Podman:

podman run -d --name lab1-web -e COURSE=linux -p 127.0.0.1:8080:80 nginx:1.26-alpine
podman ps
podman exec lab1-web sh -c 'echo "$COURSE"; uname -r; cat /etc/os-release'
curl -f http://127.0.0.1:8080/
podman logs lab1-web

На Windows/macOS откройте этот же URL в браузере основной ОС. Если проброс портов Podman machine не работает, проверьте порт внутри неё и используйте Ubuntu-ВМ. Образ содержит файлы, контейнер — запущенный экземпляр с изменяемым слоем. Ядро Linux общее с машиной движка: на Windows/macOS это ядро служебной ВМ.

2. Посмотрите слои и удалите контейнер:

Docker:

sudo docker history nginx:1.26-alpine
sudo docker stop lab1-web
sudo docker rm lab1-web

Podman:

podman history nginx:1.26-alpine
podman stop lab1-web
podman rm lab1-web

Почему удаление контейнера не удаляет образ?

Задание 2. Собственный образ

1. Откройте index.html, впишите группу и номер бригады. Самостоятельно создайте файл Dockerfile из двух инструкций:

  • FROM — базовый образ nginx:1.26-alpine;
  • COPY — скопируйте index.html в /usr/share/nginx/html/index.html.

2. Соберите и запустите образ:

Docker:

sudo docker build -t lab1-web:student .
sudo docker run -d --name lab1-web -p 127.0.0.1:8080:80 lab1-web:student
curl -f http://127.0.0.1:8080/
sudo docker logs lab1-web

Podman:

podman build -t lab1-web:student .
podman run -d --name lab1-web -p 127.0.0.1:8080:80 lab1-web:student
curl -f http://127.0.0.1:8080/
podman logs lab1-web

Проверьте свой текст в ответе. Измените исходный HTML без пересборки и повторите запрос. Объясните, почему файл внутри образа не изменился.

Задание 3. Три места хранения данных

1. Создайте файл в слое контейнера и пересоздайте контейнер:

Docker:

sudo docker exec lab1-web sh -c 'echo temporary > /tmp/note'
sudo docker stop lab1-web
sudo docker rm lab1-web
sudo docker run -d --name lab1-web -p 127.0.0.1:8080:80 lab1-web:student
sudo docker exec lab1-web cat /tmp/note

Podman:

podman exec lab1-web sh -c 'echo temporary > /tmp/note'
podman stop lab1-web
podman rm lab1-web
podman run -d --name lab1-web -p 127.0.0.1:8080:80 lab1-web:student
podman exec lab1-web cat /tmp/note

Отсутствие файла — ожидаемый результат. Сохраните сообщение об ошибке.

2. Создайте именованный том и запишите файл:

Docker:

sudo docker volume create lab1-data
sudo docker run --rm -v lab1-data:/data nginx:1.26-alpine sh -c 'echo persistent > /data/note'
sudo docker run --rm -v lab1-data:/data nginx:1.26-alpine cat /data/note

Podman:

podman volume create lab1-data
podman run --rm -v lab1-data:/data nginx:1.26-alpine sh -c 'echo persistent > /data/note'
podman run --rm -v lab1-data:/data nginx:1.26-alpine cat /data/note

Оба временных контейнера удалены, данные тома остались. --rm удаляет контейнер после завершения команды.

3. Замените контейнер вариантом с bind mount:

Docker:

sudo docker stop lab1-web
sudo docker rm lab1-web
sudo docker run -d --name lab1-web -p 127.0.0.1:8080:80 -v "$PWD:/usr/share/nginx/html:ro" lab1-web:student
curl -f http://127.0.0.1:8080/

Podman:

podman stop lab1-web
podman rm lab1-web
podman run -d --name lab1-web -p 127.0.0.1:8080:80 -v "$PWD:/usr/share/nginx/html:ro" lab1-web:student
curl -f http://127.0.0.1:8080/

Измените index.html на машине, где открыт терминал, и повторите запрос. Объясните отличие от COPY и назначение ro. На Linux с SELinux, в том числе в некоторых Podman machine, для своего учебного каталога используйте :ro,z вместо :ro. Если общая файловая система не поддерживает relabel, не отключайте SELinux глобально; выполните работу в Ubuntu-ВМ. Параметры монтирования описаны в документации Podman.

Задание 4. Неисправность и самостоятельное изменение

1. При работающем lab1-web попробуйте занять тот же порт:

Docker:

sudo docker run --name lab1-conflict -p 127.0.0.1:8080:80 lab1-web:student
sudo docker ps -a

Podman:

podman run --name lab1-conflict -p 127.0.0.1:8080:80 lab1-web:student
podman ps -a

Ожидается ошибка занятого порта. Проверьте, какой контейнер его публикует. Если неудачный запуск оставил lab1-conflict, удалите его по имени.

2. Самостоятельно замените опубликованный порт на 8081. До запуска запишите, какой URL будет работать, а какой перестанет. Проверьте, совпал ли результат с прогнозом.

Дополнительно повторите сборку и один HTTP-запрос вторым движком после остановки первого контейнера. Сравните команды и хранилища образов.

Отчёт и вопросы для защиты

Приложите Dockerfile, HTML, ответ HTTP, журнал запроса и результаты трёх опытов с данными. Ответьте:

  1. Чем контейнер отличается от ВМ и образа?
  2. На каком ядре работает контейнер в Docker Desktop?
  3. Что означает 8080:80, почему слева указан 127.0.0.1?
  4. Какие данные переживут stop, rm и пересоздание?
  5. Почему переменная окружения не является надёжным хранилищем секрета?

Сохранение и завершение

Сохраните исходные файлы и вывод команд в отчёт. Посмотрите список ресурсов, остановите и удалите lab1-web, при наличии — lab1-conflict, затем том и образ:

Docker:

sudo docker stop lab1-web
sudo docker rm lab1-web
sudo docker volume rm lab1-data
sudo docker image rm lab1-web:student

Podman:

podman stop lab1-web
podman rm lab1-web
podman volume rm lab1-data
podman image rm lab1-web:student

Не выполняйте system prune. Для повторения оставьте Dockerfile и HTML, заново соберите образ. В Podman machine сначала выйдите из SSH командой exit, затем на основной ОС выполните podman machine stop.