Навыки реальных инженеров: практические советы из .agents
Практическое руководство по навыкам, необходимым реальным инженерам, с примерами конфигураций, Docker, Kubernetes и домашней лаборатории.
Концепция реальных навыков инженера
Определение набора компетенций
Набор компетенций реального инженера — это совокупность знаний и умений, позволяющих системно проектировать, развертывать и поддерживать инфраструктуру. В практике это значит умело работать с операционной системой, контейнерами, оркестраторами, хранилищами и средствами мониторинга, а также автоматизировать рутинные операции.
- Linux‑инструменты: systemd, journalctl, iptables, nmcli.
bash
# проверка статуса сервиса systemctl status docker # просмотр журнала journalctl -u nginx -f - Контейнеры: Docker, Docker Compose, Podman.
bash
# запуск стека в фоне docker compose up -d # просмотр работающих контейнеров docker ps --filter "status=running" - Оркестрация: k3s, Rancher, kubeadm.
yaml
# минимальный манифест для k3s apiVersion: v1 kind: Node metadata: name: winni-pukh - Виртуализация: Proxmox VE, libvirt.
bash
# создание нового ВМ через CLI qm create 101 --name pytachok --memory 4096 --cores 2 --net0 virtio,bridge=vmbr0 - Хранение: ZFS, TrueNAS, NFS, Samba.
bash
# создание пула ZFS zpool create tank /dev/disk/by-id/scsi-00000_wwn-0x50020500000000000000000000000000 - Мониторинг и алерты: Prometheus, Grafana, Alertmanager.
yaml
# пример правила оповещения в Alertmanager groups: - name: node_alerts rules: - alert: HighCPUUsage expr: node_cpu_seconds_total{mode="idle"} < 0.1 for: 5m labels: severity: critical annotations: summary: "CPU usage is high on {{ $labels.instance }}" - Логирование: journald, Loki.
bash
# поиск ошибок в журнале nginx journalctl -u nginx | grep -i error - Автоматизация: Ansible (только для конфигурации).
yaml
# playbook для установки Nginx - hosts: servers become: yes tasks: - name: Install Nginx apt: name: nginx state: present
Эти компетенции образуют основу, без которой сложные задачи становятся «пожаром», требующим быстрых, но не проверенных решений.
Почему практические навыки важны
Теоретические знания дают лишь основу, а реальная ценность инженера проявляется в умении применять их на практике. Практический опыт обеспечивает предсказуемость конфигураций, позволяет быстро находить причину сбоев и автоматизировать повторяющиеся операции. Без этого любой «огромный» проект превращается в хронику случайных ошибок.
Пример из реальной лаборатории: после установки Docker Compose для стека из Plex, Nextcloud и автоматизированного бэкапа, я проверяю, что каждый контейнер стартует без ошибок, а система мониторинга (Prometheus + Grafana) отслеживает нагрузку на диск и сетевой трафик. Если один из сервисов падает, алерт в Alertmanager сразу попадает в канал, и я могу реагировать, не гася пожар вручную.
bash# проверка health‑check'ов контейнеров
docker compose ps
# перезапуск проблемного сервиса
docker compose restart nextcloud
Если бы я полагался только на «наушные» инструкции, то при изменении конфигурации Nginx мог бы получить 502 Bad Gateway без возможности быстро откатиться. Поэтому после правки файла /etc/nginx/sites-available/example.com.conf я выполняю:
bashnginx -t && systemctl reload nginx
Только так можно гарантировать, что изменения не нарушат работу сервиса, а серверы остаются стабильными годами. Практические навыки — это не просто умение пользоваться инструментами, а систематический подход к построению инфраструктуры, где каждый элемент проверен, документирован и покрыт мониторингом. Именно поэтому в реальном инженерном проекте без практических навыков не обойтись.
Инфраструктурные инструменты: Docker, Kubernetes и Proxmox
Инфраструктурные инструменты: Docker, Kubernetes и Proxmox
Контейнеризация с Docker Compose
Для небольших проектов и тестовых стендов удобно собрать всё в один docker‑compose.yml. Ниже пример стека, который я обычно использую для домашней медиа‑ и файловой инфраструктуры:
yamlversion: '3.8'
services:
nginx:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
nextcloud:
image: nextcloud:latest
environment:
- MYSQL_PASSWORD=strong_password
volumes:
- nextcloud_data:/var/www/html
plex:
image: linuxserver/plex
ports:
- "32400:32400"
volumes:
- /srv/media:/data
volumes:
nextcloud_data:
- Почему именно Compose? – он позволяет описать зависимости между контейнерами, задать сети и т. д. в одном файле, а
docker compose up -dподнимет всё за один шаг. - Проверка портов – перед стартом убедитесь, что 80 и 32400 свободны:
bashsudo ss -tlnp | grep -E ':(80|32400)\b'
- Обновление – после изменения конфигурации достаточно выполнить
docker compose pull && docker compose up -d --force-recreate.
Для более масштабных задач я переключаюсь на Kubernetes, но Docker Compose остаётся базовым инструментом для быстрого прототипирования.
Управление кластерами в Proxmox
Proxmox VE предоставляет как веб‑интерфейс, так и полностью автоматизированный CLI. В моей домашней лаборатории из трёх нод (Winnie‑Пух, Пятачок, Сова) я использую команды qm и pvecm для создания и поддержания виртуальных машин и кластера.
Создание VM – пример развертывания Debian‑11 на ноде «Пятачок» (ID 101):
bashqm create 101 \
--memory 4096 \
--cores 2 \
--net0 virtio,bridge=vmbr0 \
--ostype lxc \
--template debian-11-standard_10-11-x86_64.tar.gz
qm set 101 --boot c --bootorder order=c
qm start 101
- Настройка диска – добавляю отдельный LVM‑том для данных, чтобы не заполнять системный диск:
bashqm set 101 --scsi0 local-lvm:10G
Кластеризация – инициализация первого узла (Winnie‑Пух) и добавление остальных:
bashpvecm create winnie-pukh pvecm add pjatok --force pvecm add sova --force
После этого можно перемещать VM между нодами без простоя, а также использовать pvevm migrate для балансировки нагрузки.
- Мониторинг – Prometheus + node_exporter, а alerts настраиваются через Alertmanager. Пример правила для проверки загрузки CPU:
yaml- alert: HighCPUUsage
expr: node_cpu_seconds_total{mode="system"} > 0.8
for: 5m
labels:
severity: warning
annotations:
summary: "CPU usage on {{ $labels.instance }} is high"
description: "CPU system load > 80% for more than 5 minutes."
Эти практики позволяют поддерживать инфраструктуру в предсказуемом состоянии, минимизировать ручные ошибки и ускорять развертывание новых сервисов.
Автоматизация и надёжность: Ansible, systemd и мониторинг
### Автоматизация конфигураций через Ansible
Ansible — один из самых простых способов держать конфигурацию домашней лаборатории в нужном состоянии.
Он работает без постоянного доступа к каждому узлу: достаточно один раз описать желаемое состояние, а дальше повторять его можно в любой момент, даже после переустановки сервера.
Инвентори – это файл, где перечисляются хосты и их группы. Для небольшого кластера Proxmox + Raspberry Pi удобно разделить их так:
yaml# inventory.ini
[proxmox]
proxmox01 ansible_host=192.168.1.10
[raspberry]
pi01 ansible_host=192.168.1.20
pi02 ansible_host=192.168.1.21
[homelab:children]
proxmox
raspberry
Playbook для установки Docker Compose на всех узлах:
yaml# site.yml
- name: Prepare homelab nodes
hosts: homelab
become: true
tasks:
- name: Install required packages
apt:
name:
- ca-certificates
- curl
- gnupg
- lsb-release
state: present
update_cache: yes
- name: Add Docker official GPG key
apt_key:
url: https://download.docker.com/linux/ubuntu/gpg
state: present
- name: Add Docker repository
apt_repository:
repo: deb [arch=amd64] https://download.docker.com/linux/ubuntu {{ ansible_distribution_release }} stable
state: present
update_cache: yes
- name: Install Docker Engine
apt:
name: docker-ce
state: present
- name: Install Docker Compose (via pip)
pip:
name: docker-compose
state: present
Запуск playbook:
bashansible-playbook -i inventory.ini site.yml
Почему так?
Ansible использует SSH, поэтому настройка происходит один раз, а дальше вы получаете воспроизводимую конфигурацию. Если понадобится добавить новый Raspberry Pi, достаточно добавить его в[raspberry]и выполнить тот же playbook — всё будет готово без ручных правок.
Для более сложных сценариев (например, развертывание Kubernetes k3s) удобно использовать готовые коллекции:
(см. пример в официальной документации).
### Системные сервисы и алерты с systemd
Systemd — центральный менеджер служб в Linux. Он умеет не только запускать процессы, но и следить за их состоянием, автоматически перезапускать, а также генерировать события, которые можно использовать в алертах.
1. Простой сервис‑юнит для резервного копирования
Пусть у нас есть скрипт backup.sh, который архивирует /home/alexey и отправляет архив на TrueNAS‑шаре.
bash# /usr/local/bin/backup.sh
#!/bin/bash
set -euo pipefail
BACKUP_DIR="/backup"
TIMESTAMP=$(date +%F_%H-%M-%S)
tar -czf "${BACKUP_DIR}/home-${TIMESTAMP}.tar.gz" /home/alexey
# Пример отправки на NFS‑монтировку TrueNAS
mount -t nfs truenas:/backup_share /mnt/truenas
mv "${BACKUP_DIR}/home-${TIMESTAMP}.tar.gz" /mnt/truenas/backup/
umount /mnt/truenas
Сделаем его исполняемым:
bashchmod +x /usr/local/bin/backup.sh
Теперь создаём unit‑файл:
ini# /etc/systemd/system/home-backup.service
[Unit]
Description=Backup of /home directory
Wants=network-online.target
After=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/local/bin/backup.sh
# При необходимости задаём ограничение по времени
# TimeoutSec=30m
2. Таймер, который будет запускать сервис каждый день в 02:30
ini# /etc/systemd/system/home-backup.timer
[Unit]
Description=Run home backup daily at 02:30
[Timer]
OnCalendar=*-*-* 02:30:00
Persistent=true
[Install]
WantedBy=timers.target
Активируем таймер:
bashsystemctl daemon-reload
systemctl enable --now home-backup.timer
Проверить статус:
bashsystemctl list-timers --all | grep home-backup
3. Интеграция с мониторингом
Для алертов удобно использовать systemd-notify — он посылает события в systemd‑socket, который может быть подключён к скрипту‑провайдеру (например, отправляющему уведомление в Telegram).
Создадим простой обработчик:
bash# /usr/local/bin/systemd-alert-notify.sh
#!/bin/bash
# $1 — тип события (START, STOP, FAILURE)
case "$1" in
START)
curl -X POST https://api.telegram.org/bot${TG_TOKEN}/sendMessage \
-d chat_id=${TG_CHAT_ID} \
-d text="✅ Сервис systemd запущен: $2"
;;
FAILURE)
curl -X POST https://api.telegram.org/bot${TG_TOKEN}/sendMessage \
-d chat_id=${TG_CHAT_ID} \
-d text="❗️ Сервис systemd завершился с ошибкой: $2"
;;
esac
Сделаем его исполняемым и добавим в unit‑файл:
ini# /etc/systemd/system/home-backup.service (дополнение)
[Service]
...
ExecStartPost=/usr/local/bin/systemd-alert-notify.sh START home-backup.service
ExecStartPost=/usr/bin/bash -c 'if [ $? -ne 0 ]; then /usr/local/bin/systemd-alert-notify.sh FAILURE home-backup.service; fi'
Важно: в реальном проекте стоит добавить проверку кода возврата скрипта
backup.shи использоватьRestart=on-failure,RestartSec=5min, чтобы сервис автоматически перезапускался при падении.
4. Watchdog‑механизм
Systemd умеет самостоятельно проверять, «жив» ли процесс. В нашем примере можно добавить:
ini[Service]
...
WatchdogSec=5min
Если процесс не вызывает sd_notify("WATCHDOG=1") в течение 5 минут, systemd считает его зависшим и инициирует перезапуск. Для скриптов‑oneshot это не требуется, но для долгоживущих демонов (например, Prometheus‑node‑exporter) это полезно.
5. Логи и журнал
Все сообщения сервиса попадают в journalctl. Чтобы не терять важные строки, можно настроить ротацию:
ini# /etc/systemd/journald.conf.d/90-backup.conf
[Journal]
MaxSize=200M
MaxFileSec=1month
После изменения конфигурации перезапускаем daemon:
bashsystemctl restart systemd-journald
6. Практический совет
Системные сервисы лучше управлять через systemd, а не через cron.
Systemd гарантирует, что сервис будет запущен после загрузки системы, корректно отследит его состояние и позволит задать зависимости (например, ждать монтирования NFS). Cron подходит только для простых «запускать каждый день в 02:00»‑задач без сложных зависимостей.
Если понадобится более детальная настройка алертов (например, интеграция с Prometheus Alertmanager), см. официальную документацию systemd‑notifications
systemd‑notifications.
Хранение данных и резервное копирование
ZFS и TrueNAS для надёжного хранилища
Я, Алексей Кузнецов, использую ZFS уже более десяти лет. Эта файловая система дает проверку целостности данных, Snapshots, сжатие и простую репликацию. На домашнем сервере на базе Dell PowerEdge R730 у меня два диска 8 ТБ в зеркальном массиве, что обеспечивает отказ от одного диска без потери доступности.
Создание пула
bash# создаём пул из двух дисков, включаем 12‑битный shift для выравнивания
zpool create -f -o ashift=12 tank mirror /dev/sda /dev/sdb
Настройка свойств пула
bash# включаем сжатие lz4 – экономия места без заметной нагрузки
zfs set compression=lz4 tank
# задаём запись в режиме async для лучшей производительности
zfs set primarycache=metadata tank
Snapshots и репликация
bash# создаём снимок всех данных в файловом пространстве tank/data
zfs snapshot tank/data@2024-10-01
# отправляем снимок на резервный сервер по SSH
zfs send -R tank/data@2024-10-01 | ssh backup@example.com zfs recv -F backup/tank/data
TrueNAS (Core или Scale) предоставляет веб‑интерфейс для управления пулами, но я всё равно пишу конфиги вручную, чтобы знать, где лежит каждый параметр. Если хотите посмотреть официальную документацию, её можно найти по ссылке: TrueNAS documentation.
Практика
- Периодически проверяйте статус пула:
zpool status tank. - При добавлении новых дисков используйте
zpool add tank mirror /dev/sdc /dev/sdd. - Не забывайте о
zfs scrub– раз в месяц, чтобы проверить целостность:zfs scrub tank.
В итоге ZFS + TrueNAS дают надёжное хранилище, которое выдерживает сбои дисков и сохраняет исторические версии данных.
Резервное копирование с помощью rsync и cron
Для резервного копирования я использую rsync. Он умеет копировать только изменённые файлы, сохранять права, владельцев и поддерживает удаление лишних файлов в целевой директории.
Базовая команда
bashrsync -a --delete /tank/data/ /mnt/backup/data/
-a— архивный режим (рекурсия, сохранение атрибутов).--delete— удалять файлы в целевой директории, которых уже нет в источнике.
Скрипт‑обёртка
bash#!/bin/bash
# /usr/local/bin/backup_data.sh
set -euo pipefail
SRC="/tank/data/"
DST="/mnt/backup/data/"
LOG="/var/log/rsync_backup.log"
rsync -a --delete --partial --log-file="${LOG}" "${SRC}" "${DST}"
Сделайте скрипт исполняемым: chmod +x /usr/local/bin/backup_data.sh.
Планировщик cron
cron# каждый день в 02:00 утра 0 2 * * * /usr/local/bin/backup_data.sh >> /var/log/rsync_backup.log 2>&1
Параметры, которые я использую
--partial— сохранять частично скопированные файлы при прерывании.--progress— выводить прогресс в лог (можно убрать в cron).--exclude='*.tmp'— исключить временные файлы, если они не нужны в бэкапе.
Хранение нескольких точек восстановления
Для удобства можно создавать директорию с датой в имени и использовать hard‑links, но простой вариант — хранить только последнюю копию и полагаться на Snapshots ZFS. Если нужна более сложная ротация, можно добавить rsnapshot или borgbackup, но это уже отдельный разговор.
Проверка
После первого запуска проверьте размер целевой директории и сравните его с исходной: du -sh /tank/data /mnt/backup/data.
В практической точке зрения такой подход обеспечивает быстрый и предсказуемый процесс бэкапа, а cron + rsync остаются проверенными инструментами, которые не требуют дополнительных зависимостей. Если понадобится более надёжная репликация, можно комбинировать rsync с zfs send/receive, но для большинства домашних нужд этого достаточно.
Часто задаваемые вопросы
Как правильно настроить мониторинг CPU в Alertmanager?
Сначала в файле rules создайте правило, использующее метрику node_cpu_seconds_total с условием, что процент простоя < 0.1 (т.е. загрузка > 90 %). Установите период for: 5m, чтобы избежать ложных срабатываний, и укажите метку severity: critical. В annotations добавьте краткое описание и переменную {{ $labels.instance }} для идентификации узла. После перезагрузки Alertmanager вы получите уведомление, когда CPU будет находиться в критическом состоянии более пяти минут.
Что делать, если Docker Compose не поднимает контейнеры?
Проверьте, что все сервисы указаны корректно в docker‑compose.yml и что нет конфликтов портов. Выполните docker compose ps — это покажет статус контейнеров и любые ошибки в логах. При необходимости запустите docker compose up -d --build для пересборки образов и повторного старта. Если проблема сохраняется, просмотрите журнал Docker (docker info и journalctl -u docker) для поиска скрытых ошибок.
Как автоматизировать бэкапы ZFS‑пула?
Создайте скрипт, который запускает zfs snapshot tank@$(date +%Y-%m-%d_%H-%M) для всех датасетов, а затем zfs send и zfs receive на резервный пул. Добавьте задачу в cron с интервалом, например, каждый день в 02:00 ч. Для надёжности включите проверку наличия резервного диска и отправку уведомления в Alertmanager при неудачном выполнении. Это обеспечит предсказуемость и минимальный риск потери данных.
Как проверить статус systemd‑сервисов без лишних команд?
Самый быстрый способ — использовать systemctl list-units --type=service --state=active, что покажет только запущенные сервисы. Для более детального просмотра статуса конкретного сервиса выполните systemctl status <service_name>. Если нужно увидеть последние записи журнала, добавьте journalctl -u <service_name> -n 20. Такой подход экономит время и сразу даёт нужную информацию.