Настраиваем мониторинг виртуальных машин в Cloud.ru 🚀

MLPops

MLPops / January 06, 2025

9 мин.

Привет! 👋 Сегодня я расскажу, как я настроил мониторинг своих виртуальных машин (ВМ) в Cloud.ru. Это будет не сухое руководство, а скорее дружеская беседа о том, как я заменил nginx на Traefik, подключил мониторинг с помощью Prometheus и Grafana, и настроил алерты, чтобы всегда быть в курсе состояния своих серверов. Если вы хотите прокачать свою облачную инфраструктуру, то эта статья для вас! 😉


Начало пути: сеть и базовая настройка VPC

Схема сети

Итак, у меня есть две виртуальные машины:

  • ВМ1: 10.0.0.6
  • ВМ2: 10.0.0.5

Также у каждой ВМ есть внешний IP-адрес для доступа из интернета.

🖼️ Схема сети:

Векторные базы данных

Настройка безопасности 🛡️

После создания ВМ нужно было донастроить группу безопасности:

  1. Добавил правила для SSH (порт 22) и ICMP (для проверки доступности машин через ping).
  2. Изменения вступают в силу примерно через 5–10 минут.
Векторные базы данных

Проверяем доступность машин 🧪

После настройки сети важно проверить, видят ли машины друг друга внутри VPC.

Подключение по SSH

Подключаемся к одной из машин (например, ВМ1):

ssh user@<внешний_IP_ВМ1>

Проверка соседей

Смотрим таблицу ARP:

arp -n
Векторные базы данных

Если всё окей, вы увидите IP второй машины (10.0.0.5). Теперь проверим её доступность:

ping 10.0.0.5
Векторные базы данных

Если пинг не проходит, можно попробовать сбросить настройки сети:

  1. Сбрасываем сетевые настройки
sudo cloud-init clean
  1. Запускаем автоматическую настройку сетевого интерфейса
sudo cloud-init init

И делаем reboot двух тачек, если с первого раза не заработало, повторяем,

Подключаем домен 🌐

Чтобы управлять сервисами через удобный адрес, я привязал свой домен к публичному IP одной из машин. Это делается через панель управления доменами у вашего регистратора — просто добавьте A-запись с вашим IP.

Ставим Docker и Docker Compose

Docker

В пару шагов поставим docker

  1. Откройте терминал.

  2. Запустите команду для установки Docker:

curl -fsSL https://get.docker.com | sh
  1. Проверьте установку Docker:
docker --version
  1. (Опционально) Добавьте своего пользователя в группу Docker для запуска без sudo:
sudo usermod -aG docker $USER

Перезагрузите систему или выйдите и снова войдите в систему, чтобы изменения вступили в силу.

Если вам не критично, чтобы у вас была самая последняя версия Docker Compose, то давайте сделаем это проще — установим его из репозитория Ubuntu. Всё просто, как дважды два!

Docker Compose

Просто вбиваете в терминал вот эту команду:

sudo apt-get install docker-compose

Настройка Traefik 🚦

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

  1. Создаём папку для Traefik:
    mkdir traefik && cd traefik
  2. Создаём файл docker-compose.yml с конфигурацией.
version: "3.3"
 
services:
 
  traefik:
    image: "traefik:v3.2"
    container_name: "traefik"
    command:
      - "--providers.docker=true" # Включает использование Docker в качестве провайдера конфигурации для Traefik.
      - "--providers.docker.exposedbydefault=false" # Запрещает автоматическое выставление всех контейнеров наружу (требуется явное указание).
      - "--entryPoints.web.address=:80"  # Настраивает точку входа `web` на порту 80 (HTTP).
      - "--entrypoints.web.http.redirections.entryPoint.to=websecure" # Перенаправляет весь HTTP-трафик на точку входа `websecure` (HTTPS).
      - "--entrypoints.web.http.redirections.entryPoint.scheme=https"  # Указывает схему для перенаправления HTTP-трафика — HTTPS.
      - "--entryPoints.websecure.address=:443" # Настраивает точку входа `websecure` на порту 443 (HTTPS).
      - "--certificatesresolvers.myresolver.acme.dnschallenge=true" # Включает использование DNS Challenge для автоматической выдачи SSL-сертификатов.
      - "--certificatesresolvers.myresolver.acme.dnschallenge.provider=timewebcloud" # Указывает провайдера DNS Challenge — Timeweb Cloud.
      - "--certificatesresolvers.myresolver.acme.email=noreply@example.ru" # Указывает email для регистрации SSL-сертификатов через ACME.
      - "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json" # Указывает путь для хранения данных ACME (например, сертификатов и ключей).
      - "--metrics.prometheus=true" # Включает метрики Prometheus для мониторинга состояния Traefik.
      - "--metrics.prometheus.buckets=0.100000, 0.300000, 1.200000, 5.000000" # Настраивает интервалы (buckets) гистограммы метрик Prometheus.
      - "--metrics.prometheus.addEntryPointsLabels=true"  # Добавляет метки точек входа в метрики Prometheus.
      - "--metrics.prometheus.addServicesLabels=true"  Добавляет метки сервисов в метрики Prometheus.
      - "--entryPoints.metrics.address=:8899"   # Настраивает точку входа `metrics` на порту 8899 для экспорта метрик Prometheus.
      - "--metrics.prometheus.entryPoint=metrics" # Указывает точку входа `metrics` для экспорта данных в Prometheus.
    ports:
      - "80:80"
      - "443:443"
    environment:
      - "TIMEWEBCLOUD_AUTH_TOKEN=token" # Передает токен аутентификации Timeweb Cloud в переменной окружения для DNS Challenge
    volumes:
      - "./letsencrypt:/letsencrypt" # Монтирует локальную директорию `./letsencrypt` в контейнер по пути `/letsencrypt`.
      - "/var/run/docker.sock:/var/run/docker.sock:ro"
    networks:
      - traefik-net
 
 
networks:
  traefik-net:
    name: traefik-net
    external: true
    
  1. Запустите Traefik:
    docker-compose up -d

Настройка экспортеров метрик 🛠️

Экспортеры — это инструменты, которые собирают метрики с ваших серверов и контейнеров. Я использую два экспортера:

  • Node Exporter — собирает системные метрики (CPU, память, диски).
  • cAdvisor — собирает метрики контейнеров.
  1. На первой машине создаём папку:

    mkdir exporter && cd exporter
  2. Создаем docker-compose.yml для запуска cAdvisor и Node Exporter.

services:
 
  node-exporter:
    image: prom/node-exporter:latest
    container_name: node-exporter
    volumes:
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
      - /:/rootfs:ro
    command:
      - '--path.procfs=/host/proc'
      - '--path.sysfs=/host/sys'
      - '--collector.filesystem.ignored-mount-points=^/(sys|proc|dev|host|etc)($$|/)'
    restart: always
    networks:
      - traefik-net
 
  cadvisor:
    image: gcr.io/cadvisor/cadvisor:latest
    container_name: cadvisor
    volumes:
      - /:/rootfs:ro
      - /var/run:/var/run:rw
      - /sys:/sys:ro
      - /var/lib/docker/:/var/lib/docker:ro
    restart: always
    networks:
      - traefik-net
      
networks:
  traefik-net:
    name: traefik-net
 
  1. Запустите экспортеры:
    docker-compose up -d

Настройка Grafana и Prometheus 📈

Создаём директорию для мониторинга:

mkdir monitoring && cd monitoring

Конфигурация Grafana

Создаём файл grafana/datasource.yml с источниками данных:

services:
  prometheus:
    image: prom/prometheus
    container_name: prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
    ports:
      - 9090:9090
    restart: unless-stopped
    volumes:
      - ./prometheus:/etc/prometheus
      - prom_data:/prometheus
    networks:
      - traefik-net
 
  grafana:
    image: grafana/grafana
    container_name: grafana
    restart: unless-stopped
    environment:
      - GF_SECURITY_ADMIN_USER=admin
      - GF_SECURITY_ADMIN_PASSWORD=grafana
    volumes:
      - grafana-data:/var/lib/grafana
      - ./grafana:/etc/grafana/provisioning/datasources
    networks:
      - traefik-net
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.monitoring.rule=Host(`monitoring.mlpops.ru`)"
      - "traefik.http.routers.monitoring.entrypoints=websecure"
      - "traefik.http.routers.monitoring.tls.certresolver=myresolver"
      
networks:
  traefik-net:
    name: traefik-net
 
volumes:
  prom_data:
  grafana-data:
 

Настройка Prometheus и Grafana

Структура папок

Создайте структуру папок на первой машине:

/home
- monitoring
  - prometheus/
    - prometheus.yml
  - grafana/
    - datasource.yml
  - docker-compose.yml

Конфигурация Grafana

Добавьте источник данных в grafana/datasource.yml:

apiVersion: 1
 
datasources:
- name: Prometheus
  type: prometheus
  url: http://prometheus:9090 
  isDefault: true
  access: proxy
  editable: true

Конфигурация Prometheus

Добавим в prometheus/prometheus.yml, это наши источники куда grafana будет смотреть что бы рисовать графики.

global:
  scrape_interval: 15s
  scrape_timeout: 10s
  evaluation_interval: 15s
 
alerting:
  alertmanagers:
  - static_configs:
    - targets: []
    scheme: http
    timeout: 10s
 
scrape_configs:
- job_name: prometheus
  honor_timestamps: true
  scrape_interval: 15s
  scrape_timeout: 10s
  metrics_path: /metrics
  scheme: http
  static_configs:
    - targets:
      - localhost:9090
 
- job_name: traefic
  honor_timestamps: true
  scrape_interval: 15s
  scrape_timeout: 10s
  metrics_path: /metrics
  scheme: http
  static_configs:
    - targets:
      - traefik:8899
 
 
- job_name: 'node'
  static_configs:
    - targets:
      - node-exporter:9100
 
- job_name: 'cadvisor'
  static_configs:
    - targets:
      - cadvisor:8080
 

Запустите Prometheus и Grafana:

docker-compose up -d

Праваливаемся в нашу графану по адресу grafana.example.ru. Логинемся под пользователем admin и grafana. Создаем пользователя, делаем его админом, логинемся за него и удалеям нашего user.

Так, графану вроде подняли, добавим теперь наши Dashboard, мы в конфиги добавили 3 экспортера, traefic, node-exporter, cadvisor. И что бы самим не делать графики, то мы просто импортнем их.

Импорт готовых дашбордов 📊

Чтобы не создавать графики вручную, мы воспользуемся готовыми шаблонами из Grafana Labs. Для каждого экспортера (cAdvisor, Node Exporter, Traefik) есть свои дашборды.

Список дашбордов

Вот три дашборда, которые я использую:

ЭкспортерID дашбордаСсылка на дашборд
cAdvisor14282cAdvisor Dashboard
Node Exporter1860Node Exporter Full
Traefik Dashboard17346Traefik Dashboard

Процесс импорта

  1. Копируем ID нужного дашборда.
  2. В Grafana нажимаем ”+” → Import.
  3. Вставляем скопированный ID в поле импорта.
  4. Выбираем источник данных (Prometheus).

Копируем их id

Векторные базы данных

Идем в Grafana, жмем кнопку “New” -> “New Dashboard”

Векторные базы данных

Далее “Import dashboard”

Векторные базы данных

И вставляем скопирование id

Векторные базы данных

🎉 После импорта вы получите готовые графики с метриками ваших серверов и контейнеров.

Векторные базы данных

Добавление метрик с другой виртуальной машины 🖥️

Теперь настроим сбор метрик с машины 10.0.0.6. Для этого:

  1. Подключаемся к машине через SSH.
  2. Устанавливаем Docker (если он ещё не установлен).
  3. Создаём папку для экспортёров:
    mkdir exporter && cd exporter

Создадим манифест docker-compose.yaml

version: '3.8'
 
networks:
  internal_network:
    driver: bridge
    ipam:
      config:
        - subnet: "192.168.1.0/24"
 
services:
  cadvisor:
    image: gcr.io/cadvisor/cadvisor
    container_name: cadvisor
    networks:
      - internal_network
    ports:
      - "8080:8080"  # Локальный доступ
    volumes:
      - /:/rootfs:ro
      - /var/run:/var/run:rw
      - /sys:/sys:ro
      - /var/lib/docker/:/var/lib/docker:ro
 
  node-exporter:
    image: prom/node-exporter
    container_name: node-exporter
    networks:
      - internal_network
    ports:
      - "9100:9100"  # Локальный доступ
    volumes:
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
      - /:/rootfs:ro
 
networks:
  internal_network:
    driver: bridge
 
  1. Запускаем экспортёры:
    docker-compose up -d

Теперь метрики доступны по адресам public_ip:8080 и public_ip:9100. Однако оставлять эти порты открытыми небезопасно, поэтому закроем их для внешнего доступа.

Закрытие портов с помощью iptables 🔒

Чтобы ограничить доступ к портам только для внутренней сети VPC, используем следующие команды:

# Разрешить доступ с машины 10.0.0.5 к порту cAdvisor (8080)
iptables-legacy -A INPUT -s 10.0.0.5 -p tcp --dport 8080 -j ACCEPT
 
# Разрешить доступ с машины 10.0.0.5 к порту Node Exporter (9100)
iptables-legacy -A INPUT -s 10.0.0.5 -p tcp --dport 9100 -j ACCEPT
 
# Запретить все остальные подключения к этим портам
iptables-legacy -A INPUT -p tcp --dport 8080 -j DROP
iptables-legacy -A INPUT -p tcp --dport 9100 -j DROP

Теперь только машина 10.0.0.5 сможет получать метрики от 10.0.0.6.


Добавление новых экспортёров в Prometheus 🛠️

На машине с Prometheus (10.0.0.5) обновляем файл prometheus.yml, добавив новые источники:

...
 
- job_name: 'node'
  static_configs:
    - targets:
      - node-exporter:9100 # Локальный Node Exporter
      - 10.0.0.6:9100      # Node Exporter на второй машине
 
- job_name: 'cadvisor'
  static_configs:
    - targets:
      - cadvisor:8080       # Локальный cAdvisor
      - 10.0.0.6:8080       # cAdvisor на второй машине
 
...

После этого перезапускаем Prometheus:

docker-compose restart prometheus

Итоговая настройка 🎉

Теперь у вас есть полноценная система мониторинга с Grafana, Prometheus и экспортёрами метрик на двух машинах! Вы можете отслеживать состояние серверов, контейнеров и получать уведомления о проблемах в реальном времени.

Если у вас остались вопросы или вы хотите поделиться своими успехами — пишите в комментариях или нашем Telegram канале! 😊