Причина написания
Где-то в конце лета 2025-ого я собирал NAS-сервер. Чисто для себя, под свои нужды и хотелки, и совершенно не планировал что-то публично описывать. Всю необходимую информацию искал через google, а тот раз-через-раз в результатах поиска подкидывал вот эту статью:
Я долго проходил мимо этой ссылки, ибо сам заголовок вызывал массу вопросов, и почему-то казалось, что несогласие с автором заставит меня написать что-то в ответ. Так и получилось после прочтения. Я зачем-то зарегистрировался на Хабре и пишу эти буквы.
Основная «претензия» к статье в том, что в OmniOS нет ничего «хардкорного». Это довольно простая в понимании, логичная и устойчивая ОС. Но, да, к инструментарию нужно привыкнуть и усвоить логику взаимодействий.
Статья будет посвящена не только OmniOS, нои другим «деткам» illumos, таким как OpenIndiana, Tribbix и SmartOS, поскольку всё написанное можно приложить к любому из этих дистрибутивов. А так же тому, как это можно использовать, и что из этого может получиться. SmartOS например, достоин отдельной серии статей вместе с Triton DataCenter. Однако, пока ограничусь только этим личным проектом на OmniOS.
Начало
Итак, стартовой точкой было желание получить домашний NAS. У меня не было «железа», которое можно было пустить на строительство. Готовые решения от Synology, QNAP и пр. — дорого и универсальностью они откровенно не блещут. Стало быть остался один вариант — собрать из тех компонентов, которые можно купить на маркетплейсах за приемлемые деньги.
Дабы не распространять "рекламные материалы" ограничусь характеристиками железа:
Intel N150 (4 core)
RAM: 32 Гб
NVMe: 512 Гб
HDD: 5 x 4 Тб
+ корпус, блок питания и п.р.

Выбор ОС был сделан осознанно. Ранее мне приходилось иметь дело с Solaris и ZFS, и именно этот опыт подсказывал, что только так у меня получится "не упарываясь" собрать конструкцию, которая удовлетворит мои хотелки. Я знал, что в OmniOS есть:
Зоны - Механизм изоляции процессов, отдаленно схожий одновременно с LXC и KVM
Crossbow - SDN для построения сетей между зонами и внешним миром
ZFS в авторской редакции
И буду честным, я не ожидал, что в результате получится "микро-облако". В котором спокойно будут жить: маршрутизатор, NAS и несколько виртуальных машин.
Зоны
Во-первых - это способ изоляции процессов. Во-вторых - это способ диспетчеризации ресурсов CPU и RAM.

Если прочие, не-глобальные зоны в системе отсутствуют, то процессы будут работать в глобальной зоне. Эта зона воспринимается как "основная операционная система", однако это не совсем так. У всех зон, включая глобальную, первым процессом является "ресурсыный планировщик". Для глобальной зоны его PID равен нулю, а имя процесса 'sched'. Такой же "планировщик", с именем процесса 'zsched' предваряет процессы не-глобальных зон. Процессы 'sched' и 'zsched' порождаются непосредственно ядром, и являются "прослойкой" между ядром и зоной. Что делает все зоны практически равными между собой, и позволяет использовать все ресурсы хост-машины на конкурентной основе. Т.е. "глобальная зона" такая же зона как все остальные, но обладающая возможность "порождать" другие зоны. CPU, RAM, диски, устройства шины PCI контролируются общим ядром. Изначально "принадлежат" глобальной зоне, но могут быть "переданы" в не-глобальные.
Каждая зона имеет идентификатор (ID). У глобальной зоны ID=0, у не-глобальных ID больше нуля. Наличие такого идентификатор позволяет ядру различать процессы и сегменты памяти разных зон и изолировать данные между ними. Можно провести параллель с VRF в маршрутизаторах Cisco, логика весьма схожая.
Конкуренция за внимание, к той или иной зоне со стороны CPU - регулируемая. Есть специальная утилита - dispadmin
# Список политик диспетчеризации задач разных зон $ dispadmin -l CONFIGURED CLASSES ================== SYS (System Class) TS (Time Sharing) SDC (System Duty-Cycle Class) FSS (Fair Share) FX (Fixed Priority) # Установка политики диспетчеризации по-умолчанию. $ pfexec dispadmin -d FSS
Управление зонами
Зоны управляются двумя основными утилитами:
zoneadm
Запускает, останавливает, проверяет и т.д. В общем, отвечает за административную составляющую.
zonecfg
Создает и изменяет конфигурационные файлы, которые в дальнейшем использует zoneadm
Нельзя сказать, что эти утилиты сложны в обращении, однако количество повторяющихся, и в тоже время обязательных при использовании директив мотивировало сообщество на создание программ-прокладок, упрощающих их использование. В OmniOS такая программа называется 'zadm'.
Устанавливается через менеджер ПО 'pkg':
$ pfexec pkg install zadm
Типы зон
OmniOS в общей сложности умеет создавать 11 типов зон, или как это принято называть в терминологии illumos - брендов (brand). Зоны разных брендов обладают разными свойствами, приведу несколько примеров:
brand: ipkg, lipkg, spare
Это три бренда для создания нативной зоны, т.е. отдельно существующей инсталляции OmniOS. Отличаются они между собой способами сопровождения установленного через утилиту 'pkg' ПО.
ipkg - Independent management. Все пакеты устанавливаются внутри зоны независимо от глобальной зоны.
lipkg - Linked Image Package. Пакеты установленные в глобальной зоне автоматически устанавливаются в не-глобальную зону данного бренда.
spare - То же, что и бренд 'lipkg', но пакеты установленные в глобальной зоне не устанавливаются внутри зоны, а создаются ссылки на файлы установленных пакетов. Это позволяет экономить место на диске. При этом часть директорий базовой файловой системы (/bin, /sbin, /usr, /lib...) в зоне 'spare' будут read-only.
brand: lx
Если вы знакомы с Canonical LXD, то легко поймете принцип работы зоны бренда LX. Это контейнер в котором работает один из дистрибутивов Linux. Однако, в отличии от LXD/LXC в LX-зоне нет Linux-ядра. Все бинарники запускаются в режиме эмуляции, как в FreeBSD linuxemu.
brand: BHYVE, KVM
Два бренда зон с гипервизорами - bhyve и KVM+qemu. Предназначены для запуска других операционных систем в режиме классической виртуальный машины. Стоить отметить, что способ виртуализации через KVM+qemu внутри сообщества illumos в настоящее время отмирает. Основной применяемый гипервизор - это bhyve.
$ zadm NAME STATUS BRAND RAM CPUS SHARES global running ipkg 32G 4 20 AnyHole running lx - - 1 Immich running bhyve 4G 4 1 OPNsense26 running bhyve 2G 1 15 Torrent running lx - - 1
Crossbow
Так назывался проект программно-определяемых сетей (SDN) компании Sun Microsystems. С помощью SDN можно создавать виртуальные сетевые карты (vNIC), ethernet-хабы, коммутаторы, бриджи, оверлеи, и т.д. А так же связывать элементы между собой в нужную сетевую структуру.

На диаграмме выше показаны основные сущности SDN Crossbow и их возможные взаимосвязи.
От физических портов могут быть образованы виртуальные сетевые интерфейсы VNIC и VLAN. При этом интерфейсу VNIC может быть задан тег, что делает его практически эквивалентным интерфейсу VLAN. Так же, физические интерфейсы могут быть включены в бридж. В OmniOS бридж - это системный сервис, в отличии от Linux и FreeBSD, где бридж - это специальный сетевой интерфейс. Заставить бридж работать в OmniOS у меня не получилось. Он упорно не захотел делать то, что от него требовалось.
Etherstub - это Ethernet-хаб. Не коммутатор, а именно хаб. Все фреймы поступающие в него видны всем подключенным к нему VNIC-ам. Физические интерфейсы подключить напрямую к Etherstub нельзя, однако можно связать друг с другом Etherstub и Bridge.
VNIC и VLAN - это окончательные сетевые интерфейсы, от которых невозможно построить связи с другими элементами SDN. Они могут быть либо переданы в не-глобальную зону, либо стать интерфейсами глобальной зоны. Количество VNIC создаваемых от одного физического порта ничем не ограничено, т.е. можно образовать несколько VNIC в одном VLAN-е и распределить их по разным зонам. Физический порт в этом случае будет работать как коммутатор.
Управление элементами SDN осуществляется утилитой dladm.
Примеры:
# Создание VNIC с именем 'inet0' и заданным мак-адресом на базе физического порта igc3 $ pfexec dladm create-vnic -l igc3 -m 30:e4:db:f4:24:56 inet0 # Создание VNIC с именем 'vnic_vlan30' и PVID=30 на базе физического порта igc1. # Мак-адрес будет "случайным". $ pfexec dladm create-vnic -l igc1 -v 30 vnic_vlan30 # Создание хаба Etherstub $ pfexec dladm create-etherstub Hub0
Как можно заметить, имена элементов SDN должны быть уникальными и заканчиваться числом, в противном случае система выдаст ошибку:
$ pfexec dladm create-vnic -l igc0 wrong_name dladm: invalid link name 'wrong_name'
Исключением из этого правила является создание бриджа, там наоборот имя не должно заканчиваться числом, оно добавляется автоматически.
Все изменения dladm делает перманентными. Созданные виртуальные интерфейсы останутся в системе после ребута. Временные изменения можно сделать через добавление ключа '-t', что позволяет "откатить" совершенные операции через перезагрузку системы.
На этом краткий, сумбурный экскурс в инструментарий ОС Solaris заканчивается. В действительности тема колоссальных объемов, со своими тонкостями и нюансами, тем не менее базируется на простых постулатах, которые легко понять.
Проект "Амбар"

Представленная схема на первый взгляд слабо сочетается с фразой "не упарываясь" написанной ранее. Просто по мере вхождения во вкус было перепробовано около десятка вариантов. Как говорится, "коготок увяз - всей птичке пропасть"...
NAS
Функцию NAS выполняет глобальная зона OmniOS. Для управления дисковым пулом и SMB-шарами предполагалось использование napp-it. Однако, в дальнейшем от него пришлось отказаться и перейти на управление вручную, командами из командной строки. Причины таковы:
Napp-it - это "фримиум". Часть функционала перестает работать после 30 дней использования. К "отваливающимся" функциям относятся: мониторинг, ACL-ы ZFS и еще что-то из разряда "визуализации".
Нет возможности создать SMB-шару на русском языке. Все названия только латиницей.
Нет возможности создать SMB-шару существующего каталога, только ZFS-dataset.
Еще, скрипт инсталляции Napp-it установил какое-то безумное количество софта, которое ему для работы совершенно не нужно, а мне и подавно. Точного списка установленных пакетов у меня нет, его нужно восстанавливать из скрипта, так что с этим еще предстоит разобраться. Все равно, napp-it крайне полезен на начальном этапе, и в его коде можно найти очень и очень много подсказок.
Несколько слов о глобальных настройках ZFS, которые я сделал практически сразу после создания ZFS-пула:
Ограничение размера Adaptive Replacement Cache (ARC). По-умолчанию размер ARC вычисляется автоматически, и в результате такового может составить от 50% до 100% оперативной памяти. Самый простой способ - добавить в файл /etc/system строку:
set zfs:zfs_arc_max = 8589934592
Где 8589934592 = 8 * 1024^3, т.е. 8 гигабайт. Для домашнего файлового сервера, учитывая интенсивность использования, это очень большая величина. Можно при необходимости сократить до 4-х или до 2-х гигабайт.
Добавление SLOG в ZFS-пул шпиндельных дисков. ZFS Separate Log Device позволяет увеличить производительность операций записи на диски. В качестве SLOG-диска можно использовать ZFS-dataset на памяти NVMe. OmniOS устанавливался на него, и там образовался 'root-pool', можно откусить немного.
# # Создаем volume dataset # $ pfexec zfs create -V 5G rpool/SLOG $ zfs list rpool/SLOG NAME USED AVAIL REFER MOUNTPOINT rpool/SLOG 5,16G 373G 12K - # # Добавляем созданный том, как log-device в существующий ZFS-пул # $ pfexec zpool add TANK log /dev/zvol/dsk/rpool/SLOG # # Смотрим результат # $ zpool status TANK pool: TANK state: ONLINE scan: scrub repaired 0B in 0 days 00:26:32 with 0 errors on Tue Dec 2 23:42:13 2025 config: NAME STATE READ WRITE CKSUM TANK ONLINE 0 0 0 raidz1-0 ONLINE 0 0 0 c4t0d0 ONLINE 0 0 0 c5t0d0 ONLINE 0 0 0 c5t1d0 ONLINE 0 0 0 c5t2d0 ONLINE 0 0 0 c5t3d0 ONLINE 0 0 0 logs /dev/zvol/dsk/rpool/slog ONLINE 0 0 0 /dev/zvol/dsk/rpool/SLOG ONLINE 0 0 0 errors: No known data errors # # Поскольку это пример, и в двух SLOG-дисках необходимости нет - удаляем. :) # # Вначале из пула # $ pfexec zpool remove TANK /dev/zvol/dsk/rpool/SLOG # # Теперь уничтожаем лишний dataset # $ pfexec zfs destroy rpool/SLOG
SMB-шара по-русски
Прежде чем раскрывать данный вопрос хочется сказать, что протокол SMB в SunOS - это часть ядра системы. Нет необходимости устанавливать дополнительные пакеты ПО. Более того, за счет взаимной интеграции ZFS с SMB и NFS управлять "расшариванием" можно через редактирования параметров dataset-ов.
Вот пример:
# # Создаем dataset. # $ pfexec zfs create TANK/Hello_Habr # # По-умолчанию SMB отключен. # $ zfs get -p sharesmb TANK/Hello_Habr NAME PROPERTY VALUE SOURCE TANK/Hello_Habr sharesmb off default # # Включаем "расшаривание" и задаём имя на русском. # $ pfexec zfs set sharesmb=name="Привет Хабр!" TANK/Hello_Habr # # Проверяем... # $ zfs get -p sharesmb TANK/Hello_Habr NAME PROPERTY VALUE SOURCE TANK/Hello_Habr sharesmb name=Привет Хабр! local

Маршрутизатор
Настройка этой функции отняла пожалуй больше всего времени. Однако, тема данной статьи к этой увлекательной истории отношения не имеет. В конце концов в зоне маршрутизатора поселился OPNsense. Зоне доступно одно ядро CPU, 2 Гб памяти и диск 10 Гб.

На маршрутизаторе лежат функции: DNS-сервера, DHCP-сервера, файрвола как интернет-трафика, так трафика между сегментами внутренней сети, "Call-Home VPN" сервера и Reverse-Proxy сервера.
Заключение
OmniOS — мощная и надежная операционная система. Благодаря этой технологии я получил свое собственное микро‑облако. Ресурсов у хост‑машины откровенно мало, но даже при таких условиях удалось собрать отлично работающее решение.
К недостаткам можно отнести отсутствие веб‑морды с модным управлением «на кнопках», но если откровенно, мне, как человеку до сих пор редактирующему текстовые файлы в редакторе 'vi', это обстоятельство ничуть не мешает. И да, недостаток отсутствия «интуитивно понятного» интерфейса тоже легко исправим, было бы желание. Но я не умею кодировать фронтенд, к сожалению.
Хочу поблагодарить всех, кто дочитал эту «простыню» до конца. Искренне надеюсь, что было интересно. Даже несмотря на рваное, с пробелами повествование.
