Данная статья применима к:

Для применения  в более ранних обновлениях см. пояснения в тексте.

Установка пакетов

Установить пакеты, необходимые для создания собственных образов Docker, можно либо с помощью графического менеджера пакетов (см. Графический менеджер пакетов synaptic) либо из командной строки командой:

sudo apt install debootstrap docker.io

Создание собственного образа

Собственный образ создается в три этапа:

  1. Выполняется сборка chroot-окружения;
  2. Выполняется настройка chroot-окружения;
  3. Полученное chroot-окружение конвертируется в образ Docker.

Порядок действий:

  1. Сборка chroot-окружения выполняется командой debootstrap. При установке для удобства дальнейшей работы в chroot-окружении можно (не обязательно) сразу установить пакеты ncurses-term, mc, locales, nano, gawk, lsb-release, acl, perl-modules-5.28. Варианты установки:
    1. Если каталоги репозиториев доступны по сети, то загрузка пакетов для сборки может выполняться непосредственно из этих сетевых репозиториев, например, для Astra Linux Special Edition - из общедоступного сетевого репозитория. В примерах ниже chroot-окружение Astra Linux создаётся в каталоге /var/docker-chroot.

      Каталог /var для размещения chroot-окружения выбран потому, что по умолчанию в Astra Linux Special Edition начиная с обновления БЮЛЛЕТЕНЬ № 2022-0819SE17 (оперативное обновление 1.7.2) он имеет метку безопасности 3:63:-1:ccnr, позволяющую создавать в нем файловые объекты с любыми метками безопасности. При работе в более ранних обновлениях Astra Linux следует самостоятельно создать подобный каталог (установить метку на каталог /var). Далее в примерах команды выполняются в привилегированном режиме (от имени администратора с правами суперпользователя (при включенном МКЦ - администратора с правами суперпользователя и с высоким уровнем целостности). Для работы пользователей в непривилегированном режиме администратором системы должен быть создан доступный пользователю каталог с необходимой меткой безопасности.
      Для Astra Linux Special Edition опция --components=main,contrib,non-free обязательна, без неё образ Astra Linux Special Edition собран не будет.

      Для Astra Linux Special Edition РУСБ.10015-01 (очередное обновление 1.7) следует использовать код дистрибутива 1.7_x86-64, например:

      sudo debootstrap \
          --include ncurses-term,mc,locales,nano,gawk,lsb-release,acl,perl-modules-5.28 \
          --components=main,contrib,non-free 1.7_x86-64 \
          /var/docker-chroot \
          http://dl.astralinux.ru/astra/stable/1.7_x86-64/repository-main
      В данном примере предполагается, что сетевые https-репозитории не используются (пакет apt-transport-https не нужен и не устанавливается).

    2. Если сетевые репозитории пакетов недоступны (не используются), то загрузка может быть выполнена из копии репозитория в локальной файловой системе, например:

      sudo debootstrap --verbose orel /var/docker-chroot file:///srv/repo/orel
       

  2. Настройка окружения может выполняться как от имени суперпользователя, так и с переходом в окружение с помощью команды chroot, например:
    1. Можно использовать имеющиеся файлы /etc/resolv.conf и /etc/apt/sources.list просто скопировав его в chroot:

      sudo cp /etc/resolv.conf /var/docker-chroot/etc/resolv.conf
      sudo cp /etc/apt/sources.list /var/docker-chroot/etc/apt/sources.list
      или, по необходимости, отредактировать файлы в окружении с помощью любого текстового редактора, например, указать в файле /var/docker-chroot/etc/apt/sources.list репозитории для создания образа:
      sudo nano /var/docker-chroot/etc/apt/sources.list

      При выборе репозиториев для создания образов следует по возможности использовать репозитории с последними обновлениями. Использование устаревших репозиториев может вести к невозможности сборки образов из-за наличия уязвимостей в пакетах из этих репозиториев. Рекомендованным способом устранения невозможности запуска является установка актуального оперативного обновления в образ, см. статью Ошибка о наличии уязвимости при создании Docker-образа

      Отключить встроенную проверку уязвимостей (не рекомендуется) можно следующим образом:

      Порядок проверки уязвимостей в образах определяется значением параметра astra-sec-level службы dockerd. Значением параметра может быть от 1 до 6 включительно, определяющее класс защиты:

      • Классы защиты 1 — 5: при обнаружении уязвимости в контейнере его запуск блокируется;
      • Класс защиты 6: отладочный режим, при обнаружении уязвимости в контейнере выводится соответствующее предупреждение, при этом запуск контейнера не блокируется.

      Задать значение параметра можно:

      • С помощью конфигурационного файла:
        • Создать каталог /etc/docker если он не был создан ранее:

          sudo mkdir -p /etc/docker

        • Создать конфигурационный файл /etc/docker/daemon.json если он не был создан ранее и указать в нем параметры:

          {
          "debug" : true,
          "astra-sec-level" : 6
          }  
      • С помощью параметров запуска службы:
        • Выполнить команду:

          sudo systemctl edit docker

        • Ввести и сохранить данные:

          [Service]
          Environment="DOCKER_OPTS=--astra-sec-level 6"
      • Независимо от использованного способа перезапустить службу docker:

        sudo systemctl restart docker

       

    2. Выполнить обновление созданного chroot-окружения и, при необходимости, настройку языка, войдя в chroot-окружение с помощью команды chroot (предполагается, что пакет locales был установлен ранее):

      sudo chroot /var/docker-chroot
      apt update
      apt dist-upgrade
      echo "ru_RU.UTF-8 UTF-8" >> /etc/locale.gen
      echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen
      locale-gen
      update-locale ru_RU.UTF-8
      exit

  3. Создание образа:

    sudo tar -C /var/docker-chroot -cpf - . | \
    sudo docker import - wiki/astralinux:se \
        --change "ENV PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" \
        --change 'CMD ["/bin/bash"]' \
        --change "ENV LANG=ru_RU.UTF-8"
    в этом примере использована опция -C чтобы сменить текущий каталог при архивировании и трижды использована опция импорта --change, задающая в первом случае переменную окружения PATH, во втором - команду, которая будет вызываться по умолчанию при запуске контейнера (/bin/bash), и в третьем случае - переменную окружения, задающую язык для работы в контейнере.

Если все операции выполнены успешно, то:

  1. Созданный образ должен отображаться в списке образов:

    sudo docker images
     

  2. В созданный образ можно войти выполнив команду:

    1. Для Astra Linux без МРД и МКЦ:

      sudo docker run -it --rm wiki/astralinux:se

Пример сценария создания собственного образа

#!/bin/sh

program=$(basename $0)
version=1.0

set -e

pkg_missing=false
for required_pkg in docker.io debootstrap; do
    if ! dpkg -l $required_pkg >/dev/null 2>/dev/null; then
        printf 'Please install %s package\n' $required_pkg
        pkg_missing=true
    fi
done
if $pkg_missing; then
    exit 1
fi

# Check docker can be run without sudo
docker version 2>&1 >/dev/null ||\
    (printf 'Please run with sudo or add your account to `docker` group\n';\
    exit 1)

usage="\
Usage:
    $program -v
        Print program version

    $program -r REPOSITORY [-c CODENAME] -i IMAGE_NAME [-b]

        Create Docker image IMAGE_NAME based on REPOSITORY with CODENAME

        -v                Print version
        -r REPOSITORY     Address of the repository
        -c CODENAME       Codename (specified in $REPOSITORY/dists)
        -i IMAGE_NAME     Name of the image being created
        -b                Install base Astra Linux packages

default CODENAME is \"stable\""

invalid_args() {
      echo "${usage}" 1>&2
      exit 1
}

REPO=$REPO
IMAGE=$IMAGE
CODENAME="${CODENAME:-stable}"
install_base_pkgs=false

while getopts 'r:c:i:vb' option; do
  case $option in
    r)
      REPO=$OPTARG
      ;;
    i)
      IMAGE=$OPTARG
      ;;
    c)
      CODENAME=$OPTARG
      ;;
    b)
      install_base_pkgs=true
      ;;
    v)
      echo $program $version
      ;;
    ?)
      invalid_args
      ;;
  esac
done


if [ -z $REPO ]; then
    echo Please specify -r \(repository\) argument
fi
if [ -z $IMAGE ]; then
    echo Please specify -i \(image\) argument
fi
if [ -z $REPO ] || [ -z $IMAGE ]; then
    invalid_args
fi

ROOTFS_IMAGE="$IMAGE-rootfs"

TMPDIR=`mktemp -d`
cd $TMPDIR

cleanup() {
    cd $HOME
    # debootstrap leaves mounted /proc and /sys folders in chroot
    # when terminated by Ctrl-C
    sudo umount $TMPDIR/proc $TMPDIR/sys >/dev/null 2>/dev/null || true
    # Delete temporary data at exit
    sudo rm -rf $TMPDIR
}
trap cleanup EXIT

sudo -E debootstrap --no-check-gpg --variant=minbase \
    --components=main,contrib,non-free "$CODENAME" ./chroot "$REPO"

echo "deb $REPO $CODENAME contrib main non-free" | sudo tee ./chroot/etc/apt/sources.list

docker rmi "$ROOTFS_IMAGE" 2>/dev/null || true

sudo tar -C chroot -c . | docker import - "$ROOTFS_IMAGE"

docker rmi "$IMAGE" 2>/dev/null || true

if $install_base_pkgs; then
  cmd="echo Installing base packages && apt-get install -y parsec parsec-tests linux-astra-modules-common astra-safepolicy lsb-release acl perl-modules-5.28 ca-certificates"
else
  cmd="true"
fi

docker build --network=host --no-cache=true -t "$IMAGE" - <<EOF
FROM $ROOTFS_IMAGE
ENV TERM xterm-256color
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update
RUN $cmd
WORKDIR /
CMD bash
EOF

printf 'Docker image "%s" has been generated\n' "$IMAGE"
exit 0