Лаб. работа \"Docker: Образы\"
Лабораторная работа по теме “Docker: Образы”
Цель работы
Изучить концепции Docker-образов, их структуру и принципы работы. Получить практические навыки создания собственных образов с использованием Dockerfile, работы с многослойной архитектурой, оптимизации размера образов и управления тегами.
Краткие теоретические сведения
Docker-образ — это неизменяемый шаблон, содержащий инструкции для создания контейнера. Образ состоит из набора слоев, каждый из которых представляет собой результат выполнения определенной инструкции в Dockerfile.
Ключевые концепции Docker-образов:
- Слои (Layers) — образ строится из нескольких слоев, каждый слой добавляет новые файлы или изменяет существующие. Слои являются неизменяемыми и кэшируются для ускорения сборки.
- Базовый образ (Base Image) — начальный слой, на основе которого строится весь образ. Это может быть минимальная операционная система (Alpine, Ubuntu) или готовый образ с предустановленным ПО.
- Теги (Tags) — метки для версионирования образов. Позволяют указывать конкретные версии ПО (например,
nginx:1.21,python:3.9). - Dockerfile — текстовый файл с инструкциями для сборки образа.
- Кэширование — Docker кэширует промежуточные слои, что ускоряет повторную сборку образа при неизмененных инструкциях.
- Многоэтапная сборка (Multi-stage builds) — техника для уменьшения размера финального образа за счет разделения процесса сборки и финального образа.
Преимущества легковесных образов:
- Быстрая загрузка и распространение
- Меньшее потребление дискового пространства
- Быстрый запуск контейнеров
- Повышенная безопасность (меньше поверхности атаки)
Краткий справочник по инструкциям Dockerfile
Основные инструкции
FROM <образ>[:<тег>]— указывает базовый образ для сборкиRUN <команда>— выполняет команду во время сборки образаCOPY <источник> <назначение>— копирует файлы с хоста в образADD <источник> <назначение>— копирует файлы с хоста или URL в образ (расширенная версия COPY)WORKDIR <путь>— устанавливает рабочую директорию для последующих инструкцийENV <ключ>=<значение>— устанавливает переменную окруженияEXPOSE <порт>— указывает порт, который будет использовать контейнер (документация)CMD ["команда", "аргументы"]— команда по умолчанию при запуске контейнераENTRYPOINT ["команда"]— основная команда контейнера (не переопределяется при запуске)VOLUME ["путь"]— создает точку монтирования для тома
Инструкции для многоэтапной сборки
AS <имя>— именует стадию сборки (используется с FROM)COPY --from=<источник>— копирует файлы из предыдущей стадии сборки
Требования к окружению
- Операционная система: Debian 13 “Trixie” или новее
- Docker Engine установлен и настроен
- Доступ в Интернет для загрузки образов
- Учетная запись пользователя без прав
root - Текстовый редактор (nano, vim или другой)
Порядок выполнения работы
Часть 1. Изучение существующих образов
Просмотр доступных образов Посмотрите список всех образов на вашей системе:
1docker imagesОбратите внимание на столбцы: REPOSITORY, TAG, IMAGE ID, CREATED, SIZE.
Получение детальной информации об образе Получите подробную информацию о любом образе:
1docker inspect nginx:alpineНайдите информацию о слоях, переменных окружения, портах и других параметрах.
История образа Посмотрите историю создания образа:
1docker history nginx:alpineЭто покажет список слоев и команды, которые были использованы для их создания.
Часть 2. Создание простого Dockerfile
Создание рабочей директории Создайте директорию для работы с Dockerfile:
1mkdir ~/docker-images-lab 2cd ~/docker-images-labСоздание простого веб-приложения Создайте файл
app.pyс простым веб-сервером:1from flask import Flask 2import os 3 4app = Flask(__name__) 5 6@app.route('/') 7def hello(): 8 return f'Hello from Docker! Container ID: {os.uname()[1]}' 9 10@app.route('/health') 11def health(): 12 return {'status': 'healthy'}, 200 13 14if __name__ == '__main__': 15 app.run(host='0.0.0.0', port=5000)Создание requirements.txt Создайте файл с зависимостями:
1flask==2.3.3Создание первого Dockerfile Создайте файл
Dockerfileсо следующим содержимым:1# Базовый образ Python 2FROM python:3.11-slim 3 4# Установка рабочей директории 5WORKDIR /app 6 7# Копирование файлов зависимостей 8COPY requirements.txt . 9 10# Установка зависимостей 11RUN pip install --no-cache-dir -r requirements.txt 12 13# Копирование приложения 14COPY app.py . 15 16# Указание порта 17EXPOSE 5000 18 19# Команда запуска 20CMD ["python", "app.py"]Сборка образа Соберите образ с тегом
my-app:v1:1docker build -t my-app:v1 .Обратите внимание на процесс сборки и кэширование слоев.
Проверка размера образа Посмотрите размер созданного образа:
1docker images my-app:v1Тестирование образа Запустите контейнер из образа:
1docker run -d -p 5000:5000 --name my-app-container my-app:v1Проверьте работу приложения:
1curl http://localhost:5000 2curl http://localhost:5000/health
Часть 3. Оптимизация образа
Создание оптимизированного Dockerfile Создайте новый файл
Dockerfile.optimized:1# Многоэтапная сборка для уменьшения размера 2FROM python:3.11-slim as builder 3 4# Установка зависимостей для сборки 5WORKDIR /app 6COPY requirements.txt . 7RUN pip install --user --no-cache-dir -r requirements.txt 8 9# Финальный образ 10FROM python:3.11-slim 11 12# Создание непривилегированного пользователя 13RUN useradd -m -u 1000 appuser 14 15# Установка рабочей директории 16WORKDIR /app 17 18# Копирование установленных зависимостей из builder 19COPY --from=builder /root/.local /home/appuser/.local 20 21# Копирование приложения 22COPY app.py . 23 24# Изменение владельца 25RUN chown -R appuser:appuser /app 26 27# Переключение на непривилегированного пользователя 28USER appuser 29 30# Обновление PATH 31ENV PATH=/home/appuser/.local/bin:$PATH 32 33# Указание порта 34EXPOSE 5000 35 36# Команда запуска 37CMD ["python", "app.py"]Сборка оптимизированного образа Соберите оптимизированный образ:
1docker build -f Dockerfile.optimized -t my-app:v2 .Сравнение размеров Сравните размеры обоих образов:
1docker images | grep my-appЗапишите разницу в размерах.
Тестирование оптимизированного образа Запустите оптимизированный образ:
1docker run -d -p 5001:5000 --name my-app-optimized my-app:v2Проверьте его работу:
1curl http://localhost:5001
Часть 4. Работа с Alpine Linux
Создание Alpine-based образа Создайте файл
Dockerfile.alpine:1# Использование Alpine Linux для минимального размера 2FROM python:3.11-alpine 3 4# Установка рабочей директории 5WORKDIR /app 6 7# Копирование файлов 8COPY requirements.txt app.py ./ 9 10# Установка зависимостей 11RUN pip install --no-cache-dir -r requirements.txt 12 13# Указание порта 14EXPOSE 5000 15 16# Команда запуска 17CMD ["python", "app.py"]Сборка Alpine образа Соберите образ на базе Alpine:
1docker build -f Dockerfile.alpine -t my-app:alpine .Сравнение всех образов Сравните размеры всех созданных образов:
1docker images my-appОбратите внимание на разницу между slim и alpine версиями.
Часть 5. Тегирование и управление версиями
Добавление дополнительных тегов Добавьте несколько тегов к существующему образу:
1docker tag my-app:v1 my-app:latest 2docker tag my-app:v1 my-app:production 3docker tag my-app:v2 my-app:optimizedПросмотр всех тегов Посмотрите все теги образа:
1docker images my-appУдаление образа по тегу Удалите один из тегов:
1docker rmi my-app:productionПроверьте, что образ остался под другими тегами.
Часть 6. Исследование слоев образа
Детальный анализ слоев Посмотрите детальную информацию о слоях образа:
1docker history my-app:v1 2docker history my-app:v2 3docker history my-app:alpineСравнение слоев Сравните количество слоев и их размеры в разных образах.
Использование dive для анализа Установите и используйте утилиту dive для графического анализа образов (если доступно):
1docker run --rm -it -v /var/run/docker.sock:/var/run/docker.sock wagoodman/dive:latest my-app:v1
Задания для самостоятельного выполнения
Создание образа с Nginx и статическим сайтом Создайте Dockerfile, который:
- Использует официальный образ nginx:alpine как базовый
- Копирует простой HTML-файл с вашей страницей
- Оптимизирует размер, удаляя ненужные файлы
- Запускает nginx от непривилегированного пользователя
- Использует многоэтапную сборку для минимизации размера
Создание образа с Node.js приложением Создайте простое Node.js приложение и Dockerfile для него. Используйте:
- node:alpine как базовый образ
- Оптимизированную установку зависимостей
- Healthcheck для проверки работоспособности
- Минимальное количество слоев
Исследование кэширования Создайте Dockerfile и проведите несколько сборок, изменяя разные части файла. Наблюдайте:
- Какие слои кэшируются
- На каком этапе кэш сбрасывается
- Как оптимизировать порядок инструкций для лучшего кэширования
Создание образа с несколькими тегами Создайте образ и назначьте ему несколько тегов (latest, stable, v1.0). Проверьте:
- Как теги связаны с одним образом
- Что происходит при удалении тега
- Как работает команда docker tag
Анализ безопасности образа Используйте команду docker scan (если доступна) или другие инструменты для:
- Проверки уязвимостей в образе
- Сравнения безопасности разных базовых образов
- Поиска неиспользуемых компонентов
Контрольные вопросы
- Что такое Docker-образ и как он отличается от контейнера?
- Какие преимущества дает использование многоэтапной сборки?
- Почему важно минимизировать количество слоев в образе?
- Как работает кэширование слоев при сборке образа?
- В чем разница между инструкциями CMD и ENTRYPOINT?
- Какие существуют способы уменьшения размера Docker-образа?
- Что такое теги и как они используются для версионирования образов?
Требования к отчету
Отчет по лабораторной работе должен содержать:
- Титульный лист
- Цель работы
- Пошаговое описание выполнения работы с приведением всех вводимых команд и их выводов (можно в виде скриншотов или текстовых блоков)
- Сравнительную таблицу размеров созданных образов
- Вывод, в котором необходимо кратко описать полученные знания и навыки, а также привести примеры оптимизированных Dockerfile для ваших заданий