Docker

Дмитрий Шурмакин — ML Engineer
Лев Коваленко — Senior DS Engineer
Егор Горбань — Data Engineer

Что такое Docker?

Docker - это инструмент, который помогает упаковывать приложения и их зависимости в отдельные “контейнеры”, делая их легкими для переноса и запуска на любой системе.

Контейнеризация

Контейнеризация - это тип виртуализации, который выводит виртуализацию на уровень операционной системы.

Отличия от виртуализации

Преимущества

  • Docker решает проблемы зависимостей и рабочего окружения
  • Изоляция
  • Ускорение и автоматизация развертывания приложений
  • Контейнеры приближают к микросервисной архитектуре
  • Масштабируемость

Недостатки

  • Снижение производительности
  • Управление данными
  • Сложность сетевой конфигурации
  • Безопасность
  • Зависимость от Docker Hub

Докер-объекты

Установка Docker

  • Используя инструкции с офф. источника на примере Ubuntu и др.

  • Установка с помощью скрипта

curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh ./get-docker.sh --dry-run
  • Для Windows и macOS вы можете загрузить Docker Desktop по следующей ссылке

Проверить, успешно ли установлен Docker, выполнив команду:

sudo docker run hello-world

Работа с docker

Docker Volumes

  • Предназначение
    1. Шэрить файлы между контейнерами
    2. Сохранять состояние объектов/файлов из контейнера на хост

docker run -v [ <volume_name> | /path/to/local/file ]:<path/inside/container>:rw [...]
  • Доступы к вольюму
    • :rw - доступ на чтение и запись
    • :ro - только чтение
  • Просмотр вольюмов:
    • docker volume ls

Создание Dockerfile

  • Список команд Dockerfile с описанием и примерами:

https://docs.docker.com/reference/dockerfile/

  • Создадим файл с названием Dockerfile и поместим туда код:
FROM mambaorg/micromamba

WORKDIR /app

RUN micromamba create -n example python=3.11 jupyter -c conda-forge -y

ENTRYPOINT ["micromamba", "run", "-n", "example", "jupyter", "notebook", "--ip=0.0.0.0", "--port=8888", "--allow-root" ]

Команды Docker

  • docker build <context> - Этот командный шаблон используется для сборки Docker-контейнера в соответствии с инструкциями, указанными в файле Dockerfile.

    • <context> - путь до базовой папки (чаще всего используется docker build .). При запуске инструкции build, docker демону передаётся указанный контекст, за исключением всех файлов, указанных в .dockerignore. Поэтому тяжелые файлы, которые не нужны для сборки образа лучше указывать в .dockerignore файле, чтобы не нагружать daemon.
    • -f Dockerfile.debug - Параметр -f указывает путь к файлу Dockerfile, содержащему инструкции для сборки контейнера. В данном случае, Dockerfile.debug указывает на отладочный файл Dockerfile.
    • -t <имя> - Опция -t используется для установки тега (имени) для собранного контейнера, чтобы можно было легко идентифицировать его в дальнейшем.
  • docker run - Данная команда запускает собранный Docker-контейнер.

    • --rm - Опция --rm автоматически удаляет контейнер после его остановки, что полезно для избежания накопления неиспользуемых контейнеров.
    • -it - Опция -it используется для запуска контейнера в интерактивном режиме, обеспечивая доступ к его стандартному вводу/выводу (stdin/stdout).
    • -p 8080:80 - Этот флаг пробрасывает порт контейнера на хостовую машину. В данном случае, порт 80 контейнера привязывается к порту 8080 хостовой машины [external_port:internal_port].
    • -v ./data/:/workdir/data - Опция -v используется для создания привязки тома, позволяя контейнеру доступ к файлам на хостовой машине. В данном примере, директория ./data/ на хостовой машине привязывается к директории /workdir/data внутри контейнера.
    • --name <название> - Опция --name позволяет задать пользовательское имя контейнера для удобства идентификации его в дальнейшем.
    • --net <тип> - Опция --net позволяет настраивать сетевое окружение контейнера. Значение <тип> определяет тип сети, в которой будет работать контейнер.
    • -e <переменная=значение> - Опция -e позволяет передавать переменные среды в контейнер во время его выполнения.
    • -d - запуск в тихом режиме, без отображения событий внутри работающего контейнера.
    • -m 4GB - установка ограничения используемой контейнером памяти. В данном случае контейнер сможет использовать во время своего выполнения 4 ГБ памяти.
  • docker ps - Эта команда отображает список запущенных Docker-контейнеров.

    • -a - Опция -a показывает все контейнеры, включая остановленные.
    • -q - показывает только идентификаторы контейнеров. Полезно для комбинаций команд, например команда docker stop $(docker ps -q) останавливает все запущенные контейнеры.
  • docker logs <идентификатор_контейнера|имя_контейнера> - Команда docker logs используется для просмотра журналов вывода контейнера.

    • -f - Опция -f позволяет отслеживать живую потоковую передачу журналов, т.е. вывод в реальном времени.
    • -n <число> - Опция -n позволяет указать количество последних строк журнала для отображения.
  • docker stop <идентификатор_контейнера|имя_контейнера> - Эта команда используется для остановки запущенного Docker-контейнера.

  • docker rm <идентификатор_контейнера|имя_контейнера> - Команда docker rm удаляет указанный контейнер.

  • docker exec -it <идентификатор_контейнера|имя_контейнера> bash - Команда docker exec используется для выполнения команд внутри работающего контейнера Docker.

  • docker inspect <идентификатор_контейнера|имя_контейнера> - Команда docker inspect предоставляет подробную информацию о контейнере Docker, включая его настройки и параметры.

  • docker stats [ <идентификатор_контейнера|имя_контейнера> | --all ] - Команда docker stats позволяет в режиме реального времени мониторить ресурсы потребляемые одним контейнером, или всеми контейнерами при использовании флага --all.

  • docker <object> prune - очистка неиспользуемых объектов. Вместо <object> может находиться: container, image, volume, а в случае если нужно сразу очистить всё неиспользуемое - system.

Docker-Compose

Создадим файл с названием docker-compose.yml и поместим туда код.

тут ваш замечательный файл (предположим нам для чего-то понадобился редис)

version: '3.7'

services:
  redis:
    container_name: mlops_redis
    image:
      redis
  app:
    container_name: mlops_app
    build:
      context: .
      dockerfile: Dockerfile
    command: ["uvicorn", "..."] # перезаписывает CMD в Dockerfile
    env_file:
      - ".env"
    depends_on:
      redis
    volumes:
      - mlops_volume:/home/mlops/data:rw

volumes:
  mlops_volume:

Команды Docker-Compose

  • docker-compose up - Эта команда используется для запуска сервисов, описанных в файле docker-compose.yml.

    • -d - Опция -d позволяет запустить сервисы в фоновом режиме, без вывода логов в терминал.
    • --build - Опция --build используется для пересборки образов перед запуском контейнеров.
  • docker-compose down - Данная команда останавливает и удаляет все контейнеры, созданные с помощью docker-compose up.

    • --volumes - Опция --volumes удаляет также и тома данных, связанные с контейнерами.
  • docker-compose logs <service> - Команда docker-compose logs позволяет просматривать логи для определенного сервиса из вашего docker-compose.yml.

    • --follow - Опция --follow (или -f) отображает логи в реальном времени.
  • docker-compose ps - Эта команда показывает статус всех сервисов, запущенных с помощью docker-compose.

  • docker-compose exec <service> <command> - Команда docker-compose exec используется для выполнения команд внутри контейнера сервиса.

    • Пример: docker-compose exec webserver bash запускает интерактивный терминал в контейнере webserver.
  • docker-compose restart <service> - Эта команда перезапускает указанный сервис.

  • docker-compose stop <service> - Команда docker-compose stop останавливает указанный сервис без его удаления.

  • docker-compose start <service> - Эта команда запускает остановленный сервис.

  • docker-compose build - Команда docker-compose build используется для сборки образов, описанных в docker-compose.yml.

  • docker-compose config - Эта команда проверяет конфигурационный файл docker-compose.yml и выводит его валидность, а также объединяет все файлы конфигурации в один.

Исследование контейнера

  1. Соберите образ с тэгом mlops_app:latest, передав текущую папку как контекст

    docker build -t mlops_app:latest ./
  2. Запустите контейнер с названием mlops_container

    docker run -it --name mlops_container --rm mlops_app:latest
  3. В отдельном терминале подключитесь к файловой системе запущенного контейнера

    docker exec -it mlops_container bash
  4. Также в отдельном терминале можно проверить ресурсы, которые потребляет контейнер с помощью команды

    docker stats mlops_container