Bash Days | Linux | DevOps
23.3K subscribers
151 photos
25 videos
663 links
Авторский канал от действующего девопса

Самобытно про разработку, devops, linux, скрипты, сисадминство, техдирство и за айтишную жизу.

Автор: Роман Шубин
Реклама: @maxgrue

MAX: https://max.ru/bashdays

Курс: @tormozilla_bot
Блог: https://bashdays.ru
Download Telegram
😀😃😄😁😆

🔧 Утилиты: #utils
💳 Таблицы: #sheets
Скрипты: #bash
🎙 Мониторинг: #monitoring
🤔 Отладка: #debug
🎃 Линукс: #linux
✉️ Nginx: #nginx
📦 GIT: #git
📊 Mysql: #mysql
📱 Сервисы: #services
🔄 Девопс: #devops
🛡 Безопасность: #security
👻 Игры: #games
🌐 Сети: #networks
💬 Будни: #рабочиебудни
Please open Telegram to view this post
VIEW IN TELEGRAM
👍11118
Сегодня я снова научу тебя плохому хорошему. Про prometheus я думаю все знают. Но не все знают, что на bash можно за несколько минут написать собственный экспортер метрик. Дада, ты не ослышался — не обязательно быть golang сеньором, чтобы делать крутые и полезные штуки. Погнали чо!

У prometheus есть основной экспортер node_exporter, который собирает 100500 метрик с хоста. Ставится отдельно и элементарно. Гугол тебе подскажет. У меня он установлен везде где хоть что-то напоминает linux. Короче бест-практик.

Эт я к чему. У node_exporter есть прекрасный ключик --collector.textfile.directory. Из коробки он не прописан в systemd, поэтому нужно самостоятельно прописать руками в файле /etc/systemd/system/node_exporter.service (у тебя может называться по другому).

ExecStart=/usr/local/bin/node_exporter --collector.textfile.directory /tmp/textfile_collector

Суть такая, указываем ему директорию, которая будет регулярно опрашиваться на наличие .prom файлов. Соответственно эти .prom файлы мы будем генерировать с помощью bash скрипта, который засунем в крон. Файл представляет собой текстовый документ в определенном формате.

А далее все нужные нам метрики попадут автоматом в prometheus, а там глядишь и в grafana красиво всё станет.

Лепота! 🫥

Покажу на примере моего скрипта, который забирает количество оставшихся писем в квоте по API с почтового сервиса smtp и передает напрямую в prometheus.

#!/bin/bash

MAINDIR=/tmp/text_collector
METRICS=smtp.prom

rm $MAINDIR/$METRICS

count=$(curl -s -X GET "https://api.smtp/v1/user" -H "accept: application/json" -H "Authorization: superapipassword» | jq '.quota')

echo "smtp_quota{service=\"smtp_exporter\"} "$count >> $MAINDIR/$METRICS

Кидаем его в крон */1 * * * * и на выходе получаем в папке /tmp/text_collector файл smtp.prom в котором будет нечто подобное:

smtp_quota{service="smtp_exporter"} 26818

И это всё! Готовый экспортер на коленке за несколько минут! Все данные по квоте теперь лежат в параметре smtp_quota. А дальше выводим графики, ставим алерты, балдеем.

С помощью curl и jq можно парсить вообще всё что угодно и запихивать в prometheus, пусть страдает, он для этого и был создан! Ну а больше инфы по ключикам node_exporter можешь получить тут, может чего еще интересного откопаешь и с нами поделишься.

tags:
#bash #monitoring

🟢 Подпишись: @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
👍791
Пилил я как-то задачу связанную с мониторингом тестового сервера. С одной стороны ну что там сложного, воткнул везде node_exporter и вперед, пусть prometheus ходит и забирает с них метрики. Всё логично.

Но есть закон подлости: если оценить задачу в 5 минут, то обязательно вылезут подводные камни. Собственно они и вылезли. Сейчас расскажу.

Тестовый сервер представляет нечто подобное:

- балансировщик (белый айпишник)
- фронтэнд (192.168.0.3)
- бекэнд (192.168.0.4)
- база (192.168.0.5)

У [балансировщика] есть белый айпишник, у остальных (фронтэнд, бекэнд, база) только серые. Хм… ну и как prometheus будет ходить на серые инстансы и забирать метрики? Да никак! 🤒

Уффф. Пошел смотреть в сторону pushgateway, чтобы инстансы сами метрики пушили в prometheus или сразу в VictoriaMetrics.

VictoriaMetrics — быстрая и масштабируемая СУБД для хранения и обработки данных в форме временного ряда (запись образует время и набор соответствующих этому времени значений, например, полученных через периодический опрос состояния датчиков или сбор метрик).

Но тут снова грабли. У prometheus тоже нет белого айпи. Это провал! Какой-то замкнутый круг получается. Забрать метрики не можем, отдать тоже не можем.

Выдавать белые айпишники ой как не хочется, по причине — лень настраивать фаерволы и прочую шляпу. Но что же делать? Правильно — достаём костыли!

Так как у тестовых серверов на [балансировщике] есть белый ip адрес, будем привлекать iptables и жёстко роутить.

На балансировщике с белым ip, выполняем:

-A PREROUTING -p tcp -m tcp --dport 1001 -j DNAT --to-destination 192.168.0.3:9100
-A PREROUTING -p tcp -m tcp --dport 1002 -j DNAT --to-destination 192.168.0.4:9100
-A PREROUTING -p tcp -m tcp --dport 1003 -j DNAT --to-destination 192.168.0.5:9100
-A POSTROUTING -j MASQUERADE

Идея заключается в том, что с портов 1001-1003 (на балансировщике) мы попадаем на внутренние инстансы с серыми айпишниками и забираем свои метрики с портов 9100.

А в prometheus говорим, иди на внешний айпишник балансировщика с портами 1001-1003 и выгребай данные с серых инстансов.

prometheus.yml
---
- targets:
- balancer:1001
labels:
env: test
role: frontend
- targets:
- balancer:1002
labels:
env: test
role: backend

Красота! Кейс рабочий, костыли присутствуют, графики красивые, тестировщики довольные. Ну а что еще надо? Think different! 🧠

tags: #рабочиебудни #monitoring #networks

🟢 Подпишись: @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
👍1311
Про интересный факап и траблшутинг.

Обратился клиент — у нас mysql реплика не работает. Вернее работает, но отстала всего лишь на 3 месяца.

На вопрос — а хули вы 3 месяца сидели, у вас же мониторинг есть?

Очевидный ответ — да, есть, но оно молчит.

Ладно, полез разбираться. SHOW SLAVE STATUS\G;

А там ошибки брынчат, как хуи в бидоне.

Error 'Cannot delete or update a parent row: a foreign key constraint fails'


Ну это ладно, ошибка и ошибка, тут понятно что делать — НИЧЕГО.

Так как реплика используется чисто аналитиками на потыкать, игнорим эту ошибку через my.cfg. Быстрофикс.

Для продуктовой реплики такое делать - НЕЛЬЗЯ!

Самый важный вопрос — какого хера мониторинг 3 месяца молчал?

Тут уже интереснее. Реплика заведена в prometheus, экспортеры есть, все дела.

Но из графаны сервер пропал, хотя год назад я ее точно там видел.

Думаем… Думаем… Смотрю графану, мониторится поле: replica_seconds_behind

Хм, лезу обратно на реплику, а там сроду нет mysql_exporter. Что же это тогда такое?

Копаем вглубь и видим, что node_exporter мониторит папку /tmp на наличие файликов .prom.

Ага… То есть метрики с mysql реплики собирает какой-то bash скрипт по крону, генерит текстовичок и отдает в prometheus.

Типа такого:

replica_slave_io_running{host="replica"} 1
replica_seconds_behind{host="replica"} 1234567


Да, оно прекрасно работало, до момента пока не вылезла ошибка: Cannot delete or update a parent row

Соответственно текстовый файл replica.prom получился в таком формате:

replica_slave_io_running{host="replica"} 1
replica_seconds_behind{host="replica"} Null


Ну а дальше prometheus такое распарсить не смог (он хочет циферки, а не буковки) и тихонечко вывел эту ноду из графаны и вообще отовсюду. Ну и аллерты в придачу. На что им тригериться если ноды нет нигде?

Прикол в том, что во время возникновения ошибки, поле Seconds_Behind_Master в mysql принимает значение Null, а не продолжает дальше считать на сколько отстала реплика.

А вот и bash скрипт, который собирал метрики:

#!/bin/bash

MAINDIR=/tmp
METRICS=rstatus.prom
HOST="replica"

SLAVE_IO_RUNNING=$(mysql -e 'SHOW SLAVE STATUS \G' | grep 'Slave_IO_Running'| awk '{print $2}')
SLAVE_SECONDS_BEHIND=$(mysql -e 'SHOW SLAVE STATUS \G' | grep 'Seconds_Behind_Master'| awk '{print $2}')

if [[ "$SLAVE_IO_RUNNING" == "Yes" ]]; then
J=1
echo 'replica_slave_io_running{host="'$HOST'"}' $J > $MAINDIR/$METRICS
else
J=0
echo 'replica_slave_io_running{host="'$HOST'"}' $J > $MAINDIR/$METRICS
fi

echo 'replica_seconds_behind{host="'$HOST'"}' $SLAVE_SECONDS_BEHIND >> $MAINDIR/$METRICS


Работа над ошибками проведена, инцидент разобран. Ни одна жопа на ретроспективе пока не пострадала, но возможно дело времени.

Как писать подобные экспортеры я накидывал в этом посте.


И всегда помни — если изобретаешь велосипед, всегда обрабатывай эксепшены!

tags: #devops #debug #bash #monitoring

🔔 @bashdays
Please open Telegram to view this post
VIEW IN TELEGRAM
78
Такс, пора выходить из новогодней комы и включаться в работу.

При манипуляции с логами, ты можешь столкнуться с какими-то непонятными local0 – local7. Чо эт ваще такое?

Это «Фасилити»… Ладно, это что-то вроде категорий в которые можно завернуть свои логи и потом уже по ним грепать.

Суть этих категорий — не смешивать выхлоп пользовательских программ с системными логами.


Системные логи это: auth, daemon, mail, kern и т.д. Эти штуки ты можешь встретить например при настройке rsyslog конфига.

Рассмотрим пример:

import syslog

syslog.openlog(ident="BashDays", facility=syslog.LOG_LOCAL0)
syslog.syslog(syslog.LOG_INFO, "Привет из local0")


Не проверял, но суть ты поймешь.

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

Например, закинуть его в эластик:

local0.* @log.bashdays.com:514


Ну или обработать локально в файл:

local0.* /var/log/local0.log


Так же можно завернуть необходимую группу приложений в эту категорию и отделить ее от системных логов.

Практика использования

local0: логи веб-сервера
local1: для docker контейнеров
local2: логи бекапов
local3: логи крон скриптов
local4–local7: резервные


Такие вот пироги. Ничо в этом сложного нет. Просто категории для изоляции, гибкости и скалируемости.

Изучай!

tags: #linux #monitoring

🔔 @bashdays➡️ @gitgate
Please open Telegram to view this post
VIEW IN TELEGRAM
1064
Вчера в посте пролетала строчка:

local0.* @log.bashdays.com:514


И тут как раз частый вопрос - чо за символ «собаки» перед названием сервера?

Магии тут нет, символ «@» означает протокол передачи UDP.

Надеюсь ты знаешь, что UDP не гарантирует доставку. Если сеть перегружена или приходят «сетевые ножницы», пакет может — проебаться.

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

local0.* @@log.bashdays.com:514


По итогу получаешь:

- Подтверждение доставки (сервер подтверждает приём данных).
- Повторную отправку пакетов, если они теряются.
- Сохранение порядка доставки пакетов.

Короче тут сам выбираешь что тебе важнее, либо скорость, либо надежность.

Запоминаем:

Раз «собака» = UDP
Два «собака» = TCP

Что чаще применяют?

UDP, но если логи прям критичные то TCP, нет серебряной пули, всё зависит от конкретной ситуации. Но тут речь не про это, а про «собак».

Такие дела.

tags: #linux #monitoring

🔔 @bashdays➡️ @gitgate
Please open Telegram to view this post
VIEW IN TELEGRAM
100