Продвинутый

Навыки реальных инженеров: практические советы из .agents

Алексей Кузнецов
Алексей Кузнецов
Системный администратор10 ноября 2026 г.12 мин чтения

Практическое руководство по навыкам, необходимым реальным инженерам, с примерами конфигураций, Docker, Kubernetes и домашней лаборатории.

Навыки реальных инженеров: практические советы из .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 я выполняю:

bash
nginx -t && systemctl reload nginx

Только так можно гарантировать, что изменения не нарушат работу сервиса, а серверы остаются стабильными годами. Практические навыки — это не просто умение пользоваться инструментами, а систематический подход к построению инфраструктуры, где каждый элемент проверен, документирован и покрыт мониторингом. Именно поэтому в реальном инженерном проекте без практических навыков не обойтись.

Инфраструктурные инструменты: Docker, Kubernetes и Proxmox

Инфраструктурные инструменты: Docker, Kubernetes и Proxmox

Контейнеризация с Docker Compose

Для небольших проектов и тестовых стендов удобно собрать всё в один docker‑compose.yml. Ниже пример стека, который я обычно использую для домашней медиа‑ и файловой инфраструктуры:

yaml
version: '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 свободны:
bash
sudo 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):

bash
qm 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‑том для данных, чтобы не заполнять системный диск:
bash
qm set 101 --scsi0 local-lvm:10G

Кластеризация – инициализация первого узла (Winnie‑Пух) и добавление остальных:

bash
pvecm 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:

bash
ansible-playbook -i inventory.ini site.yml

Почему так?
Ansible использует SSH, поэтому настройка происходит один раз, а дальше вы получаете воспроизводимую конфигурацию. Если понадобится добавить новый Raspberry Pi, достаточно добавить его в [raspberry] и выполнить тот же playbook — всё будет готово без ручных правок.

Для более сложных сценариев (например, развертывание Kubernetes k3s) удобно использовать готовые коллекции:

Ansible Collections – 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

Сделаем его исполняемым:

bash
chmod +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

Активируем таймер:

bash
systemctl daemon-reload
systemctl enable --now home-backup.timer

Проверить статус:

bash
systemctl 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:

bash
systemctl 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. Он умеет копировать только изменённые файлы, сохранять права, владельцев и поддерживает удаление лишних файлов в целевой директории.

Базовая команда

bash
rsync -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. Такой подход экономит время и сразу даёт нужную информацию.

Поделиться:TelegramX / TwitterVK