Продвинутый

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

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

Практическое руководство по навыкам, которые используют реальные инженеры: от Docker и Kubernetes до ZFS, TrueNAS и автоматизации в .agents.

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

Практическое руководство по навыкам, которые используют реальные инженеры: от Docker и Kubernetes до ZFS, TrueNAS и автоматизации в .agents.

Системный подход в инженерии

Системный подход в инженерии

Планирование инфраструктуры

Планирование — это не просто список серверов в Excel, а система, где каждый элемент имеет назначение, версию и место в общей схеме. На практике я начинаю с инвентарного файла, который хранит данные о каждом узле: ОС, CPU, RAM, диски, сетевые интерфейсы и текущий статус. Такой подход позволяет быстро понять, где какие ресурсы находятся, и автоматизировать их развертывание.

yaml
# inventory.yaml — пример инвентаря Proxmox
all:
  children:
    proxmox:
      hosts:
        winnie:
          ansible_host: 192.168.10.10
          cpu: 16
          memory: 64G
          disks:
            - /dev/sda
            - /dev/sdb
        pjat:
          ansible_host: 192.168.10.11
          cpu: 8
          memory: 32G
          disks:
            - /dev/sda
  vars:
    ansible_user: root
    ansible_ssh_private_key_file: ~/.ssh/id_rsa
  • Почему так? — Видеть все параметры в одном месте упрощает построение ролей Ansible и уменьшает риск «потерять» узел вручную.
  • Как проверить? — Запуск ansible-inventory --graph покажет связь между хостами и группами, а ansible all -m ping подтвердит доступность.

Для домашнего размещения удобно использовать API Proxmox или Docker‑Compose, чтобы описать конфигурацию в виде кода, а не в графическом интерфейсе. Пример команды, которая выводит список контейнеров и их статус:

bash
# Получить статус всех контейнеров на ноде winnie
curl -s "https://api.proxmox.com/api2/json/nodes/winnie/containers?format=json" \
  -H "Authorization: PVEAPIToken=yourtoken@pam!yourtoken_id!yoursecret"

Документация API Proxmox — https://pve.proxmox.com/pve-docs/api-viewer/index.html

Методологии контроля качества

Качество инфраструктуры проверяется на нескольких уровнях: unit‑тесты конфигураций, интеграционные проверки работоспособности сервисов, а также регрессионные тесты, которые гарантируют, что изменения не ломают уже работающие части.

  1. Тесты конфигураций — пишем небольшие скрипты, которые проверяют, что файл /etc/nginx/nginx.conf содержит нужную секцию server и что порт 443 слушает только один процесс. Пример проверки с помощью bash:
bash
#!/usr/bin/env bash
# проверка, что nginx слушает 443 и только один процесс
if [[ $(ss -tlnp | grep ':443' | wc -l) -eq 1 ]]; then
    echo "✅ nginx слушает 443"
else
    echo "❌ Проблема с портом 443"
    exit 1
fi
  1. CI/CD‑pipeline — автоматизируем запуск этих проверок при каждом коммите. Ниже пример workflow для GitHub Actions, который проверяет Ansible‑playbook и запускает ansible-lint:
yaml
name: CI

on:
  push:
    branches: [ main ]
  pull_request:

jobs:
  lint-and-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: "3.11"
      - name: Install ansible-lint
        run: pip install ansible-lint
      - name: Run ansible-lint
        run: ansible-lint playbooks/*.yml
      - name: Run custom health checks
        run: |
          chmod +x ./scripts/health_check.sh
          ./scripts/health_check.sh
  1. Регрессионные проверки ZFS — после изменения пула важно выполнить zpool scrub и убедиться, что статус ONLINE сохраняется. Автоматизировать можно через cron‑задачу, которая отправляет уведомление в Alertmanager, если скраб не завершился за ожидаемое время.
bash
#!/usr/bin/env bash
# скрипт, проверяющий статус ZFS-пула и отправляющий алерт при проблемах
POOL="tank"
STATUS=$(zpool status -s "$POOL" | grep -c "ONLINE")
if [[ $STATUS -ne 1 ]]; then
    curl -X POST -H "Content-Type: application/json" \
         -d "{\"text\":\"⚠️ ZFS‑пул $POOL не в состоянии ONLINE\"}" \
         https://alertmanager.example.com/api/v1/channels/telegram
fi
  • Почему это важно? — Автоматические проверки позволяют поддерживать предсказуемость конфигураций, а не полагаться на ручной контроль, который часто приводит к «пожарам», которые можно было бы избежать.

  • Ссылка на практику — подробнее о CI‑pipeline для инфраструктуры: https://kubernetes.io/docs/setup/bootstrapping/bootstrapping-with-kubeadm/


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

Если вы только начинаете систематизировать своё домашнее размещение, начните с инвентарного файла и простых скриптов‑проверок. Позже добавьте CI‑pipeline, и ваш серверный стек станет надёжным, как проверенный IKEA‑мебельный набор: всё собирается, но с учётом своих нюансов.

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

Docker Compose для микросервисов

Docker Compose — удобный способ собрать несколько контейнеров в одну изолированную сеть, что типично для микросервисных решений в домашней лаборатории.
Пример — небольшая система из трёх сервисов: веб‑frontend, API‑backend и база данных PostgreSQL.

yaml
# docker-compose.yml
version: "3.9"
services:
  frontend:
    image: nginx:alpine
    ports:
      - "8080:80"
    volumes:
      - ./frontend:/usr/share/nginx/html:ro
    depends_on:
      - backend

  backend:
    image: python:3.11-slim
    environment:
      - DATABASE_URL=postgres://user:password@db:5432/app
    volumes:
      - ./backend:/app
    command: ["python", "app.py"]
    depends_on:
      - db

  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
      POSTGRES_DB: app
    volumes:
      - db_data:/var/lib/postgresql/data

volumes:
  db_data:
bash
# Запуск и остановка
docker compose up -d          # старт всех сервисов в фоне
docker compose down           # очистка контейнеров и сетей

Пояснение

  • depends_on гарантирует порядок старта, но не решает проблемы с готовностью базы данных.
  • named volume db_data сохраняет данные PostgreSQL между перезапусками.
  • environment в backend использует переменную DATABASE_URL, что типично для конфигурации через .env‑файл (можно вынести в отдельный файл и добавить env_file: .env).

k3s и Rancher: лёгкое кластерирование

k3s — это дистрибутив Kubernetes, оптимизированный для небольших ресурсов и простого развертывания. Он подходит для домашней лаборатории из трёх нод (например, Raspberry Pi, старый сервер или виртуальные машины).

Установка k3s на первом (master) узле

bash
# На узле, который будет master
curl -sfL https://get.k3s.io | sh -

После установки проверьте статус:

bash
sudo k3s status

Добавление агентов (worker‑нод)

На каждой рабочей ноде выполните:

bash
# Получить токен с master (можно сохранить в файл)
sudo k3s agent --token <TOKEN> --server https://<MASTER_IP>:6443

Пример (токен получен на master):

bash
sudo k3s agent --token abc123def456 --server https://192.168.1.10:6443

базовый набор команд

bash
# Показать узлы кластера
kubectl get nodes

# Развернуть простое приложение (nginx)
kubectl create deployment nginx --image=nginx:alpine
kubectl expose deployment nginx --port=80 --type=NodePort

Rancher — веб‑интерфейс для управления кластером

Rancher устанавливается как отдельный контейнер и упрощает добавление узлов через UI.

bash
docker run -d --restart=unless-stopped \
  -p 80:80 -p 443:443 \
  -v /etc/rancher:/etc/rancher \
  --name rancher rancher/rancher:latest

Откройте браузер и перейдите на http://<SERVER_IP>.
В интерфейсе создайте cluster → Add Cluster → Install k3s → скопируйте команду установки (аналог выше) и выполните её на остальных узлах.

Практический совет
Если в вашей домашней сети есть роутер без поддержки mDNS, укажите явно IP‑адрес master‑ноды в параметре --server. Это избавит от проблем с автодiscovery.


Итого

  • Docker Compose позволяет быстро собрать несколько контейнеров в одну сеть, что удобно для разработки и тестирования микросервисов.
  • k3s и Rancher дают лёгкий способ запустить полноценный Kubernetes‑кластер из нескольких небольших узлов, а веб‑интерфейс Rancher упрощает управление без необходимости писать кучу yaml‑манифестов вручную.

Оба подхода работают предсказуемо, если соблюдать базовые правила: фиксировать версии образов, использовать именованные тома для данных и проверять доступность портов перед запуском.

Хранение и резервное копирование

ZFS на TrueNAS: настройка пулов

Во‑первых, ZFS‑пул — это набор vdev‑ов (virtual devices), каждый из которых отвечает за отказ от ошибок и эффективность I/O. Выбор структуры vdev определяет, как будет распределяться данные и какие потери вы tolerates.

С практической точки зрения обычно используют два подхода:

  1. Mirror (зеркало) – минимум два диска, данные полностью копируются. Позволяет быстро заменить один диск без потери данных.
  2. RAID‑Z (raidz1/2/3) – набор минимум трёх дисков, parity‑информация распределяется по всем дискам. RAID‑Z2 (двухпарный) выдерживает два отказа, RAID‑Z3 — три.

Пример создания пула через CLI

bash
# зеркальный пул из двух дисков /dev/sda и /dev/sdb
zpool create tank mirror /dev/sda /dev/sdb

# RAID‑Z2 из четырёх дисков /dev/sda…/dev/sdg
zpool create tank raidz2 /dev/sda /dev/sdb /dev/sdc /dev/sde

Если используете TrueNAS UI, в разделе Storage → Pools → Add выбираете тип пула, указываете диски и нажимаете Create. После создания пул появляется в списке и готов к созданиюDataset‑ов.

Для контроля состояния пула удобно использовать:

bash
zpool status tank
zpool get all tank

Важно: при создании пула задайте compression = lz4, чтобы уменьшить объём данных без существенной нагрузки на CPU. Это можно задать в свойствах пула:

bash
zpool set compression=lz4 tank

Дополнительные сведения о настройке пулов – в официальной документации TrueNAS: TrueNAS Storage Configuration.


Автоматические бэкапы с rsync и cron

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

Основные параметры rsync

  • -a — режим архивации (рекурсивно, сохраняет права, ссылки, timestamps).
  • -H — сохраняет hard‑links.
  • -A — сохраняет ACL.
  • -X — сохраняет extended attributes.
  • --delete — удаляет из бэкапа файлы, которых уже нет в источнике (синхронизация).
  • -z — сжимает данные при передаче (полезно при ограниченной пропускной способности).

Пример команды rsync для бэкапа домашней директории на удалённый TrueNAS‑сервер

bash
rsync -aHAX --delete -z \
  /home/alexey/  \
  user@truenas:/mnt/backup/home/

В данном примере user@truenas — это SSH‑доступ к TrueNAS (можно настроить ключ без пароля). Путь /mnt/backup/home/ — Dataset, созданный в TrueNAS для хранения бэкапов.

Настройка cron

Cron — стандартный планировщик в Linux. Для автоматизации бэкапа добавляем запись в crontab пользователя, который будет выполнять rsync.

cron
# Ежедневно в 02:30  утра
30 2 * * * /usr/bin/rsync -aHAX --delete -z /home/alexey/ user@truenas:/mnt/backup/home/ >> /var/log/rsync_backup.log 2>&1

Запись разбита на поля:

  • 30 — минутный индекс,
  • 2 — часы,
  • * — день месяца,
  • * — месяц,
  • * — день недели,
  • команда — полный путь к rsync и параметры,
  • >> … — перенаправление вывода в лог‑файл (удобно для отладки).

После добавления записи выполните crontab -l — проверьте, что она появилась.

Проверка и восстановление

После первого запуска проверьте наличие файлов в бэкапе:

bash
ssh user@truenas "ls -l /mnt/backup/home/"

Для восстановления достаточно выполнить обратную команду rsync:

bash
rsync -aHAX --delete -z user@truenas:/mnt/backup/home/ /home/alexey/

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

Замечание: если у вас несколько серверов, удобно использовать ssh-keygen — генерацию ключа на клиенте и копирование публичного ключа в ~/.ssh/authorized_keys на TrueNAS. Это избавит от необходимости вводить пароль каждый раз.


Если понадобится более детальная настройка репликации внутри TrueNAS (например, задача Replication → Tasks), см. раздел «Replication» в официальной документации.

Мониторинг и логирование

Prometheus + Alertmanager: правила тревог

Мониторинг — это не просто сбор метрик, а система, которая сообщает, когда что‑то требует внимания. В Docker‑окружении удобно запускать Prometheus в контейнере, а Alertmanager — для обработки и рассылки алертов.

Шаг 1. Запуск Prometheus

bash
docker run -d \
  --name prometheus \
  -p 9090:9090 \
  -v /path/to/prometheus.yml:/etc/prometheus/prometheus.yml \
  -v /path/to/rules:/etc/prometheus/rules \
  prom/prometheus

файл prometheus.yml (пример минимальной конфигурации):

yaml
global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'docker'
    docker_sd_configs:
      - host: unix:///var/run/docker.sock
    relabel_configs:
      - source_labels: [__meta_docker_container_name]
        target_label: __metrics_path__
      - source_labels: [__meta_docker_container_name]
        target_label: __address__
      - target_label: __address__
        replacement: localhost:9323

Шаг 2. Правила тревог

Создайте файл rules.yml в каталоге rules:

yaml
groups:
  - name: container.rules
    rules:
      - alert: HighCpuUsage
        expr: rate(container_cpu_user_seconds_total{image!=""}[5m]) > 0.8
        for: 2m
        labels:
          severity: warning
        annotations:
          summary: "Высокий CPU‑использование контейнера {{ $labels.container }}"
          description: "CPU‑загрузка превысила 80 % в течение последних 2 минут."

Шаг 3. Конфигурация Alertmanager

yaml
global:
  resolve_timeout: 5m

receivers:
  - name: 'slack'
    slack_configs:
      - api_url: 'https://hooks.slack.com/services/XXX/YYY/ZZZ'
        channel: '#alerts'

route:
  group_by: ['alertname', 'job']
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 1h
  receiver: 'slack'

Запустите Alertmanager аналогично:

bash
docker run -d \
  --name alertmanager \
  -p 9093:9093 \
  -v /path/to/alertmanager.yml:/etc/alertmanager/alertmanager.yml \
  prom/alertmanager

После перезапуска Prometheus начнёт использовать новые правила, а Alertmanager будет отправлять уведомления в Slack (или любой другой канал).

Практический совет – держите правила в отдельном файле и подключайте их через --rule.file в команде запуска Prometheus. Это упрощает версионирование и откат.

Документация Prometheus
Alertmanager docs

Loki для централизованного логирования

Loki — лёгкий системный лог‑коллектор, который работает в паре с Promtail. Он удобно использовать для сбора журналов из Docker‑контейнеров, Proxmox‑нод и других сервисов.

Шаг 1. Запуск Loki

bash
docker run -d \
  --name loki \
  -p 3100:3100 \
  -v /path/to/loki-data:/loki \
  grafana/loki

Шаг 2. Запуск Promtail (агент, который собирает логи)

bash
docker run -d \
  --name promtail \
  --volume /var/log:/var/log \
  --volume /etc/promtail:/etc/promtail \
  -v /path/to/promtail.yaml:/etc/promtail/promtail.yaml \
  grafana/promtail

пример promtail.yaml:

yaml
server:
  http_listen_port: 9080

positions:
  filename: /tmp/positions.yaml

clients:
  - url: http://loki:3100/loki/api/v1/push

scrape_configs:
  - job_name: docker
    docker_sd_configs:
      - host: unix:///var/run/docker.sock
    pipeline_stages:
      - docker: {}
      - labels:
          job: docker
          __path__: /var/log/containers/*.log
    static_configs:
      - targets:
          - localhost
    pipeline_stages:
      - docker: {}
      - labels:
          job: docker
          __path__: /var/log/containers/*.log

Шаг 3. Пример запроса в Grafana

В Grafana создайте дашборд с панелью Loki. Пример запроса:

promql
{job="docker"} |~ "ERROR" | logfmt | line_format "{{.log}}"

Этот запрос ищет все записи, содержащие слово ERROR в журналах Docker‑контейнеров, парсит их как ключевые‑значения и выводит в виде строк.

Полезные рекомендации

  • Фильтрация по уровню – используйте |= "INFO" или |~ "WARN" для сужения результата.
  • Хранение – Loki хранит данные в файлах на диске, поэтому рекомендуется настроить ротацию (--logrotate в Docker‑команде).
  • Интеграция с Prometheus – в Alertmanager можно добавить loki как receiver, чтобы при срабатывании алерта отправлять ссылку на соответствующий запрос Loki.

Официальная документация Loki
Grafana Loki + Promtail tutorial


Итого: Prometheus + Alertmanager — это базовый набор для метрического мониторинга, а Loki — универсальное решение для централизованного сбора и анализа логов. Оба инструмента легко интегрируются в Docker‑окружение и позволяют построить предсказуемую, проверяемую систему мониторинга, которой можно доверять.

Часто задаваемые вопросы

Нужно ли описывать всю инфраструктуру в YAML-файлах?

С практической точки зрения, это вопрос предсказуемости. Если вы описываете параметры узлов в инвентарном файле, вы создаёте единый источник истины, который исключает ошибки ручного ввода. Это позволяет использовать Ansible для автоматизации задач, не гадая, сколько оперативной памяти доступно на конкретном сервере.

Можно ли полностью отказаться от графического интерфейса в пользу API?

Графический интерфейс полезен для быстрой визуальной проверки, но для серьёзной работы он создаёт риск человеческой ошибки. Использование API или конфигурации в виде кода позволяет версионировать изменения и воспроизводить состояние системы. Я предпочитаю работать с конфигами, так как это даёт полный контроль над каждым параметром.

Как начать внедрять системный подход, если инфраструктура небольшая?

Начните с ведения простого инвентарного списка, даже если у вас всего два сервера. Зафиксируйте в нём IP-адреса, версии операционных систем и дисковые массивы. Когда вы увидите свои ресурсы в структурированном виде, переход к автоматизации через Ansible или Docker Compose станет естественным следующим шагом.

Зачем использовать API Proxmox вместо стандартного управления через веб-панель?

Работа через API позволяет интегрировать управление виртуализацией в ваши скрипты и системы мониторинга. Это даёт возможность получать данные о состоянии контейнеров или виртуальных машин в автоматическом режиме, без необходимости заходить в браузер. Такой подход критически важен, когда количество узлов в вашей домашней лаборатории начинает расти.

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