Murat ÖZDEMİR 58d5c24f41
Some checks failed
Deploy Environment Monitoring to Production Environment / deploy (push) Failing after 10s
feat(health-agent): add CI/CD pipeline, Uptime Kuma setup, and runtime configuration
Deploy workflows:
- Integrate health-agent build (test) and image promotion (prod) into monitoring stack workflows
- Add storagebox download of health-agent runtime (.env.monitoring.health-agent-runtime → health-agent/.env) and setup (.env.monitoring.health-agent-setup → health-agent/.env.setup) env files
- Add "Run Uptime Kuma Setup" step: runs setup_uptime_kuma.py inside the built image only when uk_tokens.yml is missing, writes tokens to HEALTH_AGENT_CONFIG_GENERATED_DIR (/mnt/storagebox/monitoring/uk_generated)
- Add health-agent/** and health-agent/deploy/prod.env path triggers to test and prod workflows respectively
- Add HARBOR_CI_TOKEN login and HARBOR_PULL_TOKEN login before stack deploy in both workflows
- Source health-agent/.env before docker stack deploy to expose HEALTH_AGENT_CONFIG_GENERATED_DIR

Dockerfile:
- Copy config/ and scripts/ into image so setup_uptime_kuma.py can run inside the container

setup_uptime_kuma.py:
- Load .env and .env.setup automatically via python-dotenv (no manual export needed)
- Write uk_tokens.yml to config/generated/ (aligned with container volume mount)

Health checks:
- PATRONI_HOSTS and VAULT_HOSTS are now configurable via env vars (comma-separated host:port); no code change needed when node count changes
- REDIS_SENTINEL_HOSTS now correctly parses host:port format; default updated to redis-sentinel:26379
- Fix NameError in check_patroni_cluster() caused by leftover node variable after loop refactor
- Remove verify_ssl=False from Vault check; vault.iklim.co has a valid certificate

Ops:
- Add ops/build-and-push-health-agent.sh for manual bypass of CI pipeline
- Add health-agent/deploy/prod.env template for prod image promotion manifest

Project structure:
- Move .env.example and .env.setup.example to health-agent/env-example/ (root .gitignore excludes health-agent/.env*)
- Add root .gitignore: excludes uk_tokens.yml, __pycache__, .venv, and env files
- Remove health-agent/.gitignore (superseded by root .gitignore)
2026-06-26 18:45:17 +03:00
..

iklim.co Health Agent

Docker Swarm cluster içinde çalışan, push modeli üzerinden Uptime Kuma'ya sağlık durumu ileten ve Docker olaylarını Slack'e doğrudan bildiren hafif bir Python servisidir. Gelen bağlantı gerekmez — tüm trafik dışa yönelik HTTPS'tir.


Mimari

Agent, Swarm manager node üzerinde tek replica olarak çalışır ve şu kaynaklara erişir:

  • /var/run/docker.sock (salt okunur) — Swarm servislerini, node'ları ve event stream'ini dinler
  • iklimco-net overlay ağı — tüm iç servislere DNS adıyla erişir
  • StorageBox bind mount (salt okunur) — sertifika dosyaları ve yapılandırma varlığını kontrol eder
  • config/generated/uk_tokens.ymlsetup_uptime_kuma.py tarafından üretilir, agent bu dosyayı okur

Her check bağımsız çalışır ve kendi Uptime Kuma monitörüne push yapar. Bir check'in başarısız olması diğerlerini etkilemez.

Slack bildirimleri iki kanaldan gelir:

  • [Uptime Kuma] — Uptime Kuma'nın kendi HTTP/DNS/Ping monitörleri tarafından üretilir
  • [Health Agent] — health-agent'ın push check'lerinden; Uptime Kuma'nın group monitor mekanizması üzerinden iletilir
  • [Health Agent / Events] — Docker events stream'den gelen anlık restart/OOM bildirimleri; doğrudan Slack webhook'una gönderilir, Uptime Kuma'dan geçmez

Dizin Yapısı

Environment_Monitoring/health-agent/
├── config/
│   ├── monitors.yml              # tüm monitor/group/tag/status-page tanımları; node IP'leri buraya yazılır
│   └── generated/
│       └── uk_tokens.yml         # setup_uptime_kuma.py tarafından üretilir; health-agent okur
├── src/
│   └── health_agent/
│       ├── main.py               # giriş noktası; scheduler loop
│       ├── config.py             # .env + uk_tokens.yml yükler; ortam ayarlarını expose eder
│       ├── uptime_kuma.py        # push(token, status, msg, ping_ms) yardımcısı
│       ├── slack.py              # notify(webhook, source, priority, title, detail, uk_group_url) — kaynak etiketli + UK grup linki
│       ├── state.py              # restart sayısı gibi session-arası state'i dosyaya yazar/okur
│       ├── checks/
│       │   ├── swarm.py          # Docker API: node listesi, servis replica sayıları
│       │   ├── http.py           # genel HTTP check + uygulama bazlı parser'lar (Patroni, Vault, RabbitMQ...)
│       │   ├── tcp.py            # TCP port erişilebilirliği
│       │   ├── tls.py            # TLS sertifika son kullanma tarihi (dosyadan veya handshake'den)
│       │   ├── redis_sentinel.py # Redis Sentinel — redis-py ile quorum ve master kontrolü
│       │   ├── mongodb.py        # MongoDB rs.status() — pymongo ile PRIMARY ve lag kontrolü
│       │   └── filesystem.py     # StorageBox mount varlığı ve SSL cert sync durumu
│       └── events/
│           └── docker_events.py  # arka plan thread'i; Docker /events stream'ini dinler, restart/OOM bildirir
├── scripts/
│   └── setup_uptime_kuma.py     # monitors.yml'i okur, UK'da oluşturur, uk_tokens.yml'e yazar
├── Dockerfile
├── pyproject.toml
├── .env.example                  # health-agent runtime değişkenleri (credentials, ENV, CLUSTER_SIZE_*)
└── .env.setup.example            # setup script değişkenleri (UK_URL, UK_USER, UK_PASS, Slack webhook'ları)

Yapılandırma

config/monitors.yml — Tüm monitor, group, tag ve status page tanımları bu dosyadadır. Yeni bir monitor eklemek için kod değişikliği gerekmez; monitors.yml'e yeni bir blok eklenir ve setup_uptime_kuma.py çalıştırılır.

.env — Runtime değişkenler:

Variable Description
UK_PUSH_URL_BASE Uptime Kuma push base URL (e.g. https://status.iklim.co/api/push)
ENV prod or test
CLUSTER_SIZE_ETCD etcd node count (prod: 3, test: 1)
CLUSTER_SIZE_PATRONI Patroni node count
CLUSTER_SIZE_MONGODB MongoDB node count
CLUSTER_SIZE_RABBITMQ RabbitMQ node count
CLUSTER_SIZE_VAULT Vault node count
REDIS_MODE sentinel or standalone
EXTERNAL_DOMAIN Base domain — iklim.co in both environments
EXTERNAL_SUBDOMAIN_SUFFIX Subdomain suffix — empty for prod, -test for test → api-test.iklim.co
SLACK_WEBHOOK_IKLIM_{ENV}_OPS Direct Slack webhook for container crash/OOM events — e.g. SLACK_WEBHOOK_IKLIM_PROD_OPS
PATRONI_HOSTS Patroni node list (comma-separated host:port) — e.g. patroni-01:8008,patroni-02:8008
VAULT_HOSTS Vault node subdomain list (comma-separated) — e.g. vault-1,vault-2,vault-3
RABBITMQ_USER / RABBITMQ_PASS RabbitMQ management credentials
MONGO_URI MongoDB connection URI
REDIS_PASSWORD Redis / Sentinel password
REDIS_MASTER_NAME Redis Sentinel master name
REDIS_SENTINEL_HOSTS Sentinel host list (comma-separated host:port)
STORAGEBOX_PATH StorageBox mount path for filesystem check
APISIX_ADMIN_KEY APISIX admin API key for health check

Check periyotları monitors.yml'de her monitor için tanımlanır; .env'e eklenmez.

Push token'ları config/generated/uk_tokens.yml'den otomatik okunur — bu dosya setup_uptime_kuma.py tarafından üretilir ve .env'e elle kopyalanmaz.


Yeni Check Ekleme

  1. src/health_agent/checks/ altına yeni bir dosya ekle veya uygun mevcut dosyaya yeni bir fonksiyon ekle.
  2. Fonksiyon (ok: bool, msg: str, ping_ms: int) tuple'ı döndürmeli.
  3. config/monitors.yml'e yeni monitor bloğu ekle (isim, grup, öncelik, bildirim kanalı, check periyodu).
  4. setup_uptime_kuma.py'yi çalıştır — yeni monitor UK'da oluşturulur ve token uk_tokens.yml'e yazılır.
  5. main.py'de check fonksiyonunu token ve yapılandırmayla kaydet.

İlk Kurulum (Uptime Kuma)

Health-agent deploy edilmeden önce kurulum script'i çalıştırılır. Script, monitors.yml'i okuyarak tüm monitor, tag, group ve status page'leri Uptime Kuma'da oluşturur; push token'larını config/generated/uk_tokens.yml'e yazar.

Script uptime-kuma-api-v2 kütüphanesini kullanır; Socket.IO üzerinden username/password ile bağlanır.

cd Environment_Monitoring/health-agent

# Python 3.12 venv oluştur ve aktive et
python3.12 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"

# runtime ve setup değişkenlerini doldur
cp .env.example .env        # ENV, EXTERNAL_DOMAIN vb.
cp .env.setup.example .env.setup  # UK_URL, UK_USER, UK_PASS, Slack webhook'ları

# önce dry-run ile ne yapılacağını gör
python scripts/setup_uptime_kuma.py --dry-run

# tüm kaynakları oluştur
python scripts/setup_uptime_kuma.py

# sadece belirli bir monitörü işle (monitor adıyla)
python scripts/setup_uptime_kuma.py --only SWARM-CLUSTER

Script idempotent çalışır — CI/CD pipeline'ında her deploy'da güvenle tetiklenebilir.


Notification Flood Önleme

Uptime Kuma group monitor mekanizması kullanılır: Slack bildirimi child monitor'lere değil, yalnızca group monitor'e bağlanır. Bir grup içinde birden fazla monitor aynı anda çökse dahi tek bildirim üretilir.

Planlı bakım/deploy sırasında etkilenecek group için Uptime Kuma'da Maintenance penceresi açılır (API üzerinden otomatik yapılabilir). Bu süre zarfında alarm üretilmez.


Yerel Geliştirme

cd Environment_Monitoring/health-agent

# Python 3.12 venv oluştur ve aktive et
python3.12 -m venv .venv
source .venv/bin/activate

# bağımlılıkları kur
pip install -e ".[dev]"

# .env dosyasını hazırla
cp .env.example .env

# check'leri bir kez çalıştır, Uptime Kuma'ya push etme
python -m health_agent.main --once --dry-run

# check'leri bir kez çalıştır, Uptime Kuma'ya gerçekten push et
python -m health_agent.main --once

# tam scheduler'ı başlat
python -m health_agent.main

--once: her check'i bir kez çalıştırıp çıkar. --dry-run: Uptime Kuma push'larını atlar, sadece loglar. İkisi birlikte credential ve bağlantı doğrulaması için kullanılır.


Deployment

Monitoring stack ve health-agent ayrı Gitea workflow'larıyla deploy edilir:

  • .gitea/workflows/deploy-monitoring-prod.yml — prod ortamı
  • .gitea/workflows/deploy-monitoring-test.yml — test ortamı

Her iki workflow da şu sırayı izler: (1) setup_uptime_kuma.py çalıştır → uk_tokens.yml üret, (2) monitoring stack'i deploy et, (3) health-agent stack'ini deploy et.

Manuel deploy için:

# önce setup_uptime_kuma.py çalıştır
python scripts/setup_uptime_kuma.py

# tek stack: portainer + loki + promtail + health-agent
docker stack deploy \
  --with-registry-auth \
  -c docker-stack-monitoring.yml \
  iklimco-monitoring

Health-agent iklimco-net overlay ağına bağlı olmalı ve Docker socket'a salt okunur erişimi olmalıdır.


Log Formatı

Agent JSON formatında log üretir. Grafana Explore (Loki datasource, {service="iklimco-monitoring_health-agent"}) veya docker service logs iklimco-monitoring_health-agent ile izlenebilir. Her log girdisi şu alanları içerir:

  • check — monitor adı
  • statusup veya down
  • msg — Uptime Kuma'ya iletilen mesaj
  • ping_ms — check süresi
  • sourcehealth-agent veya health-agent/events
  • error — yalnızca hata durumunda; exception detayı