Комментарии 11
Подскажите, а локальный NEXUS Sonatype Free для учебного класса как вариант не рассматривали?
Рассматривали. Nexus – нормальное решение для постоянного учебного класса: один раз поднял proxy/registry внутри контура, дальше он сам кеширует всё, что студенты тянут.
У нас сценарий немного другой. Стенд – не наш железный класс, а инсталляция, к которой безопасники отрубили интернет. Поднять отдельную ВМ под Nexus там значило бы:
согласовать новую сущность с теми же безопасниками
получить доступ к ней с учебных ВМ (а сеть обрублена)
поддерживать её актуальность
Образ-консерва дешевле политически и быстрее технически: один qcow2 раздать раз и забыть. А для регулярного класса с обновлениями – да, Nexus правильнее.
Пара советов:
Лучше ставить не docker а podman. Есть в обычном репе без шаманства.
Если уж ставить podman то можно выдать доступ не от рута, тогда каждый пользователь сможет запускать контейнеры на своём uid:gid диапазоне и (что важно) в своём home
Просто запуск nginx не очень объясняет цель такой виртуалки. Возможно вообще можно обойтись даже не podman а systemd-nspawn.
Сеть в podman так же изолируется из коробки:
podman network create \ --driver bridge \ --subnet 10.89.10.0/24 \ --internal \ isolated_netПо идее можно просто заменить default сеть
Зачем локальные пакеты nginx если он запускается в контейнере так и не понял.
Спасибо за развёрнутый коммент и разбор. Отвечу по пунктам:
1 и 2) podman + rootless – технически согласен, у меня самого на личных машинах так. У курса исторический хвост в последовательности рассматриваемых тем: методичка потока была написана под docker ..., менять рантайм только из-за одного учебного стенда – это переписывание методички, материалов и тестовых сценариев. При обновлении курса будем брать podman, без вопросов
3) systemd-nspawn – интересно, в моём списке кандидатов не было. В статье nginx – это демо-минимум, чтобы туториал влез в формат. В реальном образе курса наверху живёт k3s + Helm-чарты + предзагруженные образы для кластера, поэтому контейнерный рантайм нужен железно, а не как один nginx.
4)--internal – изящнее iptables'щины, согласен для случая «изолируем контейнерную сеть». У меня iptables решает дела чуть шире – заблокировать выход самого хоста наружу (через ens18), не только контейнеров. Если бы трафика хоста не было – пожалуй да, podman networking сам бы всё закрыл.
А по локальным пакетам – там два разных артефакта, легко спутать:
/opt/offline/docker_packages/*.deb— это сам docker.io + containerd + runc, чтобы установить рантайм без репозитория (Часть 1, «Скачиваем артефакты»)/opt/offline/nginx_offline.tar– а это уже образ nginx, грузитсяdocker loadна первом запуске.
То есть deb нужны для рантайма, а tar – для образа в нём.
а чем не подходит "docker image save"?
Базовый образ слишком мал для Docker-контейнеров. Добавляем 15 ГБ:
$ qemu-img resize offline_base.qcow2 +15G
Ну и как сделать expand the partition /dev/sda1 ? Не увидел решения в статье.
LC_ALL=C virt-filesystems -a offline_base.qcow2 --all --long -h
Name Type VFS Label MBR Size Parent
/dev/sda1 filesystem ext4 - - 2.8G -
/dev/sda14 filesystem unknown - - 3.0M -
/dev/sda15 filesystem vfat - - 124M -
/dev/sda1 partition - - - 2.9G /dev/sda
/dev/sda14 partition - - - 3.0M /dev/sda
/dev/sda15 partition - - - 124M /dev/sda
/dev/sda device - - - 3.0G -
###
qemu-img resize offline_base.qcow2 +15G
###
LC_ALL=C virt-filesystems -a offline_base.qcow2 --all --long -h
Name Type VFS Label MBR Size Parent
/dev/sda1 filesystem ext4 - - 2.8G -
/dev/sda14 filesystem unknown - - 3.0M -
/dev/sda15 filesystem vfat - - 124M -
/dev/sda1 partition - - - 2.9G /dev/sda
/dev/sda14 partition - - - 3.0M /dev/sda
/dev/sda15 partition - - - 124M /dev/sda
/dev/sda device - - - 18G -Справедливое замечание, в статье шага не показал – а зря.
Если коротко, то qemu-img resize ресайзит диск, но не файловую систему. В моём случае partition + ext4 растягиваются автоматически на первом boot'е – debian cloud image включает cloud-init модули growpart и resize_rootfs, они на первом старте до-растягивают root-партишен до размера диска (это видно в /etc/cloud/cloud.cfg)
Если cloud-init вырезан или не справился (может случиться на нестандартных образах), то руками можно так:
virt-resize --expand /dev/sda1 offline_base.qcow2 offline_base_expanded.qcow2virt-resize сам и сделает growpart, и resize2fs. Делается до virt-customize, потому что virt-customize ест файловую систему «как есть».
Альтернатива – в скрипте offline_setup.sh добавить шаг перед установкой docker:
growpart /dev/sda 1
resize2fs /dev/sda1Ну а мне стоит добавить этот шаг в апдейт статьи – спасибо, что внимательно прочитали
Спасибо за ответ. growpart в пакете cloud-guest-utils. Обычно пользуюсь qemu-nbd и parted с resize2fs для expand partition. После expand partition желательна проверка с e2fsck.

Про cloud-guest-utils – хорошая мысль, добавлю в апдейт, чтобы у читателя не было ребуса «а откуда брать growpart» (на свежем debian его действительно нет из коробки).
Про связку qemu-nbd + parted + resize2fs – это абсолютно рабочий путь, и в чем-то даже более гибкий: можно в том же подключении залезть внутрь ФС, посмотреть/поправить конфиги, что-то еще поделать. Я в статье выбрал virt-resize ровно из соображений «все одной командой и без модулей ядра», но ваш подход полезен тем, кто не хочет тащить libguestfs или хочет видеть каждый шаг явно. Имеет смысл упомянуть оба варианта в апдейте.
Ну и про e2fsck справедливо для ручного пути. virt-resize фактически сам прогоняет fsck в процессе ресайза, а вот при варианте growpart + resize2fs явная проверка через e2fsck -f (особенно, если образ уже запускался до) – это правильная страховка. Допишу и это.
Спасибо за статью.
Вопросы:
1. Почему не deb 13 - он же давно стабилен.
2. Для линукс на pve лучше использовать lxc - оно гораздо легче в плане накладных расходов.
P.s. Может чего пригодится (нужен квн) https://forum.netgate.com/topic/163435/proxmox-ceph-zfs-pfsense-и-все-все-все-часть-2
Как запечатать Docker в образ, которому не нужен интернет