5 Commits

Author SHA1 Message Date
44519e842b feat: add cAdvisor, Loki, Alertmanager and Node-RED support
- Добавлена роль cAdvisor для мониторинга Docker контейнеров
- Добавлены Loki и Promtail для сбора и хранения логов
- Добавлен Alertmanager с конфигурацией для Node-RED интеграции
- Добавлена роль Node-RED для автоматизации обработки алертов
- Настроена интеграция Prometheus → Alertmanager → Node-RED
- Все контейнеры запускаются на app3 (192.168.0.112)
2026-02-05 02:23:27 +00:00
27e692c1ed Merge branch 'feature/add-cadvisor-support' into new-feature-branch 2026-02-04 13:21:43 +00:00
338e0b0f19 Add cadvisor support with monitoring stack: alertmanager, loki, node-red, promtail 2026-02-04 13:21:16 +00:00
83178d9a0d Merge pull request 'Enhance cAdvisor role and add deployment playbook' (#7) from feature/add-cadvisor-support into main
Reviewed-on: #7
2026-02-04 12:48:29 +00:00
0d85bd53aa Enhance cAdvisor role and add deployment playbook
- Updated cAdvisor default variables for better configuration
- Modified cAdvisor tasks to improve deployment process
- Added dedicated playbook for cAdvisor deployment and monitoring

This commit completes the cAdvisor monitoring integration.
2026-02-04 12:47:46 +00:00
18 changed files with 344 additions and 40 deletions

View File

@ -0,0 +1,6 @@
---
- name: Deploy Alertmanager
hosts: 192.168.0.112 # app3
become: true
roles:
- alertmanager

View File

@ -0,0 +1,6 @@
---
- name: Deploy cAdvisor on App3
hosts: 192.168.0.112 # Указываем конкретный хост
become: true
roles:
- cadvisor

View File

@ -0,0 +1,6 @@
---
- name: Deploy Loki
hosts: 192.168.0.112 # app3
become: true
roles:
- loki

View File

@ -0,0 +1,6 @@
---
- name: Deploy Node-RED
hosts: 192.168.0.112 # app3
become: true
roles:
- node-red

View File

@ -0,0 +1,6 @@
---
- name: Deploy Promtail on all nodes
hosts: all # Установим Promtail на все хосты для сбора логов
become: true
roles:
- promtail

View File

@ -0,0 +1,12 @@
---
# Alertmanager settings
alertmanager_port: 9093
alertmanager_config_path: /etc/alertmanager
# Email notifications (заполнить позже)
smtp_host: localhost
smtp_from: alertmanager@example.com
smtp_to: admin@example.com
# Webhook для тестирования
webhook_url: "http://localhost:9099"

View File

@ -0,0 +1,33 @@
---
- name: Create Alertmanager directories
file:
path: "{{ item }}"
state: directory
owner: root
group: root
mode: '0755'
loop:
- "{{ alertmanager_config_path }}"
- /var/lib/alertmanager
- name: Deploy Alertmanager configuration
template:
src: alertmanager.yml.j2
dest: "{{ alertmanager_config_path }}/alertmanager.yml"
owner: root
group: root
mode: '0644'
- name: Run Alertmanager container
docker_container:
name: alertmanager
image: prom/alertmanager:latest
state: started
restart_policy: always
ports:
- "{{ alertmanager_port }}:9093"
volumes:
- "{{ alertmanager_config_path }}/alertmanager.yml:/etc/alertmanager/alertmanager.yml"
- /var/lib/alertmanager:/alertmanager
command: --config.file=/etc/alertmanager/alertmanager.yml --storage.path=/alertmanager
tags: alertmanager

View File

@ -0,0 +1,52 @@
global:
# Настройки для уведомлений (можно настроить позже)
# smtp_smarthost: 'smtp.gmail.com:587'
# smtp_from: 'alertmanager@example.com'
# smtp_auth_username: 'user@gmail.com'
# smtp_auth_password: 'password'
# smtp_require_tls: true
route:
# Основной маршрут - все алерты идут в Node-RED
receiver: 'node-red-webhook'
group_by: ['alertname', 'severity']
group_wait: 10s
group_interval: 10s
repeat_interval: 1h
# Вложенные маршруты
routes:
- match:
severity: critical
receiver: 'node-red-critical'
group_wait: 5s
repeat_interval: 10m
- match:
severity: warning
receiver: 'node-red-warning'
group_wait: 30s
repeat_interval: 2h
receivers:
- name: 'node-red-webhook'
webhook_configs:
- url: 'http://node-red:1880/webhook/alertmanager'
send_resolved: true
- name: 'node-red-critical'
webhook_configs:
- url: 'http://node-red:1880/webhook/critical'
send_resolved: true
- name: 'node-red-warning'
webhook_configs:
- url: 'http://node-red:1880/webhook/warning'
send_resolved: true
inhibit_rules:
- source_match:
severity: 'critical'
target_match:
severity: 'warning'
equal: ['alertname', 'instance']

View File

@ -1,6 +1,9 @@
--- ---
# cAdvisor configuration # Default port for cAdvisor
cadvisor_version: "latest" cadvisor_port: 8080
cadvisor_port: 8081
cadvisor_image: "gcr.io/cadvisor/cadvisor:{{ cadvisor_version }}" # Network configuration
cadvisor_container_name: "cadvisor" cadvisor_network_mode: "host" # Альтернатива: использовать host network для избежания конфликтов портов
# Alternative: use different port if default is busy
cadvisor_fallback_ports: [8081, 8082, 8083, 8084]

View File

@ -1,51 +1,43 @@
--- ---
- name: Ensure cAdvisor container is running - name: Check for available port for cAdvisor
community.docker.docker_container: shell: |
name: "{{ cadvisor_container_name }}" for port in 8080 8081 8082 8083 8084 8085; do
image: "{{ cadvisor_image }}" if ! ss -tulpn | grep -q ":${port} "; then
echo "${port}"
break
fi
done
args:
executable: /bin/bash
register: available_port
changed_when: false
tags: cadvisor
- name: Ensure Docker container for cAdvisor is running
docker_container:
name: cadvisor
image: gcr.io/cadvisor/cadvisor:latest
state: started state: started
restart_policy: unless-stopped restart_policy: always
ports: ports:
- "{{ cadvisor_port }}:8080" - "{{ available_port.stdout | default('8084') }}:8080"
volumes: volumes:
- "/:/rootfs:ro" - "/:/rootfs:ro"
- "/var/run:/var/run:ro" - "/var/run:/var/run:ro"
- "/sys:/sys:ro" - "/sys:/sys:ro"
- "/var/lib/docker/:/var/lib/docker:ro" - "/var/lib/docker/:/var/lib/docker:ro"
- "/dev/disk/:/dev/disk:ro" - "/dev/disk/:/dev/disk:ro"
- "/var/run/docker.sock:/var/run/docker.sock:ro"
privileged: true privileged: true
devices: devices:
- "/dev/kmsg:/dev/kmsg" - "/dev/kmsg:/dev/kmsg"
cgroup_parent: "docker.slice"
tags: cadvisor tags: cadvisor
- name: Configure UFW for cAdvisor - name: Display cAdvisor access info
ufw:
rule: allow
port: "{{ cadvisor_port }}"
proto: tcp
comment: "cAdvisor metrics"
tags: cadvisor
- name: Wait for cAdvisor to be ready
wait_for:
port: "{{ cadvisor_port }}"
host: "{{ ansible_host }}"
delay: 2
timeout: 60
tags: cadvisor
- name: Verify cAdvisor is accessible
uri:
url: "http://{{ ansible_host }}:{{ cadvisor_port }}/metrics"
return_content: true
status_code: 200
register: cadvisor_check
until: cadvisor_check.status == 200
retries: 5
delay: 3
tags: cadvisor
- name: Show cAdvisor status
debug: debug:
msg: "cAdvisor successfully deployed at http://{{ ansible_host }}:{{ cadvisor_port }}/metrics" msg: |
cAdvisor is available at:
- Web UI: http://{{ inventory_hostname }}:{{ available_port.stdout | default('8084') }}
- Metrics: http://{{ inventory_hostname }}:{{ available_port.stdout | default('8084') }}/metrics
tags: cadvisor tags: cadvisor

View File

@ -0,0 +1,9 @@
---
# Default port for Loki
loki_port: 3100
# Storage configuration
loki_storage_path: /var/lib/loki
# Retention period
loki_retention_period: 720h # 30 дней

33
roles/loki/tasks/main.yml Normal file
View File

@ -0,0 +1,33 @@
---
- name: Create Loki directories
file:
path: "{{ item }}"
state: directory
owner: root
group: root
mode: '0755'
loop:
- /etc/loki
- /var/lib/loki
- name: Deploy Loki configuration
template:
src: loki-config.yml.j2
dest: /etc/loki/loki-config.yml
owner: root
group: root
mode: '0644'
- name: Run Loki container
docker_container:
name: loki
image: grafana/loki:latest
state: started
restart_policy: always
ports:
- "3100:3100"
volumes:
- /etc/loki/loki-config.yml:/etc/loki/loki-config.yml
- /var/lib/loki:/loki
command: -config.file=/etc/loki/loki-config.yml
tags: loki

View File

@ -0,0 +1,33 @@
auth_enabled: false
server:
http_listen_port: 3100
grpc_listen_port: 9096
common:
path_prefix: /tmp/loki # Изменяем путь на /tmp для теста
storage:
filesystem:
chunks_directory: /tmp/loki/chunks
rules_directory: /tmp/loki/rules
replication_factor: 1
ring:
instance_addr: 127.0.0.1
kvstore:
store: inmemory
limits_config:
allow_structured_metadata: false
schema_config:
configs:
- from: 2020-10-24
store: boltdb-shipper
object_store: filesystem
schema: v11
index:
prefix: index_
period: 24h
ruler:
alertmanager_url: http://alertmanager:9093

View File

@ -0,0 +1,9 @@
---
# Node-RED settings
node_red_port: 1880
node_red_data_dir: /var/lib/node-red
node_red_image: nodered/node-red:latest
# Persistence settings
node_red_persist_flows: true
node_red_enable_projects: false

View File

@ -0,0 +1,32 @@
---
- name: Create Node-RED data directory with correct permissions
file:
path: "{{ node_red_data_dir }}"
state: directory
owner: 1000 # Node-RED контейнер запускается от пользователя 1000
group: 1000
mode: '0755'
- name: Run Node-RED container
docker_container:
name: node-red
image: "{{ node_red_image }}"
state: started
restart_policy: always
ports:
- "{{ node_red_port }}:1880"
volumes:
- "{{ node_red_data_dir }}:/data"
user: "1000:1000" # Запускаем от правильного пользователя
env:
NODE_RED_ENABLE_PROJECTS: "{{ 'true' if node_red_enable_projects else 'false' }}"
TZ: "UTC"
tags: node-red
- name: Display Node-RED access info
debug:
msg: |
Node-RED is available at:
- Web UI: http://{{ inventory_hostname }}:{{ node_red_port }}
- API: http://{{ inventory_hostname }}:{{ node_red_port }}/red/api
tags: node-red

View File

@ -0,0 +1,7 @@
---
# Loki connection
loki_host: 192.168.0.112
loki_port: 3100
# Promtail settings
promtail_port: 9080

View File

@ -0,0 +1,31 @@
---
- name: Create Promtail directories
file:
path: /etc/promtail
state: directory
owner: root
group: root
mode: '0755'
- name: Deploy Promtail configuration
template:
src: promtail-config.yml.j2
dest: /etc/promtail/promtail-config.yml
owner: root
group: root
mode: '0644'
- name: Run Promtail container (using host network)
docker_container:
name: promtail
image: grafana/promtail:latest
state: started
restart_policy: always
network_mode: host # <-- КЛЮЧЕВОЕ ИЗМЕНЕНИЕ
volumes:
- /var/log:/var/log:ro
- /var/lib/docker/containers:/var/lib/docker/containers:ro
- /etc/promtail/promtail-config.yml:/etc/promtail/config.yml
command: -config.file=/etc/promtail/config.yml
pid_mode: host
tags: promtail

View File

@ -0,0 +1,28 @@
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /tmp/positions.yaml
clients:
- url: http://localhost:3100/loki/api/v1/push # Теперь localhost работает
scrape_configs:
- job_name: system
static_configs:
- targets:
- localhost
labels:
job: varlogs
__path__: /var/log/*log
host: "{{ inventory_hostname }}"
- job_name: docker
static_configs:
- targets:
- localhost
labels:
job: docker
__path__: /var/lib/docker/containers/*/*log
host: "{{ inventory_hostname }}"