Удобная Docker лаборатория с блэкджеком и Web GUI
Приветствую!

В этой подробной статье мы будем строить Docker лабораторию для удобного управления проектами Docker Compose с помощью графического интерфейса. И да, под капотом только Open Source 🐧.

Предисловие

Я развернул такую лабораторию на своём домашнем Linux ПК и теперь с удобством управляю своими docker compose сервисами, работающие не только на нём, но и удалённых серверах. Но обо всём по порядку 📝.

Наша будущая лаборатория будет строиться вокруг такого замечательного Open Source продукта, как Komodo.

Ниже коротко о составе лаборатории.

Схема лаборатории

Так, материала впереди много, поэтому меньше слов, больше дела, пингвины 🐧🐧🐧.

Подготовка

Установка Docker

Т.к. мы строим лабораторию для удобного управления Docker ресурсами, устанавливаем Docker Engine и добавляем нашего пользователя в группу docker.

BASH
sudo curl https://get.docker.com/ | bash

sudo gpasswd -a $USER docker

newgrp docker
Нажмите, чтобы развернуть и увидеть больше

После успешной установки и добавления в группу Docker пробуем выполнить команду:

BASH
docker run hello-world
Нажмите, чтобы развернуть и увидеть больше

В случае успеха увидим такое:

Установка вспомогательных утилит

Теперь установим утилиты из стандартных репозиториев, которые нам понадобятся в ходе настройки нашей лаборатории:

BASH
sudo apt update

sudo apt install -y libnss3-tools dnsutils acl mkcert pwgen
Нажмите, чтобы развернуть и увидеть больше

Создание рабочей директории и установка прав

Создаём workdir и ограничиваем к ней доступ:

BASH
sudo mkdir -vp /opt/komodo/

sudo chmod -v 700 /opt/komodo
Нажмите, чтобы развернуть и увидеть больше

Устанавливаем полные права на workdir и будущие файлы для текущего пользователя:

BASH
sudo setfacl -R -m m::rwx /opt/komodo

sudo setfacl -R -m d:m::rwx /opt/komodo

sudo setfacl -R -m u:ivan:rwX /opt/komodo

sudo setfacl -R -m d:u:ivan:rwX /opt/komodo

getfacl /opt/komodo
Нажмите, чтобы развернуть и увидеть больше

Генерация сертификатов

Т.к. я привожу пример настройки Docker лаборатории на десктопном Linux ПК, то создам самоподписанный “центр сертификации (RootCA)” и сертификаты для доменов.

Для этого воспользуемся ранее установленной утилитой mkcert:

BASH
mkcert -install

mkcert -CAROOT
Нажмите, чтобы развернуть и увидеть больше

Первая команда создаёт локальный центр сертификации и добавляет его корневой сертификат в доверенные сертификаты на нашей системе и в хранилище установленных браузеров, например, Firefox и Chromium:

Теперь создадим директорию для сертификатов и две штуки их самих:

BASH
mkdir -vp /opt/komodo/periphery/stacks/nginx/certs

cd /opt/komodo/periphery/stacks/nginx/certs

mkcert -cert-file ./home.lan.crt -key-file ./home.lan.key "home.lan" "localhost" "127.0.0.1"

mkcert -cert-file ./_wildcard.home.lan.crt -key-file ./_wildcard.home.lan.key "*.home.lan"
Нажмите, чтобы развернуть и увидеть больше

(Опционально) Добавление mkcert rootCA в доверенные на другом хосте

Если вы планируете обращаться по HTTPS к вашему локальному хосту с других хостов, например, по защищённой приватной сети, то просто скопируйте корневой сертификат (не ключ!), созданный mkcert, в доверенные на другом хосте и обновите список.

Пример для Debian:

BASH
scp ~/.local/share/mkcert/rootCA.pem user@target_host:/tmp/

ssh -t user@target_host sudo cp /tmp/rootCA.pem /usr/local/share/ca-certificates/mkcert-rootCA.crt

ssh -t user@target_host sudo update-ca-certificates

ssh user@target_host trust list | grep mkcert
Нажмите, чтобы развернуть и увидеть больше

Добавление хостов в /etc/hosts

Теперь нам нужно добавить 3 записи в локальный файл /etc/hosts:

BASH
cat << EOF | sudo tee -a /etc/hosts
127.0.0.1 home.lan # Nginx proxy
127.0.0.1 komodo.home.lan # Docker manager
127.0.0.1 technitium.home.lan # DNS
EOF
Нажмите, чтобы развернуть и увидеть больше

Создание сети докер

Для нашей инсталляции мы создадим отдельную сеть Docker: komodo_net:

BASH
docker network create --opt com.docker.network.bridge.name=br-komodo-net --opt com.docker.network.enable_ipv6=false --driver bridge --subnet 10.51.51.0/24 --gateway 10.51.51.1 komodo_net
Нажмите, чтобы развернуть и увидеть больше

С подготовкой закончили😌.

Настройка прокси сервера - Nginx Proxy Manager

Приступаем к настройке нашего proxy, который будет управлять сертификатами, проксированием HTTP и TCP.

Запуск nginx-proxy-manager в Docker

Переходим в рабочую директорию nginx и создаём файл docker сервисов:

BASH
cd /opt/komodo/periphery/stacks/nginx/

vim ./compose.yaml
Нажмите, чтобы развернуть и увидеть больше

Наполняем его следующим содержимым:

YAML
---
# https://nginxproxymanager.com/setup/

networks:
  komodo_net:
    external: true

services:
  nginx:
    image: jc21/nginx-proxy-manager:latest
    container_name: nginx
    restart: unless-stopped
    stop_grace_period: 30s
    cpus: 2
    mem_limit: 2G
    environment:
      TZ: Europe/Moscow
      DB_SQLITE_FILE: /data/database.sqlite
    hostname: nginx
    volumes:
      - ./data/:/data/
      - ./certs/letsencrypt:/etc/letsencrypt/
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    ports:
      - 127.0.0.1:80:80 # HTTP
      - 127.0.0.1:81:81 # Web UI
      - 127.0.0.1:443:443 # HTTPS
      # - 127.0.0.1:53:53 # DNS
    dns: 
      - 10.51.51.50
      - 8.8.8.8
    networks:
      komodo_net:
        ipv4_address: 10.51.51.50
        aliases:
          - home.lan
          - nginx-proxy-manager
          - nginx-proxy
          - nginx
Нажмите, чтобы развернуть и увидеть больше

Запускаем наш первый сервис и смотрим вывод:

BASH
docker compose up -d && docker logs -f nginx
Нажмите, чтобы развернуть и увидеть больше

После успешного запуска открываем в веб-браузере адрес http://localhost:81.

Увидим окно приветствия и предложение указать имя/email администратора и задать для него пароль:

Добавление сертификатов в Nginx

На данном шаге мы настроим прокси-доступ к Web GUI панелям наших сервисов (в т.ч. nginx-proxy-manager) по HTTPS.

После входа в админ-панель прокси включаем тёмную тему 😉, меняем язык интерфейса на русский и переходим в раздел управления сертификатами:

Нажимаем “Добавить сертификат” –> “Свой сертификат”. Указываем:

И таким же образом загружаем wildcard сертификат. В итоге у вас должно быть добавлено два сертификата:

Создание прокси-хостов

Теперь переходим в “Хосты” –> “Прокси-хосты” и нажимаем “Добавить Прокси-хост”:

В пункте “Домены” указываем home.lan и нажимаем Enter. Далее в поле “Хост” указываем сетевой алиас нашего прокси nginx, в поле “Порт” - порт, на котором работает админка прокси - 81. После заполнения переходим на вкладку “SSL”:

Тут выбираем сертификат home.lan, включаем принудительный SSL и поддержку HTTP/2. После чего нажимаем “Сохранить”:

Таким же образом добавляем еще два прокси-хоста.

Komodo:

Technitium:

В итоге у нас получится три прокси-хоста:

Проверяем работу проксирования нажав на запись home.lan в колонке “ИСТОЧНИК”. Откроется новая страница входа в панель nginx, но уже с валидным соединением по HTTPS:

Никаких ругательств на сертификаты и небезопасное соединение😌.

Создание потока (stream) для DNS запросов

Теперь мы создадим один стрим для проксирования DNS запросов в DNS сервер technitium.

Переходим в “Хосты” –> “Потоки” и нажимаем “Добавить Поток”:

Указываем:

И нажимаем “Сохранить”:

Будет такая запись:

Настройка менеджера Docker - Komodo

Переходим к менеджеру Docker ресурсов - Komodo.

Запуск Komodo в Docker

Идём в рабочую директорию и создаём compose файл:

BASH
cd /opt/komodo

vim ./compose.yaml
Нажмите, чтобы развернуть и увидеть больше

Наполняем его:

YAML
---
# https://github.com/moghtech/komodo/blob/main/compose/mongo.compose.yaml

networks:
  komodo_net:
    external: true

services:
  komodo_db:
    image: mongo:8.2.7-rc0
    container_name: komodo-db
    labels:
      komodo.skip: # Prevent Komodo from stopping with StopAllContainers
    restart: unless-stopped
    stop_grace_period: 1m
    cpus: 2
    mem_limit: 2G
    hostname: komodo-db
    command: --quiet --wiredTigerCacheSizeGB 0.25
    volumes:
      - ./db/data/:/data/db/
      - ./db/config/:/data/configdb/
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    environment:
      TZ: Europe/Moscow
      MONGO_INITDB_ROOT_USERNAME: ${KOMODO_DB_USERNAME}
      MONGO_INITDB_ROOT_PASSWORD: ${KOMODO_DB_PASSWORD}
    expose:
      - 27017
    dns: 
      - 10.51.51.50
      - 8.8.8.8
    networks:
      komodo_net:
        ipv4_address: 10.51.51.51
        aliases:
          - komodo-db.home.lan
          - komodo-db
  
  komodo_core:
    image: ghcr.io/moghtech/komodo-core:${COMPOSE_KOMODO_IMAGE_TAG:-latest}
    depends_on:
      - komodo_db
    container_name: komodo-core
    labels:
      komodo.skip: # Prevent Komodo from stopping with StopAllContainers
    restart: unless-stopped
    stop_grace_period: 1m
    cpus: 2
    mem_limit: 2G
    hostname: komodo-core
    env_file: ./.env
    environment:
      TZ: Europe/Moscow
      KOMODO_DATABASE_ADDRESS: komodo-db:27017
      KOMODO_DATABASE_USERNAME: ${KOMODO_DB_USERNAME}
      KOMODO_DATABASE_PASSWORD: ${KOMODO_DB_PASSWORD}
    volumes:
      - ./core/backups/:/backups/
      - ./core/syncs/:/syncs/
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    expose:
      - 9120
    dns: 
      - 10.51.51.50
      - 8.8.8.8
    networks:
      komodo_net:
        ipv4_address: 10.51.51.52
        aliases:
          - komodo-core.home.lan
          - komodo.home.lan
          - komodo-core
          - komodo

  komodo_periphery:
    image: ghcr.io/moghtech/komodo-periphery:${COMPOSE_KOMODO_IMAGE_TAG:-latest}
    labels:
      komodo.skip: # Prevent Komodo from stopping with StopAllContainers
    container_name: komodo-periphery
    stop_grace_period: 1m
    cpus: 2
    mem_limit: 2G
    hostname: komodo-periphery
    restart: unless-stopped
    env_file: ./.env
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - /proc:/proc
      ## Specify the Periphery agent root directory.
      ## Must be the same inside and outside the container,
      ## or docker will get confused.
      ## Default: /etc/komodo.
      - ${PERIPHERY_ROOT_DIRECTORY:-/opt/komodo}:${PERIPHERY_ROOT_DIRECTORY:-/opt/komodo}
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    expose:
      - 8120
    dns: 
      - 10.51.51.50
      - 8.8.8.8
    networks:
      komodo_net:
        ipv4_address: 10.51.51.53
        aliases:
          - komodo-periphery.home.lan
          - komodo-periphery
Нажмите, чтобы развернуть и увидеть больше

Файл описывает работу и взаимодействие трёх сервисов:

Теперь создаём файл с переменными окружения сервисов Komodo:

BASH
vim ./.env
Нажмите, чтобы развернуть и увидеть больше

И наполняем:

BASH
# https://github.com/moghtech/komodo/blob/main/compose/compose.env
TZ=Europe/Moscow
COMPOSE_KOMODO_IMAGE_TAG=2.0

KOMODO_INIT_ADMIN_USERNAME=komodo
KOMODO_INIT_ADMIN_PASSWORD=
KOMODO_DB_USERNAME=komodo
KOMODO_DB_PASSWORD=
KOMODO_PASSKEY=
KOMODO_HOST=https://komodo.home.lan
KOMODO_TITLE=Komodo
KOMODO_FIRST_SERVER=https://komodo-periphery:8120
KOMODO_FIRST_SERVER_NAME=komodo.home.lan
KOMODO_DISABLE_CONFIRM_DIALOG=true
KOMODO_MONITORING_INTERVAL="15-sec"
KOMODO_RESOURCE_POLL_INTERVAL="1-hr"
KOMODO_WEBHOOK_SECRET=
KOMODO_JWT_SECRET=
KOMODO_JWT_TTL="1-day"
KOMODO_LOCAL_AUTH=true
KOMODO_DISABLE_USER_REGISTRATION=false
KOMODO_ENABLE_NEW_USERS=false
KOMODO_DISABLE_NON_ADMIN_CREATE=false
KOMODO_TRANSPARENT_MODE=false
KOMODO_LOGGING_PRETTY=false
KOMODO_PRETTY_STARTUP_CONFIG=false

PERIPHERY_ROOT_DIRECTORY=/opt/komodo/periphery
# PERIPHERY_STACK_DIR=/opt/komodo/stacks
PERIPHERY_PASSKEYS=${KOMODO_PASSKEY}
PERIPHERY_DISABLE_TERMINALS=false
PERIPHERY_SSL_ENABLED=true
PERIPHERY_INCLUDE_DISK_MOUNTS=/etc/hostname
PERIPHERY_LOGGING_PRETTY=false
PERIPHERY_PRETTY_STARTUP_CONFIG=false
Нажмите, чтобы развернуть и увидеть больше

Тут нам необходимо задать свои значения для паролей/секретов. Вновь воспользуемся утилитой pwgen:

BASH
sed -iE "s/^KOMODO_INIT_ADMIN_PASSWORD=.*/KOMODO_INIT_ADMIN_PASSWORD=$(pwgen -s 32 1)/" ./.env

sed -iE "s/^KOMODO_DB_PASSWORD=.*/KOMODO_DB_PASSWORD=$(pwgen -s 32 1)/" ./.env

sed -iE "s/^KOMODO_PASSKEY=.*/KOMODO_PASSKEY=$(pwgen -s 64 1)/" ./.env

sed -iE "s/^KOMODO_WEBHOOK_SECRET=.*/KOMODO_WEBHOOK_SECRET=$(pwgen -s 64 1)/" ./.env

sed -iE "s/^KOMODO_JWT_SECRET=.*/KOMODO_JWT_SECRET=$(pwgen -s 64 1)/" ./.env
Нажмите, чтобы развернуть и увидеть больше

После этого можем запускать сервис komodo:

BASH
docker compose up -d && docker compose logs -f
Нажмите, чтобы развернуть и увидеть больше

После успешного запуска возвращаемся в браузер и переходим на https://komodo.home.lan, где мы видим вход в панель управления Komodo без всякой ругани на TLS сертификаты:

Вводим логин komodo и пароль из переменной KOMODO_INIT_ADMIN_PASSWORD:

BASH
grep ADMIN_PASSWORD ./.env
Нажмите, чтобы развернуть и увидеть больше

Интерфейс юзерфрендли, с приятным и современным дизайном.

Создание compose stack для nginx - файлы на сервере

Идём в “Stacks” –> “New Stack”:

Указываем имя nginx, а в качестве сервера выбираем наш локальный komodo.home.lan:

Заходим внутри стека nginx:

И на вкладке “Config” выбираем режим “Files On Server”:

Сохраняем изменения:

И т.к. наш nginx уже запущен, стек автоматически перейдёт в статус “RUNNING”:

Если видите что-то подобное:

Значит вы указали неправильное имя стека, либо некорректно примонтировали рабочую директорию periphery контейнера:

Вы можете изменять параметры стека прямо в веб интерфейсе Komodo на вкладке “Info” (в случае режима “Files On Server”). После изменений, нажмите “Save” и затем “Redeploy”, чтобы применить обновлённые параметры.

Управлять ресурсами сервера можно как внутри самого стека, так и в разделе “Servers” –> “<server_name>”:

Очень наглядно, очень удобно 👍.

Настройка DNS сервера - Technitium

(это не реклама, это Райан Гослинг)

Любая лаборатория считается неполноценной, если в ней отсутствует свой DNS сервер.

Создание compose stack для technitium - файлы на сервере

Возвращаемся в веб-панель “Komodo” –> “Stacks” –> “New Stack”. Указываем название technitium и выбираем наш локальный сервер komodo.home.lan.

После проваливаемся внутрь стека на вкладке “Config” выбираем режим “UI Defined”:

Наполняем поле “Compose File” таким содержимым:

YAML
---
# https://github.com/TechnitiumSoftware/DnsServer/blob/master/docker-compose.yml

networks:
  komodo_net:
    external: true

services:
  technitium:
    image: technitium/dns-server:${DNS_SERVER_IMAGE_TAG:-latest}
    container_name: technitium
    restart: unless-stopped
    stop_grace_period: 1m
    cpus: 2
    mem_limit: 2G
    hostname: technitium
    sysctls:
      - net.ipv4.ip_local_port_range=1024 65535
    env_file: ./.env
    volumes:
      - ./data/:/etc/dns/
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    expose:
      - 5380/tcp # DNS web console (HTTP)
      # - 53443/tcp # DNS web console (HTTPS)
      - 53/udp # DNS service
      - 53/tcp # DNS service
      # - 853/udp # DNS-over-QUIC service
      # - 853/tcp # DNS-over-TLS service
      # - 443/udp # DNS-over-HTTPS service (HTTP/3)
      # - 443/tcp # DNS-over-HTTPS service (HTTP/1.1, HTTP/2)
      # - 80/tcp # DNS-over-HTTP service (use with reverse proxy or certbot certificate renewal)
      # - 8053/tcp # DNS-over-HTTP service (use with reverse proxy)
      # - 67/udp # DHCP service
    dns: 
      - 10.51.51.50
      - 8.8.8.8
    networks:
      komodo_net:
        ipv4_address: 10.51.51.54
        aliases:
          - technitium.home.lan
          - technitium-dns
          - technitium
Нажмите, чтобы развернуть и увидеть больше

Прокручиваем вниз до поля “Environment” и наполняем следующим:

BASH
# https://github.com/TechnitiumSoftware/DnsServer/blob/master/DockerEnvironmentVariables.md
DNS_SERVER_IMAGE_TAG=14.3.0
DNS_SERVER_ADMIN_PASSWORD=4RyYdGWcpkdGFj6anL64JxtbKwpQheqC
DNS_SERVER_DOMAIN=technitium.home.lan
DNS_SERVER_PREFER_IPV6=false
DNS_SERVER_RECURSION=AllowOnlyForPrivateNetworks
DNS_SERVER_FORWARDERS=8.8.8.8, 9.9.9.9
Нажмите, чтобы развернуть и увидеть больше

Нажимаем “Save”:

И запускаемся нажатием кнопки “Deploy”:

Перейдите на вкладку “Log”, чтобы видеть вывод контейнера. Если всё ок, должны увидеть следующее:

Вы можете изменять параметры стека прямо в веб интерфейсе Komodo на вкладке “Config” (в случае режима “UI Defined”). После изменений, нажмите “Save” и затем “Redeploy”, чтобы применить обновленные параметры.

После успешного запуска идём в браузер и открываем https://technitium.home.lan. Веб интерфейс управления DNS должен также открыться без проблем:

Логин admin, пароль берём из переменной DNS_SERVER_ADMIN_PASSWORD.

После входа сразу же подключаем тёмную тему 🌚:

Данный DNS сервер очень удобен в управлении и имеет достаточно широкий функционал: зоны, кэш, рекурсия и пр.

Создание зоны home.lan и записей для неё

Для удобства работы в нашей лаборатории создадим отдельную зону для домена home.lan.

Переходим на вкладку “Zones” и нажимаем “Add Zone”:

Указываем зону home.lan, оставляем чекбокс “Primary zone (default)” и нажимаем “Add”:

После создания мы попадём в настройки новой зоны. Нажимаем “Add Record” и в качестве имени указываем символ *, а в поле адреса 127.0.0.1 или физический адрес, на котором nginx-proxy-manager слушает 443 порт.

Нажимаем “Save”.

Через минуту-две проверяем работу в терминале хоста с помощью утилиты dig:

BASH
dig @10.51.51.50 r4ven.me +noall +answer

dig @10.51.51.50 test.home.lan +noall +answer
Нажмите, чтобы развернуть и увидеть больше

Должны увидеть такое:

Данный DNS сервер умеет много чего. Рекомендую поизучать его функционал на досуге 👨‍💻.

Проверка статуса ресурсов лаборатории

Выполним небольшую проверку, что всё на месте и всё работает, после завершения настройки сервисов compose:

BASH
docker ps; docker image ls; docker network ls
Нажмите, чтобы развернуть и увидеть больше

Настройка автозапуска ключевых сервисов

Т.к. наша лаборатория зиждется на трёх китах (прокси, docker менеджер и DNS сервер), давайте настроим их автозапуск с помощью Systemd, чтобы они наверняка запускались при старте системы.

Nginx Proxy Manager

Смело вставляем весь блок в терминал (это всё одна here doc команда):

BASH
cat << EOF | sudo tee /etc/systemd/system/komodo-proxy.service
[Unit]
Description=Nginx Proxy Manager
Requires=docker.service
After=docker.service

[Service]
Restart=always
RestartSec=5
User=root
Group=root
WorkingDirectory=/opt/komodo/periphery/stacks/nginx
ExecStart=/usr/bin/docker compose up
ExecStop=/usr/bin/docker compose down

[Install]
WantedBy=multi-user.target
EOF
Нажмите, чтобы развернуть и увидеть больше

Komodo

BASH
cat << EOF | sudo tee /etc/systemd/system/komodo-core.service
[Unit]
Description=Komodo docker stack services
Requires=docker.service
After=docker.service

[Service]
Restart=always
RestartSec=5
User=root
Group=root
WorkingDirectory=/opt/komodo
ExecStart=/usr/bin/docker compose up
ExecStop=/usr/bin/docker compose down

[Install]
WantedBy=multi-user.target
EOF
Нажмите, чтобы развернуть и увидеть больше

Technitium

BASH
cat << EOF | sudo tee /etc/systemd/system/komodo-dns.service
[Unit]
Description=Technitium DNS server
Requires=docker.service
After=docker.service

[Service]
Restart=always
RestartSec=5
User=root
Group=root
WorkingDirectory=/opt/komodo/periphery/stacks/technitium
ExecStart=/usr/bin/docker compose up
ExecStop=/usr/bin/docker compose down

[Install]
WantedBy=multi-user.target
EOF
Нажмите, чтобы развернуть и увидеть больше

Запуск и проверка

Обновляем конфигурацию Systemd и пробуем запустить сервисы с включением автозапуска:

BASH
sudo systemctl daemon-reload

sudo systemctl enable --now komodo-{proxy,core,dns}

systemctl list-units | grep -E 'komodo.*.service' | column -t

systemctl status komodo-{proxy,core,dns} | grep -B3 'Active:'
Нажмите, чтобы развернуть и увидеть больше

Настройка DNS клиента

Для удобства эксплуатации нашей лаборатории, рекомендую настроить отправку локальных DNS запросов на наш сервер Technitium.

Настройка резолвинга зависит от вашей системы и конфигурации сети.

systemd-resolved

Ниже я покажу пример настройки с помощью systemd-resolved.

Делаем бэкап конфигов DNS и создаём новый минимальный конфиг systemd-resolved:

BASH
sudo mv -v /etc/resolv.conf{,.backup}

sudo ln -sv /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf

sudo mv -v /etc/systemd/resolved.conf{,_backup}

cat << EOF | sudo tee /etc/systemd/resolved.conf
[Resolve]
DNS=10.51.51.50
FallbackDNS=192.168.1.1 8.8.8.8
Domains=~.
EOF
Нажмите, чтобы развернуть и увидеть больше

Перезапускаем службу:

BASH
sudo systemctl restart systemd-resolved

systemctl status systemd-resolved

resolvectl
Нажмите, чтобы развернуть и увидеть больше

Проверяем работу DNS уже без явного указания адреса technitium:

BASH
dig r4ven.me +noall +answer +identify

dig test.home.lan +noall +answer +identify
Нажмите, чтобы развернуть и увидеть больше

Работает!

NetworkManager

Если вашей сетью управляет NetworkManager, то указать свои DNS сервера можно через GUI:

Или через nmcli:

BASH
# Смотрим соединения
nmcli connection show

# Задаём DNS
nmcli connection modify "Проводное подключение 1" \
    ipv4.dns "10.51.51.50,192.168.1.1,8.8.8.8" \
    ipv4.ignore-auto-dns yes
Нажмите, чтобы развернуть и увидеть больше

После применения изменений, желательно перезапустить сервис NetworkManager:

BASH
sudo systemctl restart NetworkManager
Нажмите, чтобы развернуть и увидеть больше

Проверяем работу DNS уже без явного указания адреса technitium:

BASH
dig r4ven.me +noall +answer +identify

dig test.home.lan +noall +answer +identify
Нажмите, чтобы развернуть и увидеть больше

На вид всё ок 😌. Но я больше рекомендую вариант с systemd-resolved.

Добавление внешних серверов в Komodo

Одна из ключевых фич Komodo - это возможность оркестрировать контейнерами, которые работают на удалённых серверах.

Далее покажу пример настройки и запуска агента (periphery) на удалённой машине с IP 192.168.122.31.

Установка komodo-periphery на удалённый хост для управления с помощью локального Komodo

Безусловно, на удалённом хосте должен быть установлен Docker Engine:

BASH
sudo curl https://get.docker.com/ | bash
Нажмите, чтобы развернуть и увидеть больше

Создаём рабочую директорию, выставляем права и создаём compose файл:

BASH
sudo mkdir -p /opt/periphery && sudo chmod 700 /opt/periphery

sudo vim /opt/periphery/compose.yaml
Нажмите, чтобы развернуть и увидеть больше

После наполняем его:

YAML
---

services:
  komodo_periphery:
    image: ghcr.io/moghtech/komodo-periphery:2.0
    labels:
      komodo.skip:
    container_name: komodo-periphery
    stop_grace_period: 1m
    cpus: 1
    mem_limit: 1G
    hostname: komodo-periphery
    restart: on-failure
    env_file: ./.env
    ports:
      - 192.168.122.31:8120:8120
    volumes:
      - ${PERIPHERY_ROOT_DIRECTORY}:${PERIPHERY_ROOT_DIRECTORY}
      - /var/run/docker.sock:/var/run/docker.sock
      - /proc:/proc
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
Нажмите, чтобы развернуть и увидеть больше

Теперь создаём и наполняем переменные окружения:

BASH
sudo vim /opt/periphery/.env
Нажмите, чтобы развернуть и увидеть больше
BASH
TZ=Europe/Moscow
PERIPHERY_ROOT_DIRECTORY=/opt/periphery
PERIPHERY_PASSKEYS=
PERIPHERY_DISABLE_TERMINALS=false
PERIPHERY_SSL_ENABLED=true
PERIPHERY_INCLUDE_DISK_MOUNTS=/etc/hostname
PERIPHERY_LOGGING_PRETTY=false
PERIPHERY_PRETTY_STARTUP_CONFIG=false
PERIPHERY_BIND_IP=0.0.0.0
Нажмите, чтобы развернуть и увидеть больше

Теперь создадим юнит Systemd для автозапуска Periphery при загрузке ОС:

BASH
sudo vim /etc/systemd/system/komodo-periphery.service
Нажмите, чтобы развернуть и увидеть больше
BASH
[Unit]
Description=Komodo periphery docker stack services
Requires=docker.service
After=docker.service

[Service]
Restart=always
RestartSec=5
User=root
Group=root
WorkingDirectory=/opt/periphery
ExecStartPre=/usr/bin/sleep 5
ExecStart=/usr/bin/docker compose up
ExecStop=/usr/bin/docker compose down

[Install]
WantedBy=multi-user.target
Нажмите, чтобы развернуть и увидеть больше

Перечитываем конфиг Systemd и запускаем наш сервис:

BASH
sudo systemctl daemon-reload

sudo systemctl enable --now komodo-periphery

systemctl status komodo-periphery

sudo docker compose -f /opt/periphery/compose.yaml logs -f komodo_periphery
Нажмите, чтобы развернуть и увидеть больше

Если видим такое, значит всё ок:

Теперь возвращаемся в интерфейс Komodo: “Servers” –> “New Server”, указываем имя, например, rustfs.home.lan:

Тут активируем сервер “Enabled” и указываем его адрес:порт. В моём случае это https://192.168.122.31:8120:

Нажимаем “Save” и при успешном подключении увидим:

Создание compose stack - RustFS (S3 storage)

В целом наша лаборатория уже в рабочем состоянии и готова выполнять свои задачи. Давайте для примера добавим еще один стек, например, RustFS - S3-совместимное хранилище, которое выступает альтернативой печально известному MinIO.

Переходим в “Stacks” –> “New Stack”, указываем имя rustfs и выбираем наш удалённый сервер rustfs.home.lan:

Далее выбираем режим UI Defined и аналогичным образом заполняем поля “Compose File”:

YAML
---
# https://github.com/rustfs/rustfs/blob/main/docker-compose-simple.yml
# https://github.com/rustfs/rustfs/blob/main/docker-compose.yml

services:
  rustfs:
    image: rustfs/rustfs:1.0.0-alpha.90
    container_name: rustfs
    restart: unless-stopped
    stop_grace_period: 30s
    cpus: 2
    mem_limit: 2G
    user: "root:root"
    env_file: ./.env
    healthcheck:
      test:
        [
          "CMD",
          "sh", "-c",
          "curl -f http://127.0.0.1:9000/health && curl -f http://127.0.0.1:9001/rustfs/console/health"
        ]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
    ports:
      - "192.168.122.31:9000:9000" # S3 API port
      - "192.168.122.31:9001:9001" # Console port
    volumes:
      - ./data/storage/:/data/
      - ./data/logs/:/app/logs/
      - ./data/certs/:/opt/tls/ # TLS configuration, you should create tls directory and put your tls files in it and then specify the path here
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
Нажмите, чтобы развернуть и увидеть больше

и “Environment”:

BASH
# https://docs.rustfs.com/installation/docker/#complete-parameter-configuration-example
RUSTFS_UID="root"
RUSTFS_GID="root"
TZ=Europe/Moscow
# RUSTFS_VOLUMES=/data/rustfs{0..3} # Define 4 storage volumes
RUSTFS_ADDRESS=0.0.0.0:9000
RUSTFS_CONSOLE_ADDRESS=0.0.0.0:9001
RUSTFS_CONSOLE_ENABLE=true
RUSTFS_CORS_ALLOWED_ORIGINS=*
RUSTFS_CONSOLE_CORS_ALLOWED_ORIGINS=*
RUSTFS_ACCESS_KEY=ivan
RUSTFS_SECRET_KEY=3QuZHlIh6KDtnX0SBElGa8nI2xZAtSNb
RUSTFS_OBS_LOGGER_LEVEL=info
RUSTFS_TLS_PATH=/opt/tls
# RUSTFS_OBS_ENDPOINT=http://otel-collector:4318
Нажмите, чтобы развернуть и увидеть больше

В переменной RUSTFS_ACCESS_KEY указываем логин администратора, а в RUSTFS_SECRET_KEY задаём пароль. Можно также сгенерить через pwgen:

BASH
pwgen -s 32 1
Нажмите, чтобы развернуть и увидеть больше

Теперь “Save” и “Deploy”:

Самое время настроить проксирование. Идём в наш Nginx: “Прокси Хосты” –> “Добавить Прокси-хост”.

Создаём запись для админки RustFS:

Следом создаём запись для самого S3:

Переходим по https://rustfs.home.lan, вводим логин (RUSTFS_ACCESS_KEY) и пароль (RUSTFS_SECRET_KEY):

Можете создавать бакеты:

И обращаться к ним по адресу s3.home.lan. Например, с помощью утилиты rclone, по которой я недавно делал статью про монтирование удалённых хранилищ:

BASH
sudo apt install -y rclone

mkdir -vp ~/.config/rclone

cat << EOF > ~/.config/rclone/rclone.conf
[rustfs]
type = s3
provider = Minio
endpoint = https://s3.home.lan
access_key_id = ivan
secret_access_key = 3QuZHlIh6KDtnX0SBElGa8nI2xZAtSNb
# force_path_style = true
# no_check_bucket = true
EOF
Нажмите, чтобы развернуть и увидеть больше

Проверяем:

BASH
rclone ls rustfs:

rclone mkdir rustfs:doc

rclone copy /usr/share/doc/docker-ce rustfs:doc

rclone ls rustfs:doc
Нажмите, чтобы развернуть и увидеть больше

Работает😌

Послесловие

Фух, как обычно, путь был тернист, но мы справились 😉👨‍💻.

Теперь у нас есть полноценная лаборатория, в которой можно разрабатывать, тестировать и эксплуатировать различные сервисы с большим удобством 😌.

В следующей заметке я покажу, как создавать стеки, используя тертий вариант - через Git репозитории. Покажу как безопасно хранить env файлы в Git и автоматизировать процедуру деплоя при пуше изменений в репо.

Также у меня есть готовый Ansible playbook для развёртывания komodo-periphery на удалённые хосты. Его я также выложу отдельной заметкой. Не пропустите!

Добавляйтесь в наш канал в телеге и Вороний чат там же. У нас там дружелюбное (я слежу за этим) сообществом пингвинов 🐧🐧🐧. Там же можете смело задавать вопросы по материалам блога.

Спасибо, что читаете. До связи! 👋

Полезные материалы

Авторские права

Автор: Иван Чёрный

Ссылка: https://r4ven.me/virtualization/udobnaya-docker-laboratoriya-s-blekdzhekom-i-web-gui/

Лицензия: CC BY-NC-SA 4.0

Использование материалов блога разрешается при условии: указания авторства/источника, некоммерческого использования и сохранения лицензии.

Начать поиск

Введите ключевые слова для поиска статей

↑↓
ESC
⌘K Горячая клавиша