Вдохновившись установкой FreeBSD на VPS, я решил поинтересоваться - а можно ли туда прикрутить Docker? Сначала я мыслил в сторону эмуляции Linux, но оказалось, что актуальному Докеру нужны cgroups, которых в эмуляции нет. Значит остаются только виртуальные машины. Родной гипервизор фряхи - bhyve, однако в уже виртуализированной FreeBSD (попробовал сначала в VirtualBox) нужные модули ядра скорее не загружаются. Таким образом, нужно реальное железо?..

Поставил систему на завалявшийся у меня внешний SSD, изготовленный самостоятельно из китайских комплектующих. Было немного страшно, когда установщик вывел список разделов на всех дисках (хотя я определенно выбирал для разбиения «флешку»), но, к счастью, ничего не затер. Для работы с виртуальной машиной понадобится окружение рабочего стола, какое же мы установим?.. scratch Ни за что не догадаетесь!

KDE

Пока что мы, конечно, в командной строке под root. Поехали:

pkg install kde5 sddm xorg firefox

Вроде обошелся без plasma5-sddm-kcm, да и некий периодически упоминаемый hald_service тоже уже не нужен как бы… Но при всем обилии устанавливаемых в рамках kde5 программ почему-то отсутствует браузер – предлагаю сразу установить Firefox (или какой-то другой, например попробовать konqueror).

Кстати вместо kde5 можно ограничиться лишь plasma5-plasma konsole remmina-lite, это будет минимальная установка +RDP/VNC клиент – скачивать примерно гигабайт вместо двух.

После установки – включить, поднастроить сервисы.

В /etc/rc.conf добавить:

dbus_enable="YES"
sddm_enable="YES"

В /etc/sysctl.conf добавить:

net.local.stream.recvspace=65536
net.local.stream.sendspace=65536

Какая установлена видеокарта?

pciconf -lv|grep -B4 VGA

Установить драйвера. В моем случае – для Radeon 5700XT – amdgpu (хотя какое-то firmware вроде установщик ОС ставил unknw):

pkg install drm-kmod
sysrc kld_list+=amdgpu

Если не создавали пользователя, то стоит создать сейчас – под root не пустит.

adduser

На этапе добавления групп предлагаю указать wheel (чтобы можно было делать su root в консоли) и video (требуется для работы xorg). Есть, конечно, подозрение, что надо бы еще и sudo установить и настроить, но для нашей задачи этого не потребовалось.

Если же пользователь есть, то добавляем его в нужные группы через pw:

pw groupmod video -m username

Вот теперь вроде бы можно перезагружаться и, если я ничего не упустил, насладиться окружением рабочего стола. Главное не забыть выбрать X11 в едва заметном поле выбора слева внизу, а то там Wayland может оказаться (вроде как такой вариант официально не поддерживается).

VirtualBox_FreeBSD Plasma_14_12_2024_15_59_18.png

Это скрин с виртуальной машины

vm-bhyve

Я думаю, работать с «голым» bhyve перебор даже для меня, так что установим простой менеджер. Тем более непонятно, как «в рукопашную» машины будут стартовать при загрузке ОС (в смысле не особо хочется заморачиваться еще и с написанием сервисов).

Подготовка

Как обычно, устанавливаем из пакетов:

pkg install vm-bhyve

Все-таки будем ориентироваться на UFS, поэтому просто создаем директорию. Включаем сервис и указываем ее в настройках:

mkdir /usr/local/vm
sysrc vm_enable="YES"
sysrc vm_dir="/usr/local/vm"

Инициализируем:

vm init

Хм, отрабатывает быстро и молча. Похоже просто создается несколько директорий и файлов в указанной vm_dir (согласно документации, еще включаются необходимые модули ядра). Далее предлагается скопировать шаблоны, но я не уверен, что стоит их прямо все копировать.

Собственно вопрос, а какой из Linux'ов взять? Сначала думал было Alpine из-за компактности, но наверное лучше будет взять Arch из-за системы rolling release и нашего любимого systemd (любимый ведь?.. Ну, если не нами, то так хотя бы Docker'ом). Плюс библиотеки там стандартные сишные (в Alpine musl – якобы на что-то может отрицательно влиять).

Так что скопируем шаблон для Arch Linux...

cp /usr/local/share/examples/vm-bhyve/arch.conf /usr/local/vm/.templates/

Или не копируем, потому что результат будет отличаться процентов на 50 – шаблон необходимо переделать. С самого начала нас встречает загрузчик grub. Нужный для его работы пакет grub2-bhyve какой-то уже подозрительный, поскольку за ним никто не присматривает. Предлагаю поменять загрузчик на uefi, соответственно удалить настройки grub из шаблона и разрешить использовать переменные UEFI (uefi_vars="yes").

Далее, если 1 ядро еще туда-сюда, то на 512 оперативки как будто в принципе ничего не работает (ошибки типа мало ресурсов или т.п. «синие экраны»). Так что делаем минимум гиг и включаем графику, поскольку иначе в консоли что-то дальше загрузочного меню ничего не происходит.

loader="uefi"
cpu=1
memory=1024M
network0_type="virtio-net"
network0_switch="public"
disk0_type="virtio-blk"
disk0_name="disk0.img"
uefi_vars="yes"
graphics="yes"
graphics_listen="127.0.0.1"

Соответственно для поддержки UEFI установим пакет:

pkg install bhyve-firmware

Скачиваем ISO, например с Яндекса:

vm iso https://mirror.yandex.ru/archlinux/iso/latest/archlinux-x86_64.iso

Если при запуске команд vm появляется ошибка ERROR: unable to load vmm.ko!, то скорее всего вы пытаетесь работать с bhyve в уже виртуализированной FreeBSD. smile

Создаем машину по шаблону с диском на 8 гигабайт:

vm create -t arch -s 8G arch

Разумеется, эти самые 8 гигабайт будут выделены сразу. С другой стороны, если есть возможность, лучше «подсыпать» этих самых гигов.

Виртуальная сеть

Предлагаю сразу же настроить локальный NAT и DHCP, чтобы назначать IP виртуальным машинам через него (я это сделаю в стиле VirtualBox). Итак, создаем сетевой мост:

vm switch create -a 192.168.56.1/24 public
vm switch add public re0

Соответственно public – имя моста (оно используется в настройках сети шаблона виртуальной машины), а re0 – ваш основной сетевой интерфейс (можно проверить ifconfig'ом, обычно в инструкциях пишут em0, но у меня вот на сей раз re0).

Включаем pf:

sysrc pf_enable=YES
sysrc gateway_enable=YES

Файл /etc/pf.conf – вот прямо без ничего, один только NAT:

nat on re0 from {192.168.56.0/24} to any -> (re0)

Конечно, в идеале бы настроить все как следует, но это, как говорится, выходит за рамки статьи. В каком-то виде я настраивал pf для веб-сервера.

Что касается DHCP, то авторы vm-bhyve пользуются dnsmasq, хотя во FreeBSD условно стандартным является isc-dhcp44-server (по крайней мере описывается в руководстве). Давайте я все же настрою «штатный»:

pkg install isc-dhcp44-server
sysrc dhcpd_enable="YES"
sysrc dhcpd_ifaces="vm-public"

Редактируем /usr/local/etc/dhcpd.conf. В нем изначально много всего лишнего, поэтому комментируем (или удаляем) все примерно начиная с log-facility local7;. Формируем собственную конфигурацию:

#option domain-name "example.org";
option domain-name-servers 77.88.8.8, 77.88.8.1;

# значения по умолчанию
default-lease-time 600;
max-lease-time 7200;

# подсеть в стиле VirtualBox
subnet 192.168.56.0 netmask 255.255.255.0 {
  range 192.168.56.101 192.168.56.254;
  option routers 192.168.56.1;
}

# фиксированный ip для виртуалки Arch Linux
host arch {
  hardware ethernet 58:9c:fc:0d:7a:81;
  fixed-address 192.168.56.10;
}

С option domain-name толком непонятно, что делать, так что решил закомментировать ее вовсе. Серверы имен пусть будут Яндексовские, а MAC-адрес сетевого адаптера виртуальной машины смотрим в /usr/local/vm/arch/arch.conf (у меня, соответственно, 58:9c:fc:0d:7a:81).

Запустим, наверное, сразу (хотя возможно лучше перезагрузить всю FreeBSD):

service pf start
service isc-dhcpd start

По идее теперь можно приступать к установке.

Установка Arch Linux

Запускаем виртуальную машину в режиме загрузки с образа диска:

vm install arch archlinux-x86_64.iso

И подключаемся к ней по VNC на присвоенный порт – проверить через vm list (скорее всего это будет 5900).

По секрету скажу, что первоначально я очень сильно намучился с KRDP (поскольку он входит в полную установку KDE), в частности с захватом клавиш. Поэтому рекомендую воспользоваться другим клиентом, например Remmina. Там, конечно, тоже все немного странно, но хотя бы есть глубоко запрятанная возможность отправить содержимое буфера обмена в виде нажатий клавиш (результат впрочем тоже может удивить). Хорошо хоть захват этих самых клавиш работает как положено – если окно активно, значит печатаем в виртуальной машине, а нет – значит нет.

Итак, система, я надеюсь, загружена, и в первую очередь нас интересует, добились ли мы нужного эффекта настройкой виртуальной сети:

ip addr
ping -c2 freebsd.org

О, да! IP-адрес сетевому адаптеру назначен, DNS работает, пинг «вовне» идет.

remmina_Arch_Linux_5900_20241218-130141.png

Что ж, можем устанавливать. Специально ради этого wink я написал статью, правда там фигурирует VirtualBox в качестве гипервизора, так что будут незначительные нюансы. Поэтому здесь приведу «скрипт» установки практически без пояснений.

Разрешаем подключение по SSH:

echo 'PermitRootLogin Yes' >> /etc/ssh/sshd_config
passwd
systemctl restart sshd

Размечаем диск, например, через fdisk:

fdisk -l
fdisk /dev/vda

Схема:

Device       Start      End  Sectors Size Type
/dev/vda1     2048  2099199  2097152   1G EFI System
/dev/vda2  2099200  4196351  2097152   1G Linux swap
/dev/vda3  4196352 16775167 12578816   6G Linux root (x86-64)

Продолжаем установку:

mkfs.fat -F 32 /dev/vda1
mkswap /dev/vda2
mkfs.btrfs /dev/vda3
mount -o compress=zstd /dev/vda3 /mnt
mount --mkdir /dev/vda1 /mnt/boot
swapon /dev/vda2
pacstrap -K /mnt base linux btrfs-progs nano efibootmgr openssh
genfstab -U /mnt >> /mnt/etc/fstab
arch-chroot /mnt
ln -sf /usr/share/zoneinfo/UTC /etc/localtime
hwclock --systohc

Внимательный читатель обратил внимание, что для корневой файловой системы я влупиул btrfs с компрессией для экономии места. UUID ФС в моем случае a0769764-52c5-4282-b63e-274747c1f76e. Ну и UTC пусть часовым поясом будет. Далее необходимо отредактировать /etc/locale.gen – раскомментировать en_US.UTF-8 UTF-8 и заодно ru_RU.UTF-8 UTF-8.

Далее:

locale-gen
echo 'LANG=en_US.UTF-8' > /etc/locale.conf
echo 'arch-vm' > /etc/hostname
efibootmgr --create --disk /dev/vda --part 1 --label "Arch Linux" --loader /vmlinuz-linux --unicode 'root=UUID=a0769764-52c5-4282-b63e-274747c1f76e rw initrd=\initramfs-linux.img'
systemctl enable sshd
echo 'PermitRootLogin Yes' >> /etc/ssh/sshd_config
systemctl enable systemd-networkd
systemctl enable systemd-resolved

Создадим файл настройки сети, например /etc/systemd/network/10-wired.network:

[Match]
Name=enp0s5

[Link]
RequiredForOnline=routable

[Network]
DHCP=yes

Устанавливаем пароль root, выходим из chroot и выключаем машину:

passwd
exit
poweroff

Запускаем виртуалку в обычном режиме:

vm start arch

Если все в порядке (проверяем подключениями по VNC и SSH), то ставим ее в «автозапуск»:

sysrc vm_list=arch

That's it!

Docker

Общая папка

vm-bhyve предлагает для этого VirtIO 9p. Что ж… Вероятно сначала надо бы машину выключить. В стиле Arch Linux на хосте создадим каталог /srv/docker и добавим диск в настройки («вручную» редактируем /usr/local/vm/arch/arch.conf или vm configure arch):

disk1_type="virtio-9p"
disk1_name="docker=/srv/docker"
disk1_dev="custom"

Запускаем Arch Linux и пробуем смонтировать:

mount --mkdir -t 9p -o trans=virtio docker /srv/docker

Внезапно получилось без установки каких-либо дополнительных пакетов. Проверяем создание файлов там и сям – все работает, права доступа и пользователь по умолчанию (644 root:wheel на хосте и 644 root:root в гостевой ОС). Но в целом права вроде бы транслируются.

Монтируем на постоянной основе – добавляем запись в /etc/fstab (в Arch Linux):

# shared directory
docker  /srv/docker     9p      trans=virtio,rw   0       0

Перезагружаем Arch Linux или перемонтируем:

umount /srv/docker
systemctl daemon-reload
mount /srv/docker

Переходим к установке Docker.

Установка в Arch Linux

Здесь все точно так же, как и в ранее упомянутой статье. Установка из пакетов:

pacman -S docker docker-compose docker-buildx

У нас btrfs, поэтому сначала создадим подтом:

btrfs subvolume create /var/lib/docker

Скорее всего каталога /etc/docker еще нет, поэтому создадим его (mkdir /etc/docker) и добавим файл /etc/docker/daemon.json для использования нужного нам драйвера хранилища:

{
  "storage-driver": "btrfs"
}

Запускаемся:

systemctl enable --now docker

Как обычно, проверить установку можно командами docker info и/или docker run hello-world.

Клиент во FreeBSD

Устанавливаем клиента на хост:

pkg install docker

Что-то старый какой-то (18-й) и опять-таки беспризорный. Ладно, на что-нибудь наверное сгодится. Но как мы получим доступ с хоста к сокету Докера в виртуальной машине? С помощью туннеля SSH.

Под пользователем, который будет работать с клиентом докера, генерируем ключ SSH и добавляем его в authorized_keys в Arch Linux:

ssh-keygen
cat ~/.ssh/id_rsa.pub | ssh root@192.168.56.10 "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"

Чтобы каждый раз не указывать хост, добавим в ~/.cshrc (при условии, что оболочка csh):

setenv  DOCKER_HOST     ssh://root@192.168.56.10

Перезайдем в консоль и проверим:

docker info

Должна быть выведена информация, аналогичная Arch Linux.

Пример

Начинаем делать под root на хосте (FreeBSD). Добавим пользователя с uid и gid 33, пусть называется как в Docker – www-data:

pw useradd www-data -u 33 -d /nonexistent -s /usr/sbin/nologin -c 'Docker Web user'

Создадим каталог /srv/docker/html, а в нем простейший файл index.php:

<?php phpinfo(); ?>

Меняем владельца:

chown -R www-data:www-data /srv/docker/html

Если клиент докера настроен под другим пользователем, то переключаемся в его консоль и:

cd /srv/docker/html
docker run -d -p 80:80 --name web -v "$PWD":/var/www/html php:8.4-apache

Проброс текущей директории $PWD возможен благодаря одинаковым путям во FreeBSD и Arch Linux. Ждем, пока скачается образ и запустится контейнер, после чего заходим «по IP». Должны отобразиться сведения о PHP.

Screenshot_20241218_203624.png

Для приличия останавливаем и удаляем контейнер.

docker stop web
docker container rm web

К сожалению, docker compose есть только непосредственно в Arch Linux (думаю сверхустаревший docker-compose 1.x рассматривать не стоит). К счастью, работать с файлами можно с хоста.

Заключение

По сравнению с VirtualBox, где можно «натыкать» конфигурацию мышкой и в немалой степени все уже сделано за нас, работа с bhyve потребует довольно длительной настройки (во всяком случае виртуальной сети). Как говорится, долго запрягать, зато потом… Кстати мне наоборот понравилось, что vm-bhyve в актуальных версиях не навязывает каких-то конкретных настроек NAT и DHCP, да и по VNC к виртуальной машине можно подключаться любым клиентом. Еще один плюс – заработавшая «из коробки» 9p с нормальной работой файловых прав доступа.

Но виртуальную машину bhyve нельзя так просто взять и запустить на VDS/VPS – на одном из них все «отвалилось» уже на этапе vm init, зато на другом внезапно запустилась. В целом система больше актуальна для рабочей станции или выделенного сервера. В этом случае можно посмотреть более продвинутый менеджер – CBSD. Кстати тамошняя статья про Docker (к сожалению, устаревшая) тоже в немалой степени сподвигла на данный эксперимент.


Категория: Программирование, веб | Опубликовано 12.06.2025 | Редакция от 05.07.2025

Похожие материалы

Веб-сервер на FreeBSD с использованием клеток

Здесь вам не Докер, а клетки (jails) - будем говорить, это контейнеры FreeBSD, когда это еще не было мейнстримом (на минуточку, они появились еще во FreeBSD 4.x - 2000 год). Практический смысл в моем случае - неким образом изолированно использовать разные версии PHP, ну и чуть ближе познакомиться с технологией, с которой я уже сталкивался при обзоре TrueNAS. Основано, как говорится, на реальных событиях - я переносил сайты на Drupal 7.x и Yii с сервера на Linux.

FreeBSD на VPS

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


Комментарии, обсуждение