Запуск контейнеров Docker на роутерах MikroTik (RouterOS 7)

Начиная с версии RouterOS 7 появилась возможность запускать Docker совместимые контейнеры прямо на роутерах MikroTik. В статье мы рассмотрим, про использование пакета Container на роутерах MikroTik, как включить поддержку контейнеров, настроить внешнее хранилище для контейнеров на подключенном USB диске, настройку сети для контейнеров, установку и управления образами.

Системные требования:

  • Не каждый роутер MikroTik поддерживаем контейнеры. Проверяйте поддержку для вашей модели на сайте производителя.
  • На роутерах с менее чем 1Гб RAM запускать контейнеры будет проблематично.
  • Требуемая версия RouterOS v7.11+
Помимо нагрузки на железо, контейнеры несут в себе дополнительные риски безопасности. Контейнеры в MikroTik не являются полноценными изолированными Docker контейнерами. Через уязвимости в контейнерах злоумышленники могут выбраться на хостовую RouterOS. Не используйте непроверенные и старые/уязвимые версии контейнеров.

Включить поддержку контейнеров в MikroTik

Проверьте, установлен ли на вашем роутере пакет container. Запустите WinBox, перейдите в раздел System -> Packages и проверьте есть ли он в списке.

Если пакет, отсутствует, скачайте официальный пакет с https://mikrotik.com/download (для вашей архитектуры и версии RouterOS).

Архитектуру и версию среды можно узнать так (в моем случае это arm64):

/system/resource/print

проверка версии routeros на mikrotik

скачать пакет container для mikrotik

Загрузите скачанный NPK файл (container-7.24.5-arm64.npk) в корневой каталог роутера с помощью WinBox через Files -> Upload и перегрузите роутер.

Проверьте, что пакет container появился в списке доступных. Включите его.

пакет containers в routeros

Теперь нужно включить поддержку контейнеров на устройстве. Откройте консоль роутера и проверьте какие функции включены на роутере:

/system/device-mode/print

поддержка контейнеров отключена

По умолчанию поддержка контейнеров отключена. Чтобы разрешить запуск контейнеров, выполните:

/system/device-mode/update container=yes

update: turn off power or reboot by pressing reset or mode button in 4m33s to
-- [Q quit|D dump|C-z pause|right]

включить контейнеры

Для активации компонента нужно в течении 5 минут нужно перегрузить роутер физически (по питанию или кнопкой reset на корпусе).

Для виртуального роутера MikroTik CHR нужно выполнить перезагрузку через консоль виртуальной машины.

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

/system/device-mode/print

проверяем, что в routeros разрешено использовать контейнеры

Настройка сети для контейнеров в MikroTik

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

Создаем бридж для контейнеров (можно использовать один для всех, или если нужно изолировать трафик контейнеров, можно создать несколько бриджей):

Interfaces -> Interface -> New Bridge. Имя br_containers

создать мост для контейнеров

Затем идем в IP -> Adresses и добавляем IP адрес 172.17.0.1/24 и подсеть для моста br_containers.

подсеть контейнеров

Создаем новый виртуальный интерфейс для подключения контейнера к сети (для каждого контейнера понадобится как минимум один сетевой интерфейс): Interfaces -> New -> VETH. Указываем имя name , address (IP адрес и маску подсети) и gateway (в качестве шлюза по умолчанию указывается IP адрес бриджа для контейнеров, который мы создадим далее).

интерфейс verh для контейнера

Добавляем интерфейс verh1 в бридж br_containers (Bridge -> Ports).

Добавить интерфейс veth в бридж

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

/interface/veth/add name=veth1 address=172.17.0.5/24 gateway=172.17.0.1
/interface/bridge/add name=br_containers
/ip/address/add address=172.17.0.1/24 interface=br_containers
/interface/bridge/port add bridge=containers interface=veth1

Создайте правило для выхода из подсети контейнеров в Интернет. В моем случае у меня уже есть глобальное srcnat (masquerade) для всех внутренних сетей:

/ip firewall nat
add action=masquerade chain=srcnat out-interface-list=WAN

Либо создайте кастомное правило masquerade для подсети контейнеров.

правило srcnat masqurade для контейнеров

Подготовка USB хранилища для контейнеров Docker в MikroTik

Для хранения образов контейнеров Docker в MikroTik понадобится внешний USB SSD диск (сойдет и обычная USB флешка или SD карта, но ресурс и производительность такого хранилища, если используются дешевые бытовые накопители, будут ниже). И конечно, не стоит хранить контейнеры на встроенной флеш памяти роутера, это быстро убьет его ресурс.

Подключаем в USB порт диск и проверяем, что он виден:

/disk scan
/disk print

вывести список подключённых USB дисков

Форматируем диск в ext4 (все данные будут удалены)

/disk/format usb1 file-system=ext4

отформатировать флешку из routeros

Создаем директории для контейнеров, временных файлов и тома для хранения данных:

/file add name=usb1/containers type=directory
/file add name=usb1/tmp type=directory
/file add name=usb1/layers type=directory
/file add name=usb1/volumes type=directory

Подключаем Docker Hub в качестве основного источника образов:

/container/config
set registry-url=https://registry-1.docker.io \
layer-dir=usb1/layers \

Вывести текущие настройки подсистемы контейнеров в разделе Containers -> Config или командой:

/container/config print

registry-url: https://registry-1.docker.io
username:
layer-dir: /usb1/layers
tmpdir: 
memory-high: unlimited
memory-max: unlimited
memory-current: 0
swap-max: unlimited
swap-current: 0

Настройка параметров docker в mikrotik

Запускаем первый контейнер на MikroTik

Переходим к настройке и запуску первого контейнера на роутере MikroTik. Мы будем разворачивать контейнер с Pi-hole, который будем использоваться в качестве простого локального DNS сервера для блокировки рекламы, телеметрии и управления черными/белыми списками сайтов для устройств в моей локальной сети.

Подготовим переменные окружения с базовыми настройками для нашего контейнера. Переменные можно создать через WinBox (Contaners -> Envs) или командами в консоли.

Мы задаем часовой пояс, имя администратора и пароль, вышестоящие upstream DNS сервера:

/container/envs/add list=ENV_PIHOLE key=TZ value="Europe/Moscow"
/container/envs/add list=ENV_PIHOLE key=DNSMASQ_USER value="root"
/container/envs/add list=ENV_PIHOLE key=FTLCONF_webserver_api_password value="MyPa33wo0rd"
/container/envs/add list=ENV_PIHOLE key=FTLCONF_dns_upstreams value="77.88.8.2; 77.88.8.88"
/container/envs/add list=ENV_PIHOLE key=FTLCONF_dns_listeningMode value="all"

создать переменные окружения для контейнера

Чтобы состояние контейнера не терялось при перезапуске, создадим точки монтирования (mounts), которые свяжут папки в контейнере с реальными папками на USB диске, в которых фактически будут хранится постоянные данные, которые должны сохраняться при перезапуске контейнера.

/container/mounts/add list=MOUNT_PIHOLE_PIHOLE src=usb1/volumes/pihole/pihole dst=/etc/pihole
/container/mounts/add list=MOUNT_PIHOLE_DNSMASQD src=usb1/volumes/pihole/dnsmasq.d dst=/etc/dnsmasq.d

точки монтирования в Docker

Опционально, если вы хотите существенно уменьшить количество операций записи на внешний накопитель (с целью продления его срока службы, особенно актуально для дешевых SD карт), часть временных файлов, кеша, логов, которые пишутся внутри контейнера, можно перенаправить на временный RAM диск в памяти роутера. На моем устройстве (hap ax3) из 1Гб используется всего 300 Мб, поэтому я без проблем могу выделить 100 мб или более для RAM диск в памяти для временных данных. Это уменьшит нагрузку и износ SD карты.

Создаем tmpfs диск в RAM:

/disk add type=tmpfs tmpfs-max-size=100M slot=ram

Создаем точки монтирования для контейнера на RAM диске:

/container/mounts/add list=MOUNT_PIHOLE_TMP src=ram/tmp dst=/tmp
/container/mounts/add list=MOUNT_PIHOLE_LOG src=ram/log dst=/var/log/pihole

Также большую нагрузку на запись на USB флешку будет давать база данных SQLite /etc/pihole/pihole-FTL.db . Ее также можно перенести во временную память в RAM (при этом у вас не будет долговременной статистики запросов, которые будут сбрасываться при перезагрузке роутера).

Либо можно отключить логирование на диск в /var/log/pihole/pihole.log , сделать сброс логов в базу более редким (не каждую минуту, а раз в час) и ограничить срок хранения статистики 7 днями:

/container/envs/add list=ENV_PIHOLE key=FTLCONF_dns_queryLogging value="false"
/container/envs/add list=ENV_PIHOLE key=FTLCONF_database_maxDBdays value="7"
/container/envs/add list=ENV_PIHOLE key=FTLCONF_database_DBinterval value="3600"

Теперь мы готовы скачать образ контейнера Pi-hole:

/container/add name=pihole \
remote-image=pihole/pihole:latest \
interface=veth1 \
root-dir=usb1/containers/pihole \ mountlists=MOUNT_PIHOLE_PIHOLE,MOUNT_PIHOLE_DNSMASQD,MOUNT_PIHOLE_TMP,MOUNT_PIHOLE_LOG
envlist=ENV_PIHOLE \
logging=yes \
start-on-boot=yes

После чего начнется загрузка образа PiHole из Docker Hub (размер образа около 120 Мб).

скачиваем образ docker для mikrotik

После создания нового Docker‑контейнера в MikroTik автоматически загружается образ, выполняется его распаковка, и экземпляр переводится в состояние stopped. Для его активации необходимо однократно нажать кнопку Start. При успешном запуске рабочий статус контейнера изменится на running.

запуск контейнера

Либо проверяем, что образ загружен и запускаем его:

/container/print
/container/start pihole

Вывести лог загрузки контейнера (удобно для отладки):

/log/print where topics~"container"

Выводим состояние контейнера:

/container/print detail

вывести информацию о контейнере

По умолчанию веб-интерфейс контейнера Pi-hole доступен на порту 80. Для удобства, чтобы сделать веб интерфейс Pi-hole доступным напрямую по IP адресу вашего роутера MikroTik (вместо доступа по IP адресу в сети контейнеров), создадим такое NAT правило:

/ip/firewall/nat add action=dst-nat chain=dstnat \ dst-address=192.168.31.1 dst-port=80 protocol=tcp \ to-addresses=172.17.0.5 to-ports=80 comment="Pi-hole web"

Проверьте, что теперь веб интерфейс Pi-hole доступен на порту 80 вашего роутера: http://192.168.31.1/admin/

веб интерфейс контейнера pihole

В зависимости от настроек правил файервола вашего роутера может понадобится создать дополнительные правила.

Попробуйте выполнить вход с помощью пароля, заданного в переменнной env .

панель управления pi-hole

Осталось изменить настройки DHCP сервера на роутере MikroTik, чтобы клиенты в локальной сети обращались за разрешением имен к DNS серверу, запущенному в контейнере Pi-hole (172.17.0.5)

  • Можно изменить только настройки DNS в DHCP сервере: /ip dhcp-server network set [find] dns-server=172.17.0.5
  • А можно настроить правила, чтобы ваш роутер пересылала все запросы на разрешение имен в контейнер Pi-hole:

/ip firewall nat add chain=dstnat action=dst-nat protocol=udp dst-port=53 to-addresses=172.17.0.5 comment="Force DNS to Pi-hole UDP"
/ip firewall nat add chain=dstnat action=dst-nat protocol=tcp dst-port=53 to-addresses=172.17.0.5 comment="Force DNS to Pi-hole TCP"

Смотрим, что на Pi-hole теперь отображается все DNS запросы из LAN.

Базовые команды для управления контейнерами MikroTik

Ограничить потребление оперативной памяти контейнером:

/container/config/set memory-high=200M

Включать автозапуск контейнера:

/container/set pihole start-on-boot=yes

Вывести список контейнеров:

/container print

Подробный вывод:

/container print detail

Запустить контейнер по его номеру:

/container start 0

Запустить по имени:

/container start [find where name~"pihole"]

Остановить контейнер по номеру:

/container stop 0

Подключиться в оболочку (shell) контейнера, что бывает удобно для выполнения диагностики и доступности изнутри контейнера:

/container/shell 0

подключиться к оболочке запущенного контейнера

Вывести логи определённо контейнера:

/container/log print where container=pihole

Контейнеры в MikroTik можно использовать для расширения возможностей роутера, и реализации функционала, который отсутствует или не полностью представлен в RouteOS. Например, сторонние VPN сервера/клиенты, DNS фильтрация, мониторинг и сбор логов, обратное проксирование, торрент клиенты, и многое другое.


Предыдущая статья Следующая статья


Комментариев: 0 Оставить комментарий

Оставить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *