![](https://habrastorage.org/webt/8k/s3/9w/8ks39w0gz0n-8or4mmdjvmvvkq0.png)
Привет, Хабр! Меня зовут Ярослав, я стажер инженерно-технического отдела в Selectel. В своих пет-проектах уже давно использую роутеры MikroTik. Но я никогда думал, что на них станет возможным развернуть Docker. Релиз стабильной версии RouterOS 7.5 изменил мое мнение: теперь MikroTik поддерживает контейнеризацию.
На примере Nextcloud показываю, как установить и настроить приложение в контейнере, и рассказываю, с какими ограничениями можно столкнуться. Подробности под катом.
Начнем с ограничений
Не каждый MikroTik поддерживает контейнеры
К сожалению, функционал поддерживается не на всех роутерах. Контейнер можно запустить только на устройстве с архитектурой ARM, ARM64 или x86. Из беспроводных роутеров можно использовать MikroTik линейки Chateau и некоторые hAP-модели. Из проводных — RB1100AHx4 Dude Edition, RB3011 и RB5009. А также — новые роутеры линейки CCR (CCR2004-16G-2S+, CCR2116-12G-4S+, CCR2216-1G-12XS-2XQ).
С полным списком моделей и их архитектурами можно ознакомиться тут.
Архитектуру x86 поддерживают программные роутеры CHR, которые могут быть установлены на сервер или виртуальную машину с соответствующим процессором.
Если у вас есть сервер, можно установить на него любую систему виртуализации создать несколько виртуальных машин. На одной из них — развернуть образ программного роутера CHR Mikrotik, а на другой — серверную операционную систему с Docker или нужным ПО.
В этом случае нет необходимости ставить контейнеры внутрь RouterOS. На мой взгляд этот способ является более стабильным и функциональным решением. Но есть одна особенность: установить контейнер RouterOS может быть быстрее, чем разворачивать систему виртуализации. К тому же она может потребовать дополнительного лицензирования.
Если вы знаете, для чего может понадобиться контейнеризации на CHR, поделитесь опытом в комментариях.
Контейнер ограничен характеристиками роутера
У аппаратных роутеров достаточно жесткие ограничения по оперативной памяти. Объем ОЗУ на роутерах, за исключением линейки CCR, не превышает 1 ГБ. И если, например, половину объема оставить под нужды RouterOS, контейнер с приложением будут сильно ограничены в памяти.
С ресурсами процессора ситуация не лучше. Для примера: приложение Nextcloud, которое я развернул на роутере RB3011, загрузило оба ядра на 100% — и это без какой-либо нагрузки.
![](https://habrastorage.org/webt/dz/gf/0c/dzgf0canoc5qfbxzrlrzqilrmoi.png)
Окно Resources, состояние процессорных ядер.
Также можно столкнуться с ограничениями по объему памяти флеш-накопителя. Его вместимость не превышает 128 МБ, за исключением накопителя в роутере RB5009. Поэтому память лучше оставить исключительно для хранения конфигураций. А для работы контейнера и хранения примонтированных каталогов использовать внешний накопитель.
Некоторые модели имеют SATA- и M.2-разъемы для подключения внешних накопителей. Если таких разъемов нет, можно воспользоваться USB и подключить флешку.
Риски использования
Немаловажна и безопасность: нужно понимать, что, если роутер будет скомпрометирован, злоумышленники могут загрузить любое вредоносное ПО в контейнере. Это может привести к чему угодно, если роутер включен в домашнюю или корпоративную сеть.
Подробнее со всеми рисками можно ознакомиться на официальном сайте.
MikroTik снимает с себя ответственность за безопасность RouterOS с установленными контейнерами. Поэтому нужно быть уверенным, что используемое ПО не содержит уязвимостей.
![](https://habrastorage.org/webt/1k/7b/to/1k7bto4ll6kmlckzsvnaox4oupc.png)
Подготовка роутера к установке контейнеров
Я уже говорил, что к аппаратному роутеру нужно подключить дополнительный накопитель. Кроме того, нужно обновить систему RouterOS до stable-версии 7.5 или выше, а потом — RouterBOARD. Но это не все, что понадобится.
Каждый из последующих этапов можно выполнить через графический интерфейс RouterOS или командную строку.
Форматирование диска
Предварительно нужно отформатировать накопитель для работы с файловой системой ext3/ext4: нужно выбрать новый накопитель и нажать Format Drive.
![](https://habrastorage.org/webt/kw/kh/3h/kwkh3hmbpjk8i40ukeu1relfrem.png)
Окно Format Drive, настройка форматирования диска.
/disk/print
Flags: M, r - RAID-MEMBER; p - PARTITION
Columns: SLOT, MODEL, SERIAL, INTERFACE, NAME
# SLOT MODEL SERIAL INTERFACE NAME
0 usb1 JetFlash Mass Storage Device CCYYMMDDHHmmSSECGXE8 USB 2.10 480Mbps
1 Mp usb1-part1
/disk/format-drive usb1 file-system=ext4
Настройка форматирования диска.
usb1 — имя накопителя, полученное командой /disk/print
Установка дополнительного пакета для работы с контейнерами
На официальном сайте в разделе Software нужно найти блок с архитектурой процессора используемого роутера. А после — скачать архив Extra packages. В нем должен быть файл container, который нужно переместить в Winbox, в окно File.
![](https://habrastorage.org/webt/wq/7k/ju/wq7kjug0pgh6lvcmnbixbfjb-z0.png)
Содержание архива Extra packages.
![](https://habrastorage.org/webt/up/xi/_k/upxi_kw9u1qno0nfqzewnes1ezm.png)
Файловая система Winbox.
Для установки пакета необходимо перезагрузить роутер.
Активация функционала контейнеров
Последний этап подготовки — активация функционала контейнеров. В терминале RouterOS нужно ввести специальную команду.
/system/device-mode/update container=yes
update: please activate by turning power off or pressing reset or mode button in 4m53s
-- [Q quit|D dump|C-z pause]
После сообщения нужно в течение 5 минут перезагрузить роутер, то есть выключить и включить его по питанию, либо нажать на кнопку reset или mode.
Установка образа контейнера с Docker Hub
Создание виртуального сетевого интерфейса
В разделе Interface → VETH нужно создать виртуальный сетевой интерфейс для будущего контейнера. Для этого нужно настроить несколько параметров:
- Name — название сетевого интерфейса,
- Address — IP-адрес и битовая маска подсети для контейнера. По данному адресу можно будет подключиться к контейнеру,
- Gateway — IP-адрес, который контейнер будет использовать в качестве шлюза для работы с устройствами в других подсетях.
![](https://habrastorage.org/webt/u8/tm/ju/u8tmjumbuwlfdcd-jvelitfgwdi.png)
Окно VETH, создание виртуального сетевого интерфейса.
/interface/veth/add name=veth3 address=10.10.4.4/24 gateway=10.10.4.1
Создание виртуального сетевого интерфейса VETH.
Для включения контейнера в сеть можно создать «виртуальный коммутатор» bridge, назначить ему IP-адрес и добавить в него виртуальный интерфейс.
/interface/bridge/add name=container-bridge
/ip/address/add address=10.10.4.1/24 interface=container-bridge
/interface/bridge/port/add bridge=container-bridge interface=veth3
Создание виртуального коммутатора для контейнеров и его настройка.
На самом деле, в bridge добавлять интерфейс не обязательно — его можно использовать отдельно, настроив, например, соединение point-to-point.
/interface/veth/add name=veth4 address=10.10.5.2/30 gateway=10.10.5.1
/ip/address/add address=10.10.5.1/30 interface=veth4
Назначение IP-адресов на PtP-интерфейс.
Я заметил особенность поведения RouterOS: при смене IP для виртуального сетевого интерфейса VETH, внутри самого контейнера адрес не обновляется. По поводу этой проблемы я создал тему на форуме MikroTik.
Конфигурирование контейнера
Далее нужно перейти в раздел Container → Config и настроить несколько параметров:
- RAM Hight — опциональный параметр, ограничивает контейнеры в потреблении оперативной памяти,
- Registry URL — адрес, с которого будет устанавливаться контейнер при запуске (для загрузки образа с Docker Hub нужно ввести registry-1.docker.io),
- Tmp dir — путь до директории, куда будут перемещены временные файлы, необходимые для установки контейнера. Рекомендую располагать директорию на дополнительном накопителе (disk2).
![](https://habrastorage.org/webt/jn/vq/rk/jnvqrkjyl9jw4gsymj92imezipy.png)
Окно Config, конфигурирование контейнера.
/container/config/set ram-high=768M registry-url=https://registry-1.docker.io tmpdir=disk2/tmp
Конфигурирование контейнера через консоль.
Особенности конфигурирования
Во время работы с Container → Config нужно учитывать ряд особенностей:
- При заполнении RAM High через Winbox неочевидно, в каких единицах нужно вводить значение. Нельзя использовать упрощенную модель — например, 768M, когда буква обозначает единицу измерения (килобайты, мегабайты, гигабайты). Объем необходимо указывать в байтах. Хотя в терминале подобная запись работает.
-
При установке контейнера в RouterOS все приложения из каталога монтирования — например, Nextcloud (/var/www/html) — отображаются сплошным списком, без соблюдения иерархии директорий. Это сильно затормаживает загрузку раздела File и вызывает неудобства в использовании. Например, после установки контейнера с Nextcloud в разделе File появляется около 46 000 строк, которые загружаются больше минуты.
- Вторая особенность вызывает неудобства и в работе с терминалом. Когда в системе содержится большое количество файлов, при настройке конфигурации контейнеров RouterOS не дает ввести путь до директории для временных файлов (tmpdir). Возможно, это происходит из-за долгой индексации файлов во время проверки системой вводимых команд.
Возможно, эти тексты тоже вас заинтересуют:
→ Домашний дата-центр: ошибки, результаты и советы
→ ML в Managed Kubernetes: для каких задач нужен кластер с GPU
→ Docker Swarm VS Kubernetes — как бизнес выбирает оркестраторы
Настройка и запуск контейнера с Nextcloud
После подготовки роутера можно создать и настроить контейнер с приложением.
Создание переменных для управления контейнером
Для управления будущим контейнером нужно создать специальные переменные. Они будут «пробрасываться» внутрь него и подгружать значения, например, в конфигурационных файлах.
Таких переменных может быть очень много. Поэтому их принято группировать. Для этого нужно перейти во вкладку Evns и заполнить форму из нескольких полей:
- Name — название группы переменных,
- Key — ключ,
- Value — значение ключа.
![](https://habrastorage.org/webt/e8/j9/pc/e8j9pcqgdff_43nmfb4iqscwq_8.png)
Окно Env, добавление переменных.
/container/envs/add name=nextcloud_evns key=APACHE_LOG_DIR value=/var/log/httpd
Команда для добавления переменных
Группы переменных понадобятся во время создания контейнера.
Настройка каталога монтирования Nextcloud
В RouterOS есть вкладка Mounts — аналог атрибута --mount, который нужен для создания каталогов монтирования в традиционном Docker. С помощью Mounts можно сопоставить директории, находящиеся в файловой системе MikroTik, и директории, находящиеся внутри контейнера.
Это нужно сделать для тех директорий, которые важно не потерять в случае перезагрузки контейнера. В моем случае нужно было создать точку монтирования для директории Nextcloud (/var/www/html).
Чтобы это сделать, нужно указать специальные параметры:
- Name — уникальное имя точки монтирования. Оно понадобится при создании контейнера,
- Src — путь к директории, находящейся на внешнем накопителе, которую необходимо смонтировать,
- Dst — путь к директории назначения внутри контейнера.
![](https://habrastorage.org/webt/ix/ei/2v/ixei2va8ilidfbcwwa4grst691a.png)
Окно Mount, добавление каталога монтирования.
/container/mounts/add name=nextcloud_html src=disk2/nextcloud_html dst=/var/www/html
Запуск контейнера
Наконец, можно создать и запустить контейнер. Для этого нужно перейти во вкладку Container и заполнить следующие поля:
- Remote Image — название образа контейнера, который будет установлен (в моем случае с Docker Hub),
- Interface — VETH-интерфейс для использования с контейнером,
- Envlist — список переменных среды, настроенных в Container → Envs, которые будут использоваться контейнером,
- Root Dir — директория, в которую будет установлен контейнер,
- Mounts — точки монтирования, настроенные в Container → Mounts.
![](https://habrastorage.org/webt/fy/53/mi/fy53mictwedpqaljegivcnbp96q.png)
Окно Container, финальная настройка и запуск.
/container add remote-image=arm32v7/nextcloud:latest envlist=nextcloud_envs hostname=nextcloud interface=veth1 mounts=nextcloud_html root-dir=disk2/nextcloud
Команда для создания контейнера.
После можно запустить контейнер нажатием на кнопку Start. Или с помощью специальной команды.
/container/start number=1
/container/print
Запуск Nextcloud в Docker-контейнере.
1 — номер контейнера, который можно узнать командой /container/print
![](https://habrastorage.org/webt/jl/st/dj/jlstdjzlbaaglkqem0ui_xchq8m.png)
Стартовое окно Nextcloud.
Изначально в RouterOS 7.5 функция автозапуска контейнеров после перезагрузки роутера отсутствовала. В версии 7.6 такая возможность появилась, но она все еще недоступна для настройки через Winbox.
Если контейнер уже создан, добавить его в автозагрузку можно специальной командной через терминал./container/set 1 start-on-boot=yes
1 — номер контейнера
Если вы только создаете контейнер, то в команде нужно прописать специальный параметр.start-on-boot=yes
Первые настройки всегда «комом»
В большинстве случаев контейнер запустить с первого раза не получится. Настройки, как блины, первый раз получаются «комом». Чтобы узнать, в каком месте допущена ошибка, вывод информации (исключений и ошибок) нужно транслировать из контейнера в log роутера.
Достаточно поставить галочку рядом с Logging.
![](https://habrastorage.org/webt/aa/dh/tn/aadhtnk9jmrg4x_prjy6_mwowha.png)
Окно Container, включение логирования сообщений. В консоли для этого нужно выполнить команду /container/set 1 logging=yes
Или вручную подключиться к работающей оболочке контейнера. Для этого нужно ввести команду и номер контейнера.
[admin@R1] > /container/shell 1
root@wireguard:/# ls
bin data etc home media opt root sbin start.sh tmp var web-vault
boot dev healthcheck.sh lib mnt proc run srv sys usr vaultwarden
root@wireguard:/# whoami
root
root@wireguard:/# exit
exit
done
Подключение к командной строке внутри контейнера, внутри которой можно выполнять любые команды (Is, whoami).
Оба способа помогут оперативно отловить «фичу» и прокричать «Ура, я запустил Docker на MikroTik!». Но оправдана ли радость?
Зачем вообще нужен контейнер на MikroTik?
Контейнеризация в MikroTik может быть полезна для решения нетребовательных задач, для которых не нужно поднимать отдельные серверы.
Вот несколько возможных сценариев использования «домашних контейнеров»:
- Организация облачного файлового хранилища. Тут важно отметить, что лучше использовать приложения «попроще». Nextcloud слишком нагружает роутер.
- Развертывание менеджера паролей. Повторюсь: лучше использовать менее нагрузочное ПО. Например, в качестве менеджера паролей вместо bitwarden можно установить его аналог — vaultwarden. Но помните: ответственность за безопасность паролей остается за вами.
- Запуск полноценного DNS-сервера. Благодаря контейнерам на роутерах MikroTik стало возможным поднимать полноценные DNS-серверы и делегировать им управление доменами. Это можно сделать с помощью установки BIND 9. Именно этим я займусь во время апгрейда своего домашнего дата-центра, о котором можно почитать в блоге Selectel.
Область применения контейнеров на RouterOS ограничивается лишь вашей фантазией и… «железом» роутеров.
Из-за ресурсных ограничений контейнеры на MikroTik подходят не всегда. Для развертывания высоконагруженных сервисов лучше воспользоваться полноценным сервисом — например, Managed Kubernetes.
А какое приложение на MikroTik запустили бы вы? Поделитесь своим мнением в комментариях.
Комментарии (24)
denis-isaev
20.10.2022 18:53+7Май гад! ) Следующим шагом ждем Дум на Микротике )
Fullmoon
21.10.2022 10:01Ну, например, https://github.com/CallumHoughton18/Doom-In-Docker. Baremetal будет посложнее, конечно.
Greenback
20.10.2022 19:30У меня RB951, который докер не потянет.
Я воткнул в USB порт малютку Raspberry PI Zero W2, приклеив двусторонним скотчем. Он по USB и питание получает и сетевой интерфейс предоставляет. Настоящий компик с линуксом, без шаманства, бонусом WiFi и Bluetooth.
Цена вопроса 15$
Whyborn77
20.10.2022 19:51уже с годик висит на моем ac3 в usb порту pi zero 2 и прекрасно себя чувствует (с дешевыми алиэкспресными медными радиаторами) и коллекция докера подтверждает надежность азиатской апельсинки:
pihole
homeassistant
watchtower
portainer_edge_agent
Doman
21.10.2022 11:02К сожалению, RPI Z2 W уже несколько месяцев как не купить, а если где-то и всплывает, то за совсем другой прайс.
Tabletko
20.10.2022 19:54+1Почему-то не упомянули reverse proxy, которого так не хватало на микротике в малых инсталляциях.
avelor
20.10.2022 20:46Чуть игрался с этой темой при первом появлении в бете (7.1 какой-то). Забавное
Не проверяли, контейнеры всё ещё непривелигированные? Хотел запустить контейнер с tap внутри (да, я странный), но --cap-add=NET_ADMIN опции как-то не было:)
JayK
21.10.2022 06:33Вообще конечно оч интересно. Допустим если 4011 применяется дома или в небольшом офисе, то и памяти и места на диске там предостаточно, 5009 уж тем более. Вот сижу думаю что бы туда можно было закачать. Видится логичным такое применение для которого малинка (которая нынче несмешно стоит) это овермощь.
Смысла в контейнере на CHR не вижу вообще никакого, CHR бай дизайн уже стоит в виртуальной среде.
Вот безопасность... Все мы помним крупнейший микротик ботнет и как устройства выдавали логин и пароль каждому желающему. Ну пока нет, не готов испытывать такое в продакшн.
OptimumOption
21.10.2022 07:47+1Ситуация с вкорячиванием контейнеров на любую доступную под рукой железку выглядит так же, как портмоне с карточками, телефоном, наличкой и ключами, брошенное на видном месте - пролюбить, так сразу всё сразу! Ну и аналогия с анекдотом "...а сейчас мы со всей этой хренью попытаемся взлететь!..." сама собой напрашивается. Прямо поколение каких то латентных садомазохистов, ей богу...
JayK
21.10.2022 09:16просто домохозяйки долго просили микротик чтобы он качал торренты, ну и вот вам решение)
DaemonGloom
21.10.2022 10:02Условные pi-hole или какой-нибудь хитрый прокси/vpn проще поставить на роутер, поскольку это сервисы, прямо связанные с его работой. Понятно, что ставить туда Home Assistant — решение странное и потом принесёт кучу проблем.
avelor
21.10.2022 12:21..от циски научились. мб потом в рамках развития например будут давать по подписке контейнеры со всякими ngfw фичами
Wernisag
21.10.2022 13:38Очевидно, что для полноты не хватает двух вещей. Запуск дума и CHR через контейнер
yabovbel Автор
21.10.2022 21:51Запуск DOOM уже стал традицией)) а вот запустить CHR в контейнере на аппаратном роутере не удастся. Проблема в поддерживаемых архитектурах. CHR удастся запустить только на x86 системе, а аппаратных платформ у Mikrotik с такой архитектурой нет.
kernelconf
vlmcsd. Гораздо более уместно, нежели Nextcloud.