28  Контейнеризация приложений

28.1 Литература

28.2 Задание №1

Обернуть любую программу, написанную вами в процессе обучения, в Docker контейнер. Для этого вам потребуется собрать Docker образ (image) из специального файла, который так и называется Dockerfile. Пример подобного файла разобран на Listing 28.1.

Listing 28.1: Пример Dockerfile
# Используем базовый образ Ubuntu 
FROM myregistry.mydomain.ru/pbis:bionic
ARG DEBIAN_FRONTEND=noninteractive

# Устанавливаем необходимые пакеты
RUN apt-get update && apt-get install -y \
    wget \
    bzip2 \
    libz-dev \
    git \
    build-essential \
    && apt-get clean

# Запуск цепи команл терминала: Скачивание архива, распаковка, удаление ненужных файлов
RUN wget https://sourceforge.net/projects/bbmap/files/BBMap_39.10.tar.gz && \
    tar -xzf BBMap_39.10.tar.gz && \
    rm BBMap_39.10.tar.gz

# Добавление в образ определенных файлов. Есть разница между командами ADD и COPY!
ADD soft/yakushina_meth.tar.gz /new_meth/
RUN chmod -R 0700 /new_meth
RUN chmod -R 0700 /bbmap

# Переменные окружения внутри контейнера
ENV CONDA_DIR /opt/conda
# Устанавливаем Anaconda
RUN wget --quiet https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh -O /tmp/miniconda.sh && \
    bash /tmp/miniconda.sh -b -p $CONDA_DIR && \
    rm /tmp/miniconda.sh

# Добавляем Anaconda в PATH
ENV PATH=$CONDA_DIR/bin:$PATH
COPY envs/pod.yml /pod.yml
RUN conda init
RUN conda env create -f /pod.yml
# Not change order
ENV PATH="${PATH}:/bbmap"\
    LC_ALL=C
ENV PATH /opt/conda/envs/soft/bin:$PATH
RUN sed -i ~/.profile -e 's/mesg n || true/tty -s \&\& mesg n/g'
RUN echo "conda activate soft" >> ~/.bashrc

# Команда по умолчанию
CMD ["source", "~/.profile"]

Ваша задача сделать так, чтобы

  1. Ваш контейнер был как можно легче, т.е. содержал как только необходимые зависимости.
  2. Был доступен для проверки и запуска преподавателем. Для этого вам потребуется зарегистрироваться на Docker Hub и отправить свой публичный образ на эту платформу с помощью командной строки.
  3. Ваша программа работала внутри контейнера. Приложите инструкцию к запуску. Причем вызов программы должен быть не “python /path/to/my_beautiful_script.py some_args”, а “my_beautiful_program some_args”

28.3 Задание №2

ВНИМАНИЕ

В процессе выполнения второго задания будут использованы системные утилиты. При неправильном их использовании можно поломать операционную систему. Настоятельно рекомендую использовать виртуальную машину для выполнения.

28.3.1 Часть №1. chroot

  1. Создайте директорию с любым именем в папке /tmp. Для чего нужна папка /tmp?

  2. Скопируйте туда файл с исполняемой оболочкой. Как узнать, где она расположена?

  3. Попробуйте изменить корень для вашего процесса. Получилось ли у вас? Если нет, то как исправить?

    chroot path/to/dir process_command
  4. Выполните команду pwd и ls? Какие команды не получилось выполнить и почему? Как это исправить?

  5. Посмотрите запущенные процессы? Почему у вас это не получится сделать? Как исправить?

  6. После исправления мы будем видеть также процессы хоста. Почему?

28.3.2 Часть №2. namespaces

  1. Создайте пространства имен (mount, net и pid) для вашего процесса из первого задания с помощью утилиты unshare.

  2. Вызовите команду ps aux. Сравните вывод с заданием 1. Является ли текущее исполнение полноценным контейнером?

28.3.3 Часть №3. cgroups

  1. С помощью утилиты unshare создайте для вашего процесса все существующие типы namespace

  2. Создайте контрольные группы на хосте(!) для вашего процесса. Для этого создайте папку с такимже именем, что и ваш контйенер в папке /sys/fs/cgroups

  3. Задайте лимит для максимальной ОЗУ вашего контенера в 1 Мб. Какие ещё можно создавать ограничения?

  4. Создайте и запустите простой нагрузочный тест для проверки ограничения. Проверьте по логам, что это действительно сработала cgroup

28.3.4 Часть №4. Создание контейнера без docker.

  1. Создайте новую директорию в /tmp и перейдите в неё.
  2. Вызовите утилиту runc spec. Будет создан config.json и директория rootfs. Вспомните формат JSON. Что содержится в этом файле?
  3. Установите программу debootstrap. С её помощью установите ubuntu jammy в созданный rootfs.
  4. Запустите контейнер с помощью rootfs run dirname.
  5. Сравните идентификаторы пространств имен на хосте и в контейнере.

28.4 Вопросы

  1. Определения вирутализации, контейнеризации, контейнера
  2. Определения пространств имен, виды пространств имен
  3. Определение контрольных групп. Виды контрольных групп. Разница между контрольными группами и пространствами имён
  4. OCI bundle, что такое и в чем его необходимость?