🏠: сайт

Страничка мониторинга опять в строю

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

Конечно, такой вариант мне не годился, но я заметил кое-что интересное, а именно — cAdvisor работает с примонтированным на чтение корнем хостовой системы, чтобы получать информацию собственно о хосте. Тогда я полез в гитхаб-репозиторий своего любимого phpsysinfo и обнаружил, что там появилась инструкция по запуску в Докере, что свидетельствовало о развитии этого направления (я года три не следил за новинками в этой программе), а также плагин, получающий информацию о контейнерах. Не хватало только одного — отображения информации о хостовой системе при работе самого сервиса в контейнере, о чём я написал разработчику, сославшись на подход, применяемый в cAdvisor.

Разработчик оказался невероятно отзывчивым и за 3 дня функционал в виде параметра ROOTFS="/rootfs", позволяющий задавать альтернативный путь к корню, был добавлен, и подправлены ошибки реализации. Настройка phpsysinfo в этом случае немного отличается — везде, где в обычных условиях запрос информации шёл в режиме ACCESS="command", теперь это сделать невозможно, так как из контейнера команды на хост, естественно, не передаются; нужно идти путём ACCESS="data" — когда хост периодически сам выполняет запросы и кладёт файл с результатом в подкаталог <phpsysinfo>/data.

Изображение без описания

Например, для параметров SMART и для Docker нужно добавить в /etc/crontab на хосте примерно следующее:

### phpsysinfo ###
# Docker containers
*/30 * * * * root docker stats --no-stream --format 'table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.MemPerc}}\t{{.NetIO}}\t{{.BlockIO}}\t{{.PIDs}}' > /var/lib/docker/volumes/home_phpsysinfo/_data/mon/data/docker.tmp
# SMART
*/30 * * * * root smartctl --all /dev/sda > /var/lib/docker/volumes/home_phpsysinfo/_data/mon/data/smart0.tmp

Я не стал использовать идущий в комплекте Dockerfile, а сделал по уже привычной схеме: nginx, php-fpm и один именованный общий том.

Изображение без описания

Красота вернулась!

P. S. Совсем забыл: пару дней назад добавил ещё и Watchtower — сервис автообновления образов Докера.

Переезд в Docker

Устройство этого сайта на сегодняшний день

Наконец-то ковыряние Докера привело к чему-то практическому. Конечно, и раньше я ставил его на работе и поднимал там всякие сервисы, но это были одиночные контейнеры и небольшая настройка. Сейчас реализована задача посложнее — переезд с моего одноплатника Orange Pi PC 2, работавшего веб-сервером без малого 4 года (сколько воды утекло с тех пор!), на неттоп, который я купил в 2016 году, завершивший свою карьеру настольного компьютера, со вставленным туда SSD Samsung 850 EVO 250 ГБ, также освободившийся от настольных задач, и смена парадигмы хостинга с монолита на микросервисы.

Технических подробностей здесь особо не будет (хотя это смешно звучит: ничего, кроме них, тут, в общем-то, и нет), потом добавлю что-то в справочник, а пока просто фиксирую по горячим следам.

На старом сервере стоял Armbian, веб-сервер Apache и база данных MySQL. Был единый каталог /var/www/html, где в корне лежал Wordpress, а в дополнительно созданных подкаталогах — другие сервисы: в /cloud — Nextcloud, в /wiki — Dokuwiki, в /mon — phpSysInfo, позже был добавлен Webtrees в одноимённую подпапку.

Не то чтобы мне нужно было позарез переезжать на новую платформу, но меня немного беспокоило, что хранилищем выступают флешки, и система стоит на карточке microSD. Хоть логи в Armbian и пишутся в память, тем не менее, ресурс флеш-носителей довольно мал — несколько месяцев назад, например, померла флешка для записи резервных копий. Ну и, конечно, хочется освоить что-то новое и быть в курсе современных прикладных направлений в ИТ. Наконец, желательно иметь более переносимую систему, которая не так привязывается к железу и в перспективе будет работать в кластере.

На неттоп, в котором памяти стало 4 ГБ после обмена с ноутбуком, была установлена Ubuntu Server 20.04 LTS с ядром HWE и Docker в качестве платформы. Затем я перенёс туда наработки, которые я делал на тестовых виртуальных машинах, и занялся миграцией данных.

Задача, главным образом, осложнялась тем, что у меня есть только одно доменное имя, и все сервисы должны работать не на поддоменах, что очень просто настраивается, а на путях после доменного имени (префиксах). Многие современные сервисы, упакованные в контейнеры, уже имеют поддержку разных режимов работы через реверс-прокси, но некоторые либо не имеют этой поддержки вовсе, либо она есть, но не работает, как в случае с Nextcloud, где можно указать параметр overwritewebroot, но работать он не будет. Из-за этого пришлось собирать Nextcloud по кускам самому. Но это даже и к лучшему, потому что официальный контейнер Nextcloud, по-хорошему, противоречит самой идее микросервисов, так как там в одном контейнере находится сразу несколько работающих процессов, что больше похоже на виртуальную машину; к тому же, при самостоятельной сборке начинаешь лучше понимать устройство системы.

Я всегда стремлюсь к экономии ресурсов, и по возможности использую либо чистый контейнер Alpine Linux (например, для php-fpm — так уж вышло), либо вариант нужного мне сервиса на базе Alpine. Иногда стремление сэкономить выходит боком — я долго возился с «лёгким» веб-сервером Lighttpd, но в случае с Webtrees не смог решить задачу «красивых ссылок» (pretty URLs) даже с помощью специального форума, и в результате решил остановиться на Nginx как самом модном и распространённом варианте на сегодняшний день, для которого везде есть куча конфигураций.

Порой я упирался в непонимание каких-то вещей, например, как раздавать права на томах, если туда смотрят 2 контейнера — nginx и php-fpm, которые работают от разных пользователей? И как раздать эти разрешения с хоста, где таких пользователей вообще нет? Заводить их там не вариант же.

Заставить работать nginx от учётки www-data у меня не вышло, но потом оказалось, что достаточно раздавать права на том с данными только для php-fpm и nginx можно вообще не трогать, а с хоста можно задавать разрешения даже для несуществующих пользователей, если просто указывать совпадающий ID:

sudo chown -R 82:82 /var/lib/docker/volumes/home_cloud/_data/cloud
# Впрочем, правильнее, наверное, так:
docker exec cloud-php chown -R www-data:www-data /var/www/html/cloud

Отдельная песня с реверс-прокси. Например, рабочий конфиг ярлыков для Nextcloud, чтобы внутри него при проверке получить зелёную галочку, оказался такой:

labels:
  - "traefik.enable=true"
  - "traefik.http.routers.nc.rule=PathPrefix(`/cloud`,`/.well-known`)"
  - "traefik.http.routers.nc.middlewares=nc-dav,nc-wellknown,nc-sts"
  - "traefik.http.middlewares.nc-dav.redirectregex.regex=(.*)/.well-known/ca(rd|l)dav"
  - "traefik.http.middlewares.nc-dav.redirectregex.replacement=$$1/cloud/remote.php/dav/"
  - "traefik.http.middlewares.nc-wellknown.replacepathregex.regex=^(/.well-known.*)"
  - "traefik.http.middlewares.nc-wellknown.replacepathregex.replacement=/cloud/index.php$$1"
  - "traefik.http.middlewares.nc-sts.headers.stspreload=true"
  - "traefik.http.middlewares.nc-sts.headers.stsseconds=31536000"

И на это уходят дни и недели. Иногда думаешь — да ну всё это к чёрту, потом опять начинаешь долбить эту стену, пока, наконец, не пробьёшся.

Помимо тех сервисов, которые у меня были, я добавил новые:

  • Photoprism — фото- и видеогалерея с распознаванием лиц, геолокацией, распознаванием дубликатов, доступом по ссылкам и т. п.
  • Bepasty — аналог Pastebin, но не только для текста. Можно выкладывать всё, что угодно.
  • Alltube — веб-морда для старого доброго youtube-dl.

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

Есть и убытки — не переехала страничка мониторинга, так как в контейнере она хоста не увидит, а на самом хосте поднимать ради этого веб-сервис глупо. Тандем Prometheus + Grafana — это довольно громоздко, трудоёмко и не очень-то осмысленно ради такого мелкого результата. Посмотрим позже, пока нужно хотя бы наладить какое-то резервное копирование.

Продолжение следует.

Подкручиваем HTTPS

Больше трёх лет назад я делал подобную заметку, настало время дальнейшего пересмотра настроек. Я мало смыслю в безопасности, но зато люблю, когда онлайн-проверки светятся зелёным. За прошедшее время появился протокол HTTP/2, который я включил в конце 2017-го, и TLS 1.3, а версии TLS 1.0 и 1.1 уже признаются устаревшими с марта этого года, и отправляются на заслуженную пенсию составлять компанию уже находящемуся там SSL.

Итак, чтобы выключить все протоколы, кроме самых новых и надёжных, нужно добавить в файл конфигурации Апача, например, /etc/apache2/sites-available/default-ssl.conf (у меня другой файл, который создаёт Let’s Encrypt), следующее:

# Set Forward Secrecy
SSLProtocol -all +TLSv1.2 +TLSv1.3
SSLHonorCipherOrder on
SSLCipherSuite HIGH:!aNULL:!MD5:!3DES

# Strict transport security
<IfModule mod_headers.c>
 Header always set Strict-Transport-Security "max-age=15768000; includeSubDomains"
 Header always set Referrer-Policy "no-referrer-when-downgrade"
</IfModule>

С TLS 1.3, по ощущениям, действительно работает быстрее — ведь для установки защищённого соединения ему нужно меньше согласований. SSLHonorCipherOrder on — это включение расстановки приоритета алгоритмов шифрования самим сервером, что рекомендуется.

Также, я включил в Апаче поддержку OCSP Stapling — вроде бы полезная вещь — и, забавы ради, HSTS preloading, но это уже совсем необязательно.

Результат обстоятельного теста на Ssllabs после настройки:

Список других полезных тестов:

Переехал на новый сервер

Полторы недели назад наконец-то перенёс свой сайт на новый сервер. «Сервер» — это звучит гордо: это такой же, что и раньше, размером с сигаретную пачку пластиковый корпус, в котором заключена маленькая печатная плата. Тем не менее, это полноценный сервер, чему я не перестаю удивляться.

Модель — Orange Pi PC 2, от предыдущей модели с почти таким же названием (Orange Pi PC Plus) он отличается более мощным процессором, гигабитным сетевым интерфейсом и отсутствием wi-fi, который мне и не нужен в данном случае.

Orange Pi PC 2

С середины сентября, то есть, со времени, как он доехал ко мне из Китая, я не мог дождаться от него стабильной работы — я пробовал дистрибутив за дистрибутивом, но он перезагружался во время установки программ, мог вообще не запускаться — в общем, ни о каком разумном применении речь не шла. Работала, конечно, какая-то версия полугодичной давности, но нужно было заморозить версию ядра и не обновлять его совсем, при первом же обновлении начинались проблемы — это меня совершенно не устраивало. Я уже начал жалеть, что купил эту плату, и отложил переезд на неопределённый срок. Выяснилось, что сейчас нужно сначала узнать, поддерживается ли железка какой-либо из операционных систем, прежде чем её покупать. Раньше как-то само собой подразумевалось, что есть аппарат — а софт под него найдётся, теперь это неверно: железка может выйти на рынок не поддерживаемая вообще ничем, то есть, хороший софт сейчас важнее хорошего железа.

Несколько недель я вообще не трогал плату, устав наблюдать внезапные перезагрузки. Тем временем, ядро Linux обновлялось, вбирая в себя поддержку всё новых и новых устройств и избавляясь от ошибок, а ребята из Armbian постоянно допиливали свой дистрибутив. Где-то в начале ноября я решил попробовать новую сборку Armbian — и с удивлением заметил, что перезагрузки прекратились. Выждав примерно неделю, установив несколько обновлений системы и убедившись, что всё работает стабильно, я перевёз сайт на новый одноплатник.

Нужно сказать, что на этом компьютере и сейчас всё небезоблачно — например, выключить его командой shutdown из консоли вообще невозможно, только выдёргиванием из розетки, а из-за лицензионных ограничений драйверы под Linux для видеоускорителя Mali-450 могут вообще никогда не увидеть свет, но для моих целей это не нужно, так что я доволен результатом. Из дополнительных плюсов — процессор меньше греется. Безо всякого охлаждения, температура процессора в покое 33-40°, на старом сервере было 44-50°.

Также, я поменял страничку мониторинга — eZ Server Monitor заменил на phpSysInfo, описанный в предыдущей публикации, потому что он умеет определять имя процессора, в отличие от предшественника, пишущего «нет данных». А ещё у него есть мобильное приложение для телефона, непонятно зачем сделанное, но сам по себе факт забавный. Вот как это выглядит:

phpSysInfo

phpSysInfo

Обнаружил интересную программу для мониторинга — phpSysInfo. Это аналог eZ Server Monitor, который я использую сейчас, но очень гибко настраиваемый и более функциональный — он умеет работать со многими пакетами слежения за состоянием оборудования и работы с датчиками (HDDtemp, LMSensors, ThermalZone и т. д., всего более 15), имеет подключаемые модули, из которых особенно примечателен SNMPPInfo, который может выводить информацию с принтеров (а теоретически — со всего, что умеет работать с SNMP). Справки нет, потому что файл настроек тщательно откомментирован.

Приятным дополнением к вышеперечисленному является наличие русского перевода и набор красивых визуальных стилей. Вот как это выглядит после минимальной настройки на моём Orange Pi PC 2: