251 lines
15 KiB
Markdown
251 lines
15 KiB
Markdown
# 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.yml` — `setup_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
|
||
│ ├── checks/
|
||
│ │ ├── swarm.py # Docker API: node listesi (sadece Swarm node kontrolü)
|
||
│ │ ├── swarm_services.py # Docker API: iklimco stack servislerinin replica kontrolü
|
||
│ │ ├── actuator.py # Mikroservisler için HTTP actuator health (IP/replica bazlı) check
|
||
│ │ ├── 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.
|
||
|
||
**Mikroservis Ekleme:** `microservice_monitors` bölümü, BE servislerinin Uptime Kuma'ya (actuator ve swarm replica bazında) eklenmesini otomatikleştirir. Yeni bir BE servisi eklendiğinde kod değişikliği gerekmez; sadece bu bölüme servis tanımı ve opsiyonel `replicas.<env>` beklentisi yazılıp setup script çalıştırılır. `replicas.<env>`, ortam bazlı beklenen replica sayısıdır; Docker "desired" değerinden bağımsız çalışır (yanlış scale-down veya deploy edilmeme durumlarını alarm olarak yakalar). Servisin replica değerini kalıcı olarak değiştiriyorsanız, `monitors.yml` dosyasını da güncelleyip imajı rebuild etmelisiniz (çünkü bu dosya imaja gömülüdü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` | Expected RabbitMQ cluster member count (RabbitMQ runs as a single Swarm service — this only sets the expected total, not per-node hostnames) |
|
||
| `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` |
|
||
| `ETCD_HOSTS` | etcd node list (comma-separated `host:port`) — e.g. `etcd-01:2379,etcd-02:2379`; falls back to `etcd-01..0N` derived from `CLUSTER_SIZE_ETCD` |
|
||
| `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_HOSTS` | Optional RabbitMQ endpoint override (comma-separated `host:port`); defaults to the single `rabbitmq` Swarm service — normally leave unset |
|
||
| `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 |
|
||
|
||
**Altyapı Beklentileri (CLUSTER_SIZE_*)**: Altyapı check'leri, `*_HOSTS` listesi `.env` içinde tanımlıysa onu kullanır, tanımsız/boş ise `CLUSTER_SIZE_*` sayısına göre (ör. `etcd-01`, `etcd-02`...) beklenen host listesini otomatik türetir. Bu sayede cluster node sayısını artırıp azaltmak kod veya imaj rebuild gerektirmez.
|
||
|
||
**Monitör Adlandırma Konvansiyonu**: Test ve prod aynı Uptime Kuma'yı paylaştığı için monitörler UK arayüzünde `iklim [<env>] <Ad>` formatıyla oluşturulur. Ancak `uk_tokens.yml` dosyası ve kod içi `push()` fonksiyonu, prefix'siz ham ad (ör. "Stack Services") ile çalışmaya devam eder.
|
||
|
||
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.
|
||
|
||
```bash
|
||
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
|
||
|
||
```bash
|
||
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 Gitea workflow'larıyla deploy edilir:
|
||
|
||
- `.gitea/workflows/deploy-monitoring-test.yml` — `test` branch'ine push ile tetiklenir. Sırası: (1) imajı **build edip** Harbor'a `health-agent:<version>-rc` olarak push'lar ve log'a "Promotion Manifest" (digest + tag) yazdırır, (2) `uk_tokens.yml` yoksa `setup_uptime_kuma.py`'yi çalıştırır, (3) monitoring stack'ini deploy eder.
|
||
- `.gitea/workflows/deploy-monitoring-prod.yml` — `prod-env` branch'ine push ile tetiklenir. **İmaj build etmez**; `health-agent/deploy/prod.env` dosyasındaki `SOURCE_IMAGE_DIGEST`'i çekip `PROD_IMAGE_TAG` ile yeniden etiketleyerek promote eder. Sonrası test ile aynıdır: `uk_tokens.yml` yoksa setup, ardından stack deploy.
|
||
|
||
> ⚠️ **İki kritik davranış:**
|
||
>
|
||
> 1. **Setup adımı `uk_tokens.yml` varken hiç çalışmaz.** Workflow'daki `if [ ! -s uk_tokens.yml ]` koşulu nedeniyle dosya host'ta durduğu sürece `setup_uptime_kuma.py` atlanır. `monitors.yml`'e yeni monitor/group eklediyseniz, deploy öncesinde host'taki `${HEALTH_AGENT_CONFIG_GENERATED_DIR}/uk_tokens.yml` dosyasını silmelisiniz — yoksa yeni monitörler Uptime Kuma'da asla oluşmaz. Script idempotent olduğu için mevcut monitörler güncellenir, yenileri eklenir, token'lar yeniden yazılır.
|
||
> 2. **Aynı tag ile deploy servisi güncellemez.** Stack deploy `--resolve-image changed` kullanır: servis tanımındaki imaj referansı (repo/tag string'i) değişmediyse Swarm digest'i yeniden çözmez ve çalışan container **eski imajla devam eder** — Harbor'da tag'in üzerine yeni imaj yazılmış olsa bile. Bu yüzden her kod değişikliğinde versiyon yükseltmek zorunludur (aşağıdaki release prosedürüne bakın).
|
||
|
||
Ayrıca `config/monitors.yml` ve `scripts/setup_uptime_kuma.py` **imaja gömülüdür** — setup adımı `docker run` ile yalnızca `config/generated/` dizinini mount eder. Repo'da `monitors.yml`'i değiştirip merge etmek tek başına hiçbir şeyi değiştirmez; değişikliğin etkili olması için imajın yeniden build edilmesi gerekir.
|
||
|
||
Manuel deploy için:
|
||
|
||
```bash
|
||
# ö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 \
|
||
monitoring
|
||
```
|
||
|
||
Health-agent `iklimco-net` overlay ağına bağlı olmalı ve Docker socket'a salt okunur erişimi olmalıdır.
|
||
|
||
---
|
||
|
||
## Güncelleme / Release Prosedürü
|
||
|
||
Health-agent'ta herhangi bir değişiklik (kod, `monitors.yml`, bağımlılık) prod'a şu adımlarla çıkar. Adımların hiçbiri atlanamaz — özellikle versiyon yükseltme (bkz. yukarıdaki ⚠️ notları):
|
||
|
||
1. **Versiyonu yükselt:** `health-agent/pyproject.toml` içindeki `version` alanını artır (ör. `0.2.0` → `0.3.0`). Build script tag'i buradan okur; tag değişmezse Swarm çalışan servisi güncellemez.
|
||
2. **İmajı build et ve push'la** (`main` branch'inde, `Environment_Monitoring/` kökünden):
|
||
```bash
|
||
HARBOR_CI_TOKEN=<token> ./ops/build-and-push-health-agent.sh
|
||
```
|
||
Alternatif: `test` branch'ine push'lamak test workflow'unda aynı build'i yapar. Her iki yol da çıktının sonunda "Promotion Manifest" basar:
|
||
```
|
||
SOURCE_IMAGE_DIGEST=registry.tarla.io/iklimco/health-agent@sha256:<digest>
|
||
PROD_IMAGE_TAG=<version>
|
||
```
|
||
3. **Manifest'i prod'a yaz:** `prod-env` branch'inde `health-agent/deploy/prod.env` dosyasına yukarıdaki iki satırı aynen yaz (`PROD_IMAGE_TAG` `-rc` içeremez). Bu dosyanın kaynak doğrusu `prod-env` branch'idir; `main`'deki kopyası kullanılmaz.
|
||
4. **Gerekliyse `uk_tokens.yml`'i sil:** Yalnızca `monitors.yml`'e yeni monitor/group/status-page eklediyseniz, prod host'taki `${HEALTH_AGENT_CONFIG_GENERATED_DIR}/uk_tokens.yml` dosyasını silin ki setup adımı yeniden çalışsın. Salt kod değişikliğinde dosyaya ve Uptime Kuma'daki monitörlere dokunmayın.
|
||
5. **`prod-env`'i push'la:** `main`'i `prod-env`'e merge edip `prod.env` değişikliğiyle birlikte push'layın — push, prod workflow'unu tetikler.
|
||
6. **Doğrula:**
|
||
```bash
|
||
docker service inspect monitoring_health-agent --format '{{.Spec.TaskTemplate.ContainerSpec.Image}}'
|
||
```
|
||
Çıktı `health-agent:<yeni-version>@sha256:<yeni-digest>` olmalı. Ardından `docker service logs monitoring_health-agent` ile check'lerin push'landığını ve Uptime Kuma'da monitörlerin yeşile döndüğünü kontrol edin. Deploy `stop-first` olduğu için heartbeat'lerde 1-2 dakikalık boşluk normaldir.
|
||
|
||
**Sıfırdan kurulum / monitörleri yeniden yaratma:** Uptime Kuma'daki monitörler silinip baştan oluşturulacaksa, hem UK'daki eski monitör/grupları hem de host'taki `uk_tokens.yml`'i silin; aksi halde eski push monitörlerine heartbeat gelmeyeceği için sahte "down" alarmları üretilir.
|
||
|
||
---
|
||
|
||
## Log Formatı
|
||
|
||
Agent JSON formatında log üretir. Grafana Explore (Loki datasource, `{service="monitoring_health-agent"}`) veya `docker service logs monitoring_health-agent` ile izlenebilir. Her log girdisi şu alanları içerir:
|
||
|
||
- `check` — monitor adı
|
||
- `status` — `up` veya `down`
|
||
- `msg` — Uptime Kuma'ya iletilen mesaj
|
||
- `ping_ms` — check süresi
|
||
- `source` — `health-agent` veya `health-agent/events`
|
||
- `error` — yalnızca hata durumunda; exception detayı
|