script — запись сессии терминала для документации или разбора инцидента
Сделали сложную последовательность действий, которая привела к починке системы. Через месяц потребуется повторить, а Вы уже не помните детали. Или нужно показать коллеге точную последовательность команд и их вывод.
Память человека - ненадёжный носитель. Сессия терминала, записанная в файл, - надёжный.
➤ Вариант 1 (Простая запись): запуск
➤ Вариант 2 (Запись с меткой времени): полезно для расследования инцидентов, чтобы понимать, в какой момент что произошло.
➤ Вариант 3 (Тихий режим): запись без сообщений о начале и конце.
➤ Вариант 4 (Дозапись): добавление к существующему логу.
➤ Приложить к постмортему.
➤ Использовать для обучения новых сотрудников.
➤ Разобрать, чтобы понять, какая именно команда что-то сломала.
➤ Воспроизвести для демонстрации.
🌐 @helcode
Сделали сложную последовательность действий, которая привела к починке системы. Через месяц потребуется повторить, а Вы уже не помните детали. Или нужно показать коллеге точную последовательность команд и их вывод.
script записывает всё, что происходит в терминале - и ввод, и вывод - в файл.Память человека - ненадёжный носитель. Сессия терминала, записанная в файл, - надёжный.
➤ Вариант 1 (Простая запись): запуск
script начинает запись, exit завершает.script session.log
# ... делаем что-то важное ...
exit
# Всё сохранено в session.log
➤ Вариант 2 (Запись с меткой времени): полезно для расследования инцидентов, чтобы понимать, в какой момент что произошло.
script --timing=timing.txt session.log
# Позже можно воспроизвести сессию с реальными задержками
scriptreplay --timing=timing.txt session.log
➤ Вариант 3 (Тихий режим): запись без сообщений о начале и конце.
script -q session.log
➤ Вариант 4 (Дозапись): добавление к существующему логу.
script -a session.log
script - это автоматизация документирования работы в терминале. Он превращает хаотичную сессию администрирования в структурированный лог, который можно:➤ Приложить к постмортему.
➤ Использовать для обучения новых сотрудников.
➤ Разобрать, чтобы понять, какая именно команда что-то сломала.
➤ Воспроизвести для демонстрации.
P.S. script записывает даже управляющие последовательности (цвета, позиционирование курсора), поэтому файл может содержать "мусор". Для просмотра лучше использовать cat или less -R, чтобы видеть оригинальное форматирование.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍8🔥5❤2
shellcheck — статический анализ для ваших bash-скриптов
Bash-скрипт написан, работает... но почему-то падает на пустых переменных или некорректно обрабатывает пробелы в именах файлов.
Bash - мощный, но коварный язык. Ошибки в нём часто проявляются не сразу, а в самый неподходящий момент.
➤ Вариант 1 (Базовая проверка): просто запустить
➤ Вариант 2 (Интеграция в редактор): плагины для VS Code, Sublime, Vim подсвечивают проблемы прямо во время написания кода.
➤ Вариант 3 (Интеграция в CI/CD): добавление шага в пайплайн, который проверяет все
➤ Вариант 4 (Подавление предупреждений): иногда нужно отключить конкретную проверку, если Вы точно знаете, что делаете.
Каждый скрипт, который живёт дольше одного дня, должен проходить через
🌐 @helcode
Bash-скрипт написан, работает... но почему-то падает на пустых переменных или некорректно обрабатывает пробелы в именах файлов.
shellcheck - это линтер для shell-скриптов, который находит сотни потенциальных ошибок, уязвимостей и неэффективностей, объясняя, что именно не так и как это исправить.Bash - мощный, но коварный язык. Ошибки в нём часто проявляются не сразу, а в самый неподходящий момент.
➤ Вариант 1 (Базовая проверка): просто запустить
shellcheck на скрипте.shellcheck deploy.sh
➤ Вариант 2 (Интеграция в редактор): плагины для VS Code, Sublime, Vim подсвечивают проблемы прямо во время написания кода.
➤ Вариант 3 (Интеграция в CI/CD): добавление шага в пайплайн, который проверяет все
.sh файлы. Если скрипт содержит ошибки — пайплайн падает.# Пример для GitLab CI
shellcheck:
script:
- apt-get install -y shellcheck
- shellcheck *.sh
➤ Вариант 4 (Подавление предупреждений): иногда нужно отключить конкретную проверку, если Вы точно знаете, что делаете.
# shellcheck disable=SC2086
some_command $variable # SC2086: Double quote to prevent globbing and word splitting
shellcheck - это автоматизация повышения качества и надёжности скриптов. Он превращает написание bash-скриптов из шаманства в инженерную дисциплину с обратной связью от инструмента.Каждый скрипт, который живёт дольше одного дня, должен проходить через
shellcheck. Это простое правило убережёт от тонн трудноотлавливаемых багов.P.S. У shellcheck есть онлайн-версия (shellcheck.net), куда можно скопировать код и мгновенно увидеть все проблемы. Полезно, если нет возможности установить локально.
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8❤2🤔1👌1
systemd: сервисы, которые умеют себя обслуживать
Писать скрипты на Bash для запуска демонов и их перезапуска при падении — это изобретение велосипеда.
Скрипт в
➤ Вариант 1 (Базовая устойчивость): простая конфигурация юнита с
➤ Вариант 2 (Зависимости и порядок): правильное указание
➤ Вариант 3 (Ограничение ресурсов): секция
Какие возможности systemd, помимо простого start/stop, Вы используете чаще всего? Мониторинг через journalctl, cgroups или таймеры?
🌐 @helcode
Писать скрипты на Bash для запуска демонов и их перезапуска при падении — это изобретение велосипеда.
systemd — это фреймворк для управления жизненным циклом служб со встроенными возможностями самовосстановления.Скрипт в
/etc/init.d/, который не умеет корректно обрабатывать сигналы и логировать, — это наследие прошлого.➤ Вариант 1 (Базовая устойчивость): простая конфигурация юнита с
Restart=on-failure и RestartSec=5 уже делает сервис намного надежнее.[Service]
ExecStart=/usr/bin/my_daemon
Restart=on-failure
RestartSec=5
StandardOutput=journal
➤ Вариант 2 (Зависимости и порядок): правильное указание
After=network.target и Requires=postgresql.service гарантирует, что сервис запустится только когда его зависимости готовы.➤ Вариант 3 (Ограничение ресурсов): секция
[Slice] и MemoryMax позволяют ограничить потребление памяти, предотвращая «проседание» всей системы из-за одной утечки.systemd — это автоматизация управления процессами на уровне ОС. Он превращает приложение из «просто исполняемого файла» в управляемый, наблюдаемый и устойчивый сервис.Какие возможности systemd, помимо простого start/stop, Вы используете чаще всего? Мониторинг через journalctl, cgroups или таймеры?
P.S. Споры о systemd — бесконечны, но его распространенность в современном Linux-мире делает его знание обязательным. Это не всегда выбор, но это реальность.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍9❤2👌1
Git Hooks: Твой личный робот-помощник
Хотите, чтобы код автоматически прогонял тесты перед каждым коммитом? Или чтобы линтер проверял стиль? Или чтобы скрипт развертывания сам запускался после пушa в
Хуки лежат в папке
Не забудьте дать файлу права на выполнение:
Git Hooks — это скрипты, которые Git запускает в ответ на определенные события (commit, push, rebase и т.д.). Они выполняются локально и позволяют автоматизировать рутину и внедрить контроль качества.
Какой самый полезный или безумный Git Hook Вы когда-либо использовали или хотели бы использовать? Поделитесь идеями!
Настроить
🌐 @helcode
Хотите, чтобы код автоматически прогонял тесты перед каждым коммитом? Или чтобы линтер проверял стиль? Или чтобы скрипт развертывания сам запускался после пушa в
main? Пора познакомиться с Git Hooks.Хуки лежат в папке
.git/hooks/. Пример пре-коммит хука (.git/hooks/pre-commit), который не даст закоммитить код, не прошедший линтинг:#!/bin/sh
echo "Запуск линтера..."
if ! eslint --cache --fix .; then
echo "Линтер нашел ошибки! Коммит отменен."
exit 1
fi
git add . # Добавляем исправления, сделанные линтером
Не забудьте дать файлу права на выполнение:
chmod +x .git/hooks/pre-commitGit Hooks — это скрипты, которые Git запускает в ответ на определенные события (commit, push, rebase и т.д.). Они выполняются локально и позволяют автоматизировать рутину и внедрить контроль качества.
Какой самый полезный или безумный Git Hook Вы когда-либо использовали или хотели бы использовать? Поделитесь идеями!
Настроить
pre-commit хук — это как нанять очень принципиального секьюрити, который не пустит Вас на работу в пижаме. Иногда раздражает, но в итоге все только выигрывают.Please open Telegram to view this post
VIEW IN TELEGRAM
❤4👍3👌1
Автоматическое резервное копирование: спим спокойно
Бэкапы — это как страховка: все знают, что нужны, но мало кто их делает. Исправим это одним скриптом.
"А у нас есть бэкап?" — самый страшный вопрос, который можно услышать после "система легла". Ручные бэкапы ненадежны и забываются.
Вариант 1 (Bash-скрипт + Cron):
Вариант 2 (Python-скрипт с отправкой в облако):
Disaster Recovery — автоматизируем процессы восстановления после сбоев. Правило 3-2-1: 3 копии данных, на 2 разных носителях, 1 копия off-site.
А как у вас с бэкапами? Ручные, автоматические, или по принципу "если продакшен упадет, просто найдем новую работу"?
🌐 @helcode
Бэкапы — это как страховка: все знают, что нужны, но мало кто их делает. Исправим это одним скриптом.
"А у нас есть бэкап?" — самый страшный вопрос, который можно услышать после "система легла". Ручные бэкапы ненадежны и забываются.
Вариант 1 (Bash-скрипт + Cron):
#!/bin/bash
BACKUP_DIR="/backups"
DATE=$(date +%Y%m%d_%H%M%S)
# Бэкап базы данных
pg_dump mydb > $BACKUP_DIR/mydb_$DATE.sql
# Бэкап важных директорий
tar -czf $BACKUP_DIR/app_$DATE.tar.gz /app/data
# Удаляем старые бэкапы (старше 30 дней)
find $BACKUP_DIR -name "*.sql" -mtime +30 -delete
find $BACKUP_DIR -name "*.tar.gz" -mtime +30 -delete
Вариант 2 (Python-скрипт с отправкой в облако):
import boto3
from datetime import datetime
s3 = boto3.client('s3')
backup_file = f"backup_{datetime.now().strftime('%Y%m%d')}.sql"
# Создаем бэкап и загружаем в S3
subprocess.run(['pg_dump', 'mydb', '-f', backup_file])
s3.upload_file(backup_file, 'my-backup-bucket', backup_file)
Disaster Recovery — автоматизируем процессы восстановления после сбоев. Правило 3-2-1: 3 копии данных, на 2 разных носителях, 1 копия off-site.
А как у вас с бэкапами? Ручные, автоматические, или по принципу "если продакшен упадет, просто найдем новую работу"?
P.S. Есть два типа людей: те, кто делают бэкапы, и те, кто еще будет их делать.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7❤2👌2🥱1
Война с плавающим багом в CI
Ваш CI-пайплайн падает раз в два дня из-за плавающего теста, и все делают вид, что не замечают? Сегодня объявляем ему войну. Не игнорируем, а автоматизируем поимку.
Это классика: "У меня работает", "Heisenbug*", который исчезает при попытке отладки. Команда привыкает к красному статусу и перестает ему доверять, что убивает саму идею CI. Ручной перезапуск — это не решение, это признание поражения.
➤ Вариант 1 (Bash + Cron): Пишем скрипт, который дергает API вашего CI (например, Jenkins/GitLab), проверяет последний запуск падающего джоба и в случае ошибки автоматически перезапускает его, отправляя уведомление в Slack.
➤ Вариант 2 (GitHub Actions): используем
Речь об устойчивости и проактивном мониторинге. Система не должна полагаться на бдительность человека. Мы встраиваем механизм самовосстановления для известных, но трудноустранимых проблем. Это тот же принцип, что и в
А в вашей команде есть "призрачный" баг? Как вы с ним боретесь: пишете сложные логи, ставите ретраи или просто молитесь?
🌐 @helcode
Ваш CI-пайплайн падает раз в два дня из-за плавающего теста, и все делают вид, что не замечают? Сегодня объявляем ему войну. Не игнорируем, а автоматизируем поимку.
Это классика: "У меня работает", "Heisenbug*", который исчезает при попытке отладки. Команда привыкает к красному статусу и перестает ему доверять, что убивает саму идею CI. Ручной перезапуск — это не решение, это признание поражения.
➤ Вариант 1 (Bash + Cron): Пишем скрипт, который дергает API вашего CI (например, Jenkins/GitLab), проверяет последний запуск падающего джоба и в случае ошибки автоматически перезапускает его, отправляя уведомление в Slack.
# Пример для GitLab CI с использованием jq и curl
PIPELINE_STATUS=$(curl -s --header "PRIVATE-TOKEN: <your_token>" "https://gitlab.com/api/v4/projects/<project_id>/pipelines/latest" | jq -r '.status')
if [ "$PIPELINE_STATUS" = "failed" ]; then
curl --request POST --header "PRIVATE-TOKEN: <your_token>" "https://gitlab.com/api/v4/projects/<project_id>/pipelines/latest/retry"
curl -X POST -H 'Content-type: application/json' --data '{"text":"Плавающий тест снова упал. Автоперезапуск...»"}' $SLACK_WEBHOOK
fi
➤ Вариант 2 (GitHub Actions): используем
schedule и джоб с условием для автоматического перезапуска только конкретного флаки-теста.jobs:
retry_flaky_test:
if: failure() && contains(github.event.head_commit.message, 'retry flaky test')
runs-on: ubuntu-latest
steps:
- name: Retry the flaky test suite
run: |
echo "Автоматический ретрай запущен"
Речь об устойчивости и проактивном мониторинге. Система не должна полагаться на бдительность человека. Мы встраиваем механизм самовосстановления для известных, но трудноустранимых проблем. Это тот же принцип, что и в
livenessProbe в Kubernetes: если система нездорова, ее нужно перезапустить, прежде чем бить в колокола.А в вашей команде есть "призрачный" баг? Как вы с ним боретесь: пишете сложные логи, ставите ретраи или просто молитесь?
P.S. Автоматический ретрай — это не починка бага, это костыль. Но лучше автоматический костыль, чем кривые костыли ручных ретраев.
*Гейзенбаг - жаргонный термин, используемый в программировании для описания программной ошибки, которая исчезает или меняет свои свойства при попытке её обнаружения.
Please open Telegram to view this post
VIEW IN TELEGRAM
❤2👌2🔥1
Мониторинг производительности: от сбора метрик до визуализации
Цель: настроить полноценную систему мониторинга серверной инфраструктуры
Архитектура: Node Exporter + Prometheus + Grafana
Установка Node Exporter
Настройка Prometheus
Дашборды Grafana
Полезные запросы PromQL:
🌐 @helcode
Цель: настроить полноценную систему мониторинга серверной инфраструктуры
Архитектура: Node Exporter + Prometheus + Grafana
Установка Node Exporter
# Скачивание и установка
wget https://github.com/prometheus/node_exporter/releases/download/v1.6.1/node_exporter-1.6.1.linux-amd64.tar.gz
tar xzf node_exporter-*.tar.gz
sudo mv node_exporter-*/node_exporter /usr/local/bin/
# Создание systemd сервиса
sudo cat > /etc/systemd/system/node_exporter.service << EOF
[Unit]
Description=Node Exporter
After=network.target
[Service]
User=node_exporter
ExecStart=/usr/local/bin/node_exporter
[Install]
WantedBy=multi-user.target
EOF
# Запуск
sudo systemctl daemon-reload
sudo systemctl enable node_exporter
sudo systemctl start node_exporter
Настройка Prometheus
# prometheus.yml
global:
scrape_interval: 15s
scrape_configs:
- job_name: 'node'
static_configs:
- targets: ['node1:9100', 'node2:9100']
metrics_path: /metrics
Дашборды Grafana
# Импорт готовых дашбордов
# Node Exporter Full: id 1860
# Kubernetes cluster monitoring: id 315
Полезные запросы PromQL:
# Использование CPU
100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)
# Доступная память
node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes * 100
# Использование диска
100 - (node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"} * 100)
🌐 @helcode
👍5❤2🔥1
Сила .gitignore: защита от самого себя
Коммит файлов с паролями, конфигурацией IDE или артефактами сборки — это классическая ошибка, которая случается с каждым.
Человеческая память ненадежна. Доверить ей решение, что можно коммитить, а что нет — наивно.
➤ Вариант 1 (Глобальный
➤ Вариант 2 (Специфичный для языка/инструмента): генерация или использование готовых шаблонов для Python (
➤ Вариант 3 (
Доводилось ли Вам «вычищать» историю репозитория из-за случайно закоммиченного секрета? Или .gitignore всегда стоит на страже?
🌐 @helcode
Коммит файлов с паролями, конфигурацией IDE или артефактами сборки — это классическая ошибка, которая случается с каждым.
.gitignore — это не список, это оборонительный периметр Вашего репозитория.Человеческая память ненадежна. Доверить ей решение, что можно коммитить, а что нет — наивно.
➤ Вариант 1 (Глобальный
~/.gitignore_global): для файлов, которые никогда не должны попадать ни в один репозиторий: .DS_Store, Thumbs.db, *.swp, файлы конфигурации Вашего редактора.# Настройка
git config --global core.excludesfile ~/.gitignore_global
➤ Вариант 2 (Специфичный для языка/инструмента): генерация или использование готовых шаблонов для Python (
__pycache__/, *.pyc), Node.js (node_modules/), Java (target/), Go (/vendor/).➤ Вариант 3 (
.gitignore как часть инициализации проекта): автоматическое создание адекватного .gitignore при старте нового проекта через git init или инструменты вроде cookiecutter..gitignore — это проактивная автоматизация. Это предотвращение ошибки до ее совершения. Это один из немногих файлов в проекте, который требует максимально педантичного отношения.Доводилось ли Вам «вычищать» историю репозитория из-за случайно закоммиченного секрета? Или .gitignore всегда стоит на страже?
P.S. Есть сервисы вроде git-secrets или truffleHog, которые сканируют историю на наличие ключей и паролей. Но лучше не допускать их попадания туда.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍5❤2🔥1
ansible / salt — идемпотентность как религияРучное выполнение одних и тех же команд на десятках серверов с риском что-то пропустить или выполнить в разном порядке — это гарантия «дрейфа конфигурации». Инструменты управления конфигурацией (CM) выполняют описание *желаемого состояния* системы, и делают это идемпотентно (повторный запуск не меняет корректно настроенную систему).
Подход «напишите скрипт на bash для настройки сервера» терпит крах, когда нужно понять, нужно ли применять изменение, и что было изменено в прошлый раз.
- Вариант 1 (Простая идемпотентность Ansible): модуль
apt установит пакет, только если его нет. Модуль template создаст файл из шаблона, только если он изменился.- name: Ensure nginx is installed
apt:
name: nginx
state: present
- name: Deploy nginx config
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
owner: root
group: root
mode: '0644'
- Вариант 2 (Сбор фактов и условия): Ansible сначала собирает информацию о системе (facts), что позволяет выполнять задачи только на определенных ОС или при определенных условиях.
- Вариант 3 (Откат и проверка): многие CM-инструменты имеют режим
--check (пробный прогон) и позволяют описывать шаги отката на случай неудачи.Идемпотентность — это "суперсила" автоматизации. Она превращает настройку инфраструктуры из искусства в предсказуемую инженерную дисциплину, где результат не зависит от начального состояния и количества запусков.
P.S. Главный тест на идемпотентность: запустите плейбук дважды подряд. Во второй раз не должно быть изменений (changed=0). Если это так — Вы на правильном пути.
🌐 @helcode
👍5❤2🔥1
Самолечение для Kubernetes: beyond kubectl get pods
В сотый раз получаем алерт, что под упал. В сотый раз вручную делаем
➤ Вариант 1 (Нативные механизмы K8s):
➤ Вариант 2 (Operator Pattern): для сложных stateful приложений (БД, Kafka). Кастомный контроллер (Operator) следит за состоянием и может делать сложные вещи: делать бэкап, ребалансировать партиции*, увеличивать объем хранилища.
➤ Вариант 3 (Скрипт на Bash/Python + CronJob): если нативных механизмов мало. Например, скрипт, который проверяет логи на наличие конкретной ошибки и выполняет кастомную операцию по ее исправлению.
Это воплощение принципа "выбирай исправление, а не оповещение". Мы движемся от мониторинга ("что-то сломалось") к автоматическому реагированию ("я уже пытаюсь это починить"). Это краеугольный камень самоцелительных (self-healing) систем.
* Партиции (или секции) — это отдельные физические или логические части, на которые разбиваются большие наборы данных, например, таблицы в базах данных или разделы в системах обработки данных.
🌐 @helcode
kubectl get pods | grep CrashLoopBackOff - это не диагноз, это крик о помощи. Давайте научим кубер самолечению, чтобы он не просто сообщал о проблеме, а пытался ее исправить.В сотый раз получаем алерт, что под упал. В сотый раз вручную делаем
kubectl delete pod .... Это цифровая "яжемать :)", а не работа инженера. Система должна заботиться о себе сама.➤ Вариант 1 (Нативные механизмы K8s):
livenessProbe и readinessProbe — это основа. Если проба живучести падает, kubelet убивает и пересоздает контейнер.livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 15
periodSeconds: 10
➤ Вариант 2 (Operator Pattern): для сложных stateful приложений (БД, Kafka). Кастомный контроллер (Operator) следит за состоянием и может делать сложные вещи: делать бэкап, ребалансировать партиции*, увеличивать объем хранилища.
➤ Вариант 3 (Скрипт на Bash/Python + CronJob): если нативных механизмов мало. Например, скрипт, который проверяет логи на наличие конкретной ошибки и выполняет кастомную операцию по ее исправлению.
# Пример: поиск и лечение утечки памяти
if kubectl logs my-pod --since=10m | grep -q "OutOfMemoryError"; then
kubectl rollout restart deployment my-app
fi
Это воплощение принципа "выбирай исправление, а не оповещение". Мы движемся от мониторинга ("что-то сломалось") к автоматическому реагированию ("я уже пытаюсь это починить"). Это краеугольный камень самоцелительных (self-healing) систем.
P.S. Идеал — это когда вы спокойно спите, а ваш кластер ночью сам перезапускает поды, рестартит деплоименты и даже делает кофе. Ну, почти.
* Партиции (или секции) — это отдельные физические или логические части, на которые разбиваются большие наборы данных, например, таблицы в базах данных или разделы в системах обработки данных.
🌐 @helcode
👍4❤1🔥1👌1
Сборка самописных утилит на Go. Когда Bash уже мал.
Ваш bash-скрипт для деплоя разросся до 500 строк и стал похож на" Франкенштейна"? Пора переписать его на Go и получить одну бинарку, которую можно кинуть куда угодно.
Bash отлично справляется с маленькими задачами, но когда нужна сложная логика, работа с HTTP API, парсинг сложного JSON — он становится неуклюжим и трудночитаемым.
➤ Простой пример на Go: утилита, которая ходит в API, проверяет статус и шлет уведомление.
➤ Почему Go? Простая компиляция в один бинарный файл, кросс-компиляция, удобная стандартная библиотека (особенно для сетевых задач), нет зависимостей в рантайме.
Речь о выборе правильного инструмента. Bash — для быстрых, тексто-ориентированных задач. Python — для скриптов, где важна скорость разработки и есть много библиотек. Go — для высокопроизводительных, надежных утилит, которые должны работать без проблем в любом окружении.
P.S. Написание утилит на Go — это как собрать своего робота из Лего: удобно, надежно и невероятно приятно, когда он работает.
🌐 @helcode
Ваш bash-скрипт для деплоя разросся до 500 строк и стал похож на" Франкенштейна"? Пора переписать его на Go и получить одну бинарку, которую можно кинуть куда угодно.
Bash отлично справляется с маленькими задачами, но когда нужна сложная логика, работа с HTTP API, парсинг сложного JSON — он становится неуклюжим и трудночитаемым.
➤ Простой пример на Go: утилита, которая ходит в API, проверяет статус и шлет уведомление.
package main
import (
"encoding/json"
"fmt"
"net/http"
"os"
)
func main() {
resp, err := http.Get("https://api.status.io/1.0/status/xyz")
if err != nil {
panic(err)
}
defer resp.Body.Close()
var status Status
json.NewDecoder(resp.Body).Decode(&status)
if status.Status != "operational" {
fmt.Println("Сервис лежит!")
os.Exit(1)
}
fmt.Println("Всё ок!")
}
type Status struct {
Status string `json:"status"`
}
➤ Почему Go? Простая компиляция в один бинарный файл, кросс-компиляция, удобная стандартная библиотека (особенно для сетевых задач), нет зависимостей в рантайме.
Речь о выборе правильного инструмента. Bash — для быстрых, тексто-ориентированных задач. Python — для скриптов, где важна скорость разработки и есть много библиотек. Go — для высокопроизводительных, надежных утилит, которые должны работать без проблем в любом окружении.
P.S. Написание утилит на Go — это как собрать своего робота из Лего: удобно, надежно и невероятно приятно, когда он работает.
🌐 @helcode
👍3❤1🔥1👌1
Война с плавающим багом в CI
Ваш CI-пайплайн падает раз в два дня из-за плавающего теста, и все делают вид, что не замечают? Сегодня объявляем ему войну. Не игнорируем, а автоматизируем поимку.
Это классика: "У меня работает", "Heisenbug*", который исчезает при попытке отладки. Команда привыкает к красному статусу и перестает ему доверять, что убивает саму идею CI. Ручной перезапуск — это не решение, это признание поражения.
➤ Вариант 1 (Bash + Cron): Пишем скрипт, который дергает API вашего CI (например, Jenkins/GitLab), проверяет последний запуск падающего джоба и в случае ошибки автоматически перезапускает его, отправляя уведомление в Slack.
➤ Вариант 2 (GitHub Actions): используем
Речь об устойчивости и проактивном мониторинге. Система не должна полагаться на бдительность человека. Мы встраиваем механизм самовосстановления для известных, но трудноустранимых проблем. Это тот же принцип, что и в
*Гейзенбаг - жаргонный термин, используемый в программировании для описания программной ошибки, которая исчезает или меняет свои свойства при попытке её обнаружения.
🌐 @helcode
Ваш CI-пайплайн падает раз в два дня из-за плавающего теста, и все делают вид, что не замечают? Сегодня объявляем ему войну. Не игнорируем, а автоматизируем поимку.
Это классика: "У меня работает", "Heisenbug*", который исчезает при попытке отладки. Команда привыкает к красному статусу и перестает ему доверять, что убивает саму идею CI. Ручной перезапуск — это не решение, это признание поражения.
➤ Вариант 1 (Bash + Cron): Пишем скрипт, который дергает API вашего CI (например, Jenkins/GitLab), проверяет последний запуск падающего джоба и в случае ошибки автоматически перезапускает его, отправляя уведомление в Slack.
# Пример для GitLab CI с использованием jq и curl
PIPELINE_STATUS=$(curl -s --header "PRIVATE-TOKEN: <your_token>" "https://gitlab.com/api/v4/projects/<project_id>/pipelines/latest" | jq -r '.status')
if [ "$PIPELINE_STATUS" = "failed" ]; then
curl --request POST --header "PRIVATE-TOKEN: <your_token>" "https://gitlab.com/api/v4/projects/<project_id>/pipelines/latest/retry"
curl -X POST -H 'Content-type: application/json' --data '{"text":"Плавающий тест снова упал. Автоперезапуск...»"}' $SLACK_WEBHOOK
fi
➤ Вариант 2 (GitHub Actions): используем
schedule и джоб с условием для автоматического перезапуска только конкретного флаки-теста.jobs:
retry_flaky_test:
if: failure() && contains(github.event.head_commit.message, 'retry flaky test')
runs-on: ubuntu-latest
steps:
- name: Retry the flaky test suite
run: |
echo "Автоматический ретрай запущен"
Речь об устойчивости и проактивном мониторинге. Система не должна полагаться на бдительность человека. Мы встраиваем механизм самовосстановления для известных, но трудноустранимых проблем. Это тот же принцип, что и в
livenessProbe в Kubernetes: если система нездорова, ее нужно перезапустить, прежде чем бить тревогу.P.S. Автоматический ретрай — это не починка бага, это костыль. Но лучше автоматический костыль, чем кривые костыли ручных ретраев.
*Гейзенбаг - жаргонный термин, используемый в программировании для описания программной ошибки, которая исчезает или меняет свои свойства при попытке её обнаружения.
🌐 @helcode
👍4❤1👌1
"Пару слов" про оптимизацию Docker-образов
Коллеги, есть у меня одна "больная тема". Вижу в CI/CD пайплайнах образы на гигабайты, которые тянут за собой пол-интернета при каждом деплое. При этом внутри - бубунту с полным набором пакетов ради одного скрипта на питоне.
Почему это плохо? Каждый лишний мегабайт в образе - это:
- Медленный пулл на нодах
- Лишнее место в регистри
- Долгий старт подов
- Лишний трафик
Что с этим делать:
➤ Используйте alpine где можно. Базовый образ питона на alpine весит 50 МБ вместо 900 МБ на дебиане. Разница очень ощутима.
➤ Чистите за собой кэши. Если ставите пакеты через apt, не забывайте про
➤ Многослойная сборка. Классика: в одном слое компилируете, во второй кладёте только результат. В итоге в финальном образе нет ни компиляторов, ни исходников, ни временных файлов.
➤ Объединяйте RUN-инструкции. Каждый RUN создаёт отдельный слой. Если разнести установку пакетов и чистку по разным RUN, то в промежуточном слое кэши останутся и будут торчать в финальном образе.
➤ Не тащите лишние файлы.
Проверяйте размер своих образов хотя бы раз в месяц. Я обычно смотрю статистику в registry и если вижу, что какой-то образ резко потолстел - иду разбираться. Часто находится что-то неожиданное вроде случайно примонтированных логов или дампов памяти.
🌐 @helcode
Коллеги, есть у меня одна "больная тема". Вижу в CI/CD пайплайнах образы на гигабайты, которые тянут за собой пол-интернета при каждом деплое. При этом внутри - бубунту с полным набором пакетов ради одного скрипта на питоне.
Почему это плохо? Каждый лишний мегабайт в образе - это:
- Медленный пулл на нодах
- Лишнее место в регистри
- Долгий старт подов
- Лишний трафик
Что с этим делать:
➤ Используйте alpine где можно. Базовый образ питона на alpine весит 50 МБ вместо 900 МБ на дебиане. Разница очень ощутима.
➤ Чистите за собой кэши. Если ставите пакеты через apt, не забывайте про
apt-get clean && rm -rf /var/lib/apt/lists/*. В том же alpine с apk та же история.➤ Многослойная сборка. Классика: в одном слое компилируете, во второй кладёте только результат. В итоге в финальном образе нет ни компиляторов, ни исходников, ни временных файлов.
# Билдер
FROM golang:1.20 AS builder
COPY app.go .
RUN go build -o /app app.go
# Финальный образ
FROM alpine:latest
COPY --from=builder /app /app
CMD ["/app"]
➤ Объединяйте RUN-инструкции. Каждый RUN создаёт отдельный слой. Если разнести установку пакетов и чистку по разным RUN, то в промежуточном слое кэши останутся и будут торчать в финальном образе.
# Плохо
RUN apt-get update
RUN apt-get install -y curl
RUN apt-get clean
# Хорошо
RUN apt-get update && \
apt-get install -y curl && \
apt-get clean
➤ Не тащите лишние файлы.
.dockerignore рулит. Не тащите в образ .git, тесты, документацию и локальные конфиги.Проверяйте размер своих образов хотя бы раз в месяц. Я обычно смотрю статистику в registry и если вижу, что какой-то образ резко потолстел - иду разбираться. Часто находится что-то неожиданное вроде случайно примонтированных логов или дампов памяти.
🌐 @helcode
❤3👍3🔥2
Скрипты на bash и их предсказуемость
Поймал себя на мысли, что многие пишут bash-скрипты как придётся. Запустили, оно вроде работает, и ладно. А потом скрипт падает в три часа ночи, потому что переменная оказалась пустой или в названии файла попался пробел.
Есть вещи, которые я всегда добавляю в начало любых скриптов:
➤ Разбор полётов:
-
-
-
➤ Проверка аргументов. Если скрипт требует аргументы, проверяйте их сразу.
➤ Кавычки везде. Всегда, всегда, всегда берите переменные в кавычки. Если в переменной окажется пробел, без кавычек это будут два отдельных аргумента.
➤ Проверка на существование. Если скрипт работает с файлами, проверяйте, что они есть.
➤ Логирование. Пишите в stdout, что происходит. Это потом спасёт при разборе инцидентов.
Я иногда смотрю на чужие скрипты и вижу там отсутствие этих простых вещей. В итоге скрипт работает на машине автора, потому что там есть нужные файлы и переменные, но падает на чистой системе. А виноват потом "кривой линух".
У вас были случаи, когда bash-скрипт падал из-за неожиданного пробела в имени файла или незаданной переменной?
🌐 @helcode
Поймал себя на мысли, что многие пишут bash-скрипты как придётся. Запустили, оно вроде работает, и ладно. А потом скрипт падает в три часа ночи, потому что переменная оказалась пустой или в названии файла попался пробел.
Есть вещи, которые я всегда добавляю в начало любых скриптов:
#!/bin/bash
set -euo pipefail
➤ Разбор полётов:
-
-e — скрипт умирает при первой же ошибке. Без этого флага он продолжит выполнение, даже если команда упала, и вы можете получить кашу.-
-u — если переменная не объявлена, скрипт сразу падает. Без этого флага пустая переменная превратится в пустую строку и может натворить дел (например, rm -rf $UNDEFINED удалит всё, потому что команда превратится в rm -rf).-
-o pipefail — если в пайпе что-то упало, весь пайп считается упавшим. Без этого флага false | true вернёт успех.➤ Проверка аргументов. Если скрипт требует аргументы, проверяйте их сразу.
if [ -z "${1:-}" ]; then
echo "Ошибка: не указан конфигурационный файл"
exit 1
fi➤ Кавычки везде. Всегда, всегда, всегда берите переменные в кавычки. Если в переменной окажется пробел, без кавычек это будут два отдельных аргумента.
# Плохо
rm -rf $SOME_DIR
# Хорошо
rm -rf "$SOME_DIR"
➤ Проверка на существование. Если скрипт работает с файлами, проверяйте, что они есть.
if [ ! -f "$CONFIG_FILE" ]; then
echo "Файл конфигурации не найден: $CONFIG_FILE"
exit 1
fi
➤ Логирование. Пишите в stdout, что происходит. Это потом спасёт при разборе инцидентов.
echo "[$(date +'%Y-%m-%d %H:%M:%S')] Начинаю бэкап базы данных"
Я иногда смотрю на чужие скрипты и вижу там отсутствие этих простых вещей. В итоге скрипт работает на машине автора, потому что там есть нужные файлы и переменные, но падает на чистой системе. А виноват потом "кривой линух".
У вас были случаи, когда bash-скрипт падал из-за неожиданного пробела в имени файла или незаданной переменной?
🌐 @helcode
🔥9👍3❤2🙏2
Про автоматизацию обновления сертификатов
Каждый, кто админит свои сервера, через это проходил. Просыпаешься утром, а сайт не открывается. Лезешь в логи, а там "SSL certificate expired". Руки чешутся, кофе стынет, сертификат протух ещё неделю назад.
Почему это вообще происходит. Let's Encrypt даёт сертификаты на 90 дней. Это не их прихоть, а стандарт индустрии - короткие сертификаты безопаснее. Но человеческая память короче 90 дней, и ручное обновление рано или поздно проспишь.
➤ 1. Ставим certbot. Он умеет не только получать сертификаты, но и продлевать их.
➤ 2. Разово получаем сертификат.
➤ 3. Настраиваем автоматическое продление. Certbot создаёт systemd-таймер сам при установке. Проверить можно так:
Таймер запускается два раза в день и проверяет, не пора ли обновить сертификаты. Если до истечения осталось меньше 30 дней - обновляет.
➤ 4. Добавляем хуки на перезагрузку. После обновления nginx нужно перезагрузить, чтобы он подхватил новый сертификат.
➤ 5. Проверяем, что всё работает.
Если вдруг certbot не вариант. Бывает, что сервер в закрытом контуре или используются внутренние CA. Тогда пишется простой скрипт в cron:
В cron добавляется еженедельный запуск:
Важный момент. Автоматика автоматикой, но я всё равно добавляю мониторинг на дату истечения. Например, в Prometheus можно экспортировать метрику с днями до протухания и настроить алерт, если осталось меньше недели. Тогда даже если автоматика почему-то не сработала, будет время вмешаться вручную.
У кого как организовано обновление сертификатов? Доверяете автоматике или ходите раз в три месяца ручками продлевать?
🌐 @helcode
Каждый, кто админит свои сервера, через это проходил. Просыпаешься утром, а сайт не открывается. Лезешь в логи, а там "SSL certificate expired". Руки чешутся, кофе стынет, сертификат протух ещё неделю назад.
Почему это вообще происходит. Let's Encrypt даёт сертификаты на 90 дней. Это не их прихоть, а стандарт индустрии - короткие сертификаты безопаснее. Но человеческая память короче 90 дней, и ручное обновление рано или поздно проспишь.
➤ 1. Ставим certbot. Он умеет не только получать сертификаты, но и продлевать их.
apt-get install certbot python3-certbot-nginx
➤ 2. Разово получаем сертификат.
certbot --nginx -d example.com -d www.example.com
➤ 3. Настраиваем автоматическое продление. Certbot создаёт systemd-таймер сам при установке. Проверить можно так:
systemctl status certbot.timer
systemctl list-timers | grep certbot
Таймер запускается два раза в день и проверяет, не пора ли обновить сертификаты. Если до истечения осталось меньше 30 дней - обновляет.
➤ 4. Добавляем хуки на перезагрузку. После обновления nginx нужно перезагрузить, чтобы он подхватил новый сертификат.
certbot renew --renew-hook "systemctl reload nginx"
➤ 5. Проверяем, что всё работает.
certbot renew --dry-run
Если вдруг certbot не вариант. Бывает, что сервер в закрытом контуре или используются внутренние CA. Тогда пишется простой скрипт в cron:
#!/bin/bash
# renew-internal-cert.sh
CERT_PATH="/etc/ssl/certs/myapp.crt"
EXPIRY_DAYS=$(openssl x509 -in "$CERT_PATH" -noout -enddate | cut -d= -f2 | xargs -I{} date -d "{}" +%s)
CURRENT=$(date +%s)
DAYS_LEFT=$(( (EXPIRY_DAYS - CURRENT) / 86400 ))
if [ $DAYS_LEFT -lt 7 ]; then
echo "Сертификат скоро истекает ($DAYS_LEFT дней). Запускаю обновление..."
/usr/local/bin/update-internal-cert.sh
systemctl reload nginx
fi
В cron добавляется еженедельный запуск:
0 2 * * 1 /root/renew-internal-cert.sh
Важный момент. Автоматика автоматикой, но я всё равно добавляю мониторинг на дату истечения. Например, в Prometheus можно экспортировать метрику с днями до протухания и настроить алерт, если осталось меньше недели. Тогда даже если автоматика почему-то не сработала, будет время вмешаться вручную.
У кого как организовано обновление сертификатов? Доверяете автоматике или ходите раз в три месяца ручками продлевать?
🌐 @helcode
❤4👍3🔥1
Коллеги, рад всех приветствовать! Мы закончили миграцию: теперь нас можно читать не только в Телеграм!
Недавно я запускал голосование с вопросом: куда мигрируем на случай блокировки Телеграм? Вы ответили - и довольно однозначно. Спасибо всем, кто участвовал в опросе и оставлял комментарии.
Всё это время я не сидел сложа руки. Была изучена статистика, проанализированы площадки, где присутствует техническая аудитория, проанализировано удобство работы с контентом на различных площадках. Выводы сделаны, инфраструктура настроена.
Что имеем на выходе:
Основной канал как был в Телеграм, так и остается. Сюда я буду писать в первую очередь, здесь же будет основное обсуждение. Никаких "уходим навсегда" не планируется. Также, был переработан формат постов для адекватного репоста в иные соц. сети, весь .md формат (код) уходит в изображение. В ближайшее время мы с ним "познакомимся".
Но теперь у @helcode есть официальные зеркала на двух дополнительных площадках:
VK - для тех, кто привык читать ленту в соцсети и не хочет ставить лишние мессенджеры. Туда уходят все посты синхронно с Телеграм. Минус - в комментарии захожу реже, но читаю.
Boosty - для любителей блог-формата. Там же будет постепенно появляться расширенная версия некоторых материалов, если тема глубокая и не влезает в короткий пост. Об этом буду обязательно оповещать.
Статический сайт пока отложил. Идея хорошая, но требует времени на поддержку, которого и так в обрез. Возможно, вернусь к ней, когда накопится критическая масса контента, которую неудобно искать в соцсетях.
Резюмирую. Канал жив, контент выходит по плану, темы по автоматизации, Linux и утилитам никуда не делись. Если завтра Телеграм вдруг станет совсем недоступен - вы знаете, где искать. Все "перекрестные" ссылки будут под каждым постом!
🌐 @helcode
Недавно я запускал голосование с вопросом: куда мигрируем на случай блокировки Телеграм? Вы ответили - и довольно однозначно. Спасибо всем, кто участвовал в опросе и оставлял комментарии.
Всё это время я не сидел сложа руки. Была изучена статистика, проанализированы площадки, где присутствует техническая аудитория, проанализировано удобство работы с контентом на различных площадках. Выводы сделаны, инфраструктура настроена.
Что имеем на выходе:
Основной канал как был в Телеграм, так и остается. Сюда я буду писать в первую очередь, здесь же будет основное обсуждение. Никаких "уходим навсегда" не планируется. Также, был переработан формат постов для адекватного репоста в иные соц. сети, весь .md формат (код) уходит в изображение. В ближайшее время мы с ним "познакомимся".
Но теперь у @helcode есть официальные зеркала на двух дополнительных площадках:
VK - для тех, кто привык читать ленту в соцсети и не хочет ставить лишние мессенджеры. Туда уходят все посты синхронно с Телеграм. Минус - в комментарии захожу реже, но читаю.
Boosty - для любителей блог-формата. Там же будет постепенно появляться расширенная версия некоторых материалов, если тема глубокая и не влезает в короткий пост. Об этом буду обязательно оповещать.
Статический сайт пока отложил. Идея хорошая, но требует времени на поддержку, которого и так в обрез. Возможно, вернусь к ней, когда накопится критическая масса контента, которую неудобно искать в соцсетях.
Резюмирую. Канал жив, контент выходит по плану, темы по автоматизации, Linux и утилитам никуда не делись. Если завтра Телеграм вдруг станет совсем недоступен - вы знаете, где искать. Все "перекрестные" ссылки будут под каждым постом!
🌐 @helcode
👍13👌4❤1🔥1
Коллеги, всех приветствую!
Давно хотел показать что-то действительно полезное и при этом созданное внутри нашего сообщества. Знакомьтесь: DevToolbox Cheats - проект подписчика @boomlavka.
Для тех, кто, как и я, работает в Linux и постоянно ловит себя на мысли: "А какой там флаг у tar...?", "Как правильно смонтировать диск...?", "А как сбросить настройку iptables...?".
Что сделал автор? Он взял и упаковал более 100 готовых шпаргалок (Git, Bash, Docker, RegEx, Ansible и ещё много чего) в удобный интерфейс, который встраивается прямо в панель вашего рабочего стола.
➤ Чем проект цепляет лично меня:
1. Универсальность: неважно, сидите вы в KDE, GNOME, XFCE или даже в голом i3 - утилита сама подстроится и будет выглядеть как родная.
2. Скорость: кэширование отрабатывает так, что список команд появляется быстрее, чем открывается браузер.
3. Копирование в один клик: нашёл команду - ткнул - она уже в буфере. Минимум телодвижений.
4. Умное редактирование: если встроенных шпаргалок вдруг покажется мало, автор продумал сценарий на любой случай. Можно открыть конфиг в любимом редакторе (VS Code, Geany и др.) - скрипт сам определит, что у вас стоит. Если редактор не найден или вы работаете в minimal окружении - файл откроется прямо во всплывающем окошке zenity.
Мы часто обсуждаем автоматизацию на уровне систем и скриптов, но автоматизация личного рабочего процесса - это то, что экономит часы каждую неделю. DevToolbox Cheats - именно про это. Не надо гуглить, не надо лезть в заметки. Просто кликнул на иконку и продолжил работу.
ВАЖНО:
Я знаю, что @boomlavka продолжает развивать проект, и ему, как любому разработчику, важна обратная связь. Если вы покопаетесь в репозитории и найдёте баг, или наоборот - придумаете, как улучшить - не стесняйтесь писать автору или создавать issue на GitHub. Сообщество сильное только тогда, когда Мы помогаем друг другу становиться лучше.
👉 Ссылка на [GitHub](https://github.com/dominatos/devtoolbox-cheats)
Буду благодарен, если поставите звёздочку тем, кто зайдёт. Автору будет приятно, а каналу - почётно, что наши коллеги делают полезные инструменты.
P.S. Если у кого-то тоже есть свои проекты или полезные наработки - смело пишите в личку (@helcodeadm). Покажем, обсудим, поддержим.
🌐 @helcode
Давно хотел показать что-то действительно полезное и при этом созданное внутри нашего сообщества. Знакомьтесь: DevToolbox Cheats - проект подписчика @boomlavka.
Для тех, кто, как и я, работает в Linux и постоянно ловит себя на мысли: "А какой там флаг у tar...?", "Как правильно смонтировать диск...?", "А как сбросить настройку iptables...?".
Что сделал автор? Он взял и упаковал более 100 готовых шпаргалок (Git, Bash, Docker, RegEx, Ansible и ещё много чего) в удобный интерфейс, который встраивается прямо в панель вашего рабочего стола.
➤ Чем проект цепляет лично меня:
1. Универсальность: неважно, сидите вы в KDE, GNOME, XFCE или даже в голом i3 - утилита сама подстроится и будет выглядеть как родная.
2. Скорость: кэширование отрабатывает так, что список команд появляется быстрее, чем открывается браузер.
3. Копирование в один клик: нашёл команду - ткнул - она уже в буфере. Минимум телодвижений.
4. Умное редактирование: если встроенных шпаргалок вдруг покажется мало, автор продумал сценарий на любой случай. Можно открыть конфиг в любимом редакторе (VS Code, Geany и др.) - скрипт сам определит, что у вас стоит. Если редактор не найден или вы работаете в minimal окружении - файл откроется прямо во всплывающем окошке zenity.
Мы часто обсуждаем автоматизацию на уровне систем и скриптов, но автоматизация личного рабочего процесса - это то, что экономит часы каждую неделю. DevToolbox Cheats - именно про это. Не надо гуглить, не надо лезть в заметки. Просто кликнул на иконку и продолжил работу.
ВАЖНО:
Я знаю, что @boomlavka продолжает развивать проект, и ему, как любому разработчику, важна обратная связь. Если вы покопаетесь в репозитории и найдёте баг, или наоборот - придумаете, как улучшить - не стесняйтесь писать автору или создавать issue на GitHub. Сообщество сильное только тогда, когда Мы помогаем друг другу становиться лучше.
👉 Ссылка на [GitHub](https://github.com/dominatos/devtoolbox-cheats)
Буду благодарен, если поставите звёздочку тем, кто зайдёт. Автору будет приятно, а каналу - почётно, что наши коллеги делают полезные инструменты.
P.S. Если у кого-то тоже есть свои проекты или полезные наработки - смело пишите в личку (@helcodeadm). Покажем, обсудим, поддержим.
🌐 @helcode
GitHub
GitHub - dominatos/devtoolbox-cheats: Cross-Desktop cheatsheet manager for Linux with native support for GNOME, KDE, XFCE, Windows…
Cross-Desktop cheatsheet manager for Linux with native support for GNOME, KDE, XFCE, Windows and more. Access your Markdown command references instantly from your panel or menu. - dominatos/devtool...
❤6🤔3
Helcode | Хелкод | Скрипты и автоматизация pinned «Коллеги, рад всех приветствовать! Мы закончили миграцию: теперь нас можно читать не только в Телеграм! Недавно я запускал голосование с вопросом: куда мигрируем на случай блокировки Телеграм? Вы ответили - и довольно однозначно. Спасибо всем, кто участвовал…»
Ansible: миф об идемпотентности и как не прострелить себе ногу
Ansible позиционируется как идемпотентный инструмент: можно запустить плейбук сто раз, и система будет в одном и том же состоянии. В теории - красиво, на практике - не всегда. Главная боль возникает, когда вы начинаете писать собственные сценарии с модулями
Чтобы побороть это, используют параметры
Стоит помнить: Ansible хорош ровно настолько, насколько хорошо вы используете его модули. Если задача сложная и требует логики, может быть, проще написать скрипт на Python и вызвать его через модуль
🌐 @helcode
Ansible позиционируется как идемпотентный инструмент: можно запустить плейбук сто раз, и система будет в одном и том же состоянии. В теории - красиво, на практике - не всегда. Главная боль возникает, когда вы начинаете писать собственные сценарии с модулями
command или shell. Они по умолчанию не идемпотентны. Запустите их дважды - они выполнятся дважды.Чтобы побороть это, используют параметры
creates и removes (проверка наличия файла-маркера), changed_when и failed_when (тонкая настройка условий изменения и ошибки). Но это всё костыли. Если вы ловите себя на том, что часто используете shell вместо специализированных модулей (copy, template, file, lineinfile, package), значит, вы пишете не декларативный код, а процедурный скрипт на bash внутри Ansible.Стоит помнить: Ansible хорош ровно настолько, насколько хорошо вы используете его модули. Если задача сложная и требует логики, может быть, проще написать скрипт на Python и вызвать его через модуль
script, сохранив идемпотентность на уровне внешнего скрипта.🌐 @helcode
👍9🤔3❤2
Доброго времени суток! Попробуем истории из личной практики?)
Довелось мне на одном из проектов поработать с человеком, который писал комментарии к каждой строчке кода. Буквально к каждой, никаких преувеличений. Выглядело это примерно так:
# Увеличиваем счетчик на 1
i = i + 1;
# Проверяем, не больше ли 10
if (i > 10) {
# Если больше, сбрасываем
i = 0;
}
Сначала это было действительно забавно. Спустя время мы пытались объяснить, что код должен быть "самодокументируемым" (поясню для тех, кто с термином не знаком. Это некий стиль написания кода, при котором он пишется настолько ясно, чисто и понятно, что не требует внешних комментариев для понимания его логики работы).
Через примерно год его код превратился в простыню, где читать комментарии было дольше, чем разбираться в логике. А когда он уволился и нужно было править его модуль, мы осознали весь звиздец ситуации: комментарии были на русском, переменные на английском, а логика - на каком-то своём, крайне непонятном.
При этом, половина комментариев уже давно не соответствовала реальности, потому что код меняли, а комментарии не трогали. Зачем, верно?)
На самом деле, даже рад случившемуся, много полезного усвоил. После той ситуации и отношение к коду/комментариям поменялось. Стараюсь писать максимально понятно.
🌐 @helcode
Довелось мне на одном из проектов поработать с человеком, который писал комментарии к каждой строчке кода. Буквально к каждой, никаких преувеличений. Выглядело это примерно так:
# Увеличиваем счетчик на 1
i = i + 1;
# Проверяем, не больше ли 10
if (i > 10) {
# Если больше, сбрасываем
i = 0;
}
Сначала это было действительно забавно. Спустя время мы пытались объяснить, что код должен быть "самодокументируемым" (поясню для тех, кто с термином не знаком. Это некий стиль написания кода, при котором он пишется настолько ясно, чисто и понятно, что не требует внешних комментариев для понимания его логики работы).
Через примерно год его код превратился в простыню, где читать комментарии было дольше, чем разбираться в логике. А когда он уволился и нужно было править его модуль, мы осознали весь звиздец ситуации: комментарии были на русском, переменные на английском, а логика - на каком-то своём, крайне непонятном.
При этом, половина комментариев уже давно не соответствовала реальности, потому что код меняли, а комментарии не трогали. Зачем, верно?)
На самом деле, даже рад случившемуся, много полезного усвоил. После той ситуации и отношение к коду/комментариям поменялось. Стараюсь писать максимально понятно.
🌐 @helcode
😁5❤1👎1🌚1
Небольшая история про оптимизацию
Была у нас микросервисная архитектура. Красивая, как в учебниках. Каждый сервис делал что-то одно и делал хорошо. Только вот беда - их было 47 штук.
Один сервис отвечал за генерацию PDF, второй за отправку писем, третий за превьюшки картинок, четвёртый за сборку всего этого в отчёты... Ну, вы поняли.
Прилетает задача: ускорить генерацию отчёта. Менеджеры жалуются - целых 3 секунды приходится ждать, "пока там крутится".
Полез оптимизировать. Лимиты поднял, запросы распараллелил, кэширование добавил. В общем, добился ускорения до 1.5 секунд. Пошёл к руководству, отчитываться.
Получил вопрос: "А логи посмотрел?". Вернулся, пошёл смотреть логи... 0.5 секунды из 1.5 - сбор метрик для нашего же мониторинга, ещё 0.5 - запись в лог...
Выключил метрики на тестовом стенде, отчёт прилетел за 0.3 секунды. Теперь стараюсь придерживаться правила: прежде чем оптимизировать - посмотреть, сколько времени жрёт наблюдаемость.
P.S. Если вдруг заходит подобный формат - пишите, буду периодически рассказывать что-то из личной практики)
🌐 @helcode
Была у нас микросервисная архитектура. Красивая, как в учебниках. Каждый сервис делал что-то одно и делал хорошо. Только вот беда - их было 47 штук.
Один сервис отвечал за генерацию PDF, второй за отправку писем, третий за превьюшки картинок, четвёртый за сборку всего этого в отчёты... Ну, вы поняли.
Прилетает задача: ускорить генерацию отчёта. Менеджеры жалуются - целых 3 секунды приходится ждать, "пока там крутится".
Полез оптимизировать. Лимиты поднял, запросы распараллелил, кэширование добавил. В общем, добился ускорения до 1.5 секунд. Пошёл к руководству, отчитываться.
Получил вопрос: "А логи посмотрел?". Вернулся, пошёл смотреть логи... 0.5 секунды из 1.5 - сбор метрик для нашего же мониторинга, ещё 0.5 - запись в лог...
Выключил метрики на тестовом стенде, отчёт прилетел за 0.3 секунды. Теперь стараюсь придерживаться правила: прежде чем оптимизировать - посмотреть, сколько времени жрёт наблюдаемость.
P.S. Если вдруг заходит подобный формат - пишите, буду периодически рассказывать что-то из личной практики)
🌐 @helcode
👍27❤2😁2