Prometheus und Grafana
Seit Containly 2.7.3 stellt Containly /metrics für Prometheus bereit: Endpoint erreichbar, CPU, Arbeitsspeicher und Disk der Hosts, Zustand, Health, Neustarts, CPU und Arbeitsspeicher der Container. Free, standardmässig aus, mit Metrik-Token geschützt. Scrape-Konfiguration, Metriken und Grafana-Abfragen.
Containly 2.7.3 exportiert seine Host- und Container-Metriken im Textformat von Prometheus. Ein Scrape deckt alle Hosts ab, die Containly verwaltet. Der Export ist Free und standardmässig aus.
Einschalten
- Öffne als Admin Einstellungen > Integrationen.
- Schalte Prometheus-Export ein. Lass API-Token verlangen eingeschaltet (empfohlen).
- Öffne Profil > API-Tokens, erstelle ein Token mit der Berechtigung Prometheus-Metriken (und sonst nichts) und kopiere es.
- Kopiere die Scrape-Konfiguration aus der Karte in deine
prometheus.ymlund lege das Token in die Datei, die untercredentials_filesteht.
scrape_configs:
- job_name: containly
scrape_interval: 60s
scheme: https
metrics_path: /metrics
authorization:
type: Bearer
credentials_file: /etc/prometheus/containly.token
static_configs:
- targets: ['containly.example.com']
Containly misst einmal pro Minute, scrape_interval: 60s reicht also; kürzere Intervalle liefern einfach dieselben Werte (ein Scrape fragt nie Docker, er liest den Zwischenspeicher von Containly).
Von Hand prüfen:
curl -H "Authorization: Bearer $TOKEN" https://containly.example.com/metrics
Ist der Export aus, antwortet /metrics mit 404, ohne Token mit 401, mit einem Token ohne Metrik-Berechtigung mit 403. Nur wenn /metrics ausschliesslich aus einem vertrauenswürdigen Netz erreichbar ist, darfst du API-Token verlangen ausschalten: Dann kann jeder, der Containly erreicht, Containernamen und Ressourcenverbrauch lesen.
Metriken
Labels: endpoint (Name des Hosts in Containly), stack (Compose-Projekt, leer bei einzelnen Containern), container (Name), image (Referenz ohne Digest). Keine Container-IDs, ein neu erstellter Container erzeugt also keine neuen Zeitreihen; pro Host werden höchstens 500 Container aufgeführt.
| Metrik | Bedeutung |
|---|---|
containly_info{version,edition} | Version und Edition (free oder pro) |
containly_endpoint_up{endpoint} | 1, wenn der Host erreichbar ist |
containly_host_cpu_percent | CPU-Auslastung des Hosts in Prozent |
containly_host_memory_used_bytes, containly_host_memory_total_bytes | Arbeitsspeicher des Hosts |
containly_host_disk_used_bytes, containly_host_disk_total_bytes | Docker-Datendisk |
containly_host_sample_timestamp_seconds | Zeitpunkt der letzten Host-Messung |
containly_containers{endpoint,state} | Anzahl Container pro Zustand |
containly_container_state{...,state} | 1 für den aktuellen Zustand (running, exited, restarting, paused, created, dead) |
containly_container_health{...,health} | 1 für healthy, unhealthy, starting oder none (kein Health-Check) |
containly_container_restarts | Neustart-Zähler von Docker (beginnt bei 0, wenn der Container neu erstellt wird) |
containly_container_cpu_percent | CPU eines laufenden Containers in Prozent einer CPU |
containly_container_memory_bytes | Arbeitsspeicher eines laufenden Containers |
containly_containers_dropped{endpoint} | Container, die über 500 pro Host weggelassen wurden |
Grafana
Füge Prometheus als Datenquelle hinzu und baue Panels mit diesen Abfragen:
- Hosts nicht erreichbar:
containly_endpoint_up == 0 - CPU der Hosts:
containly_host_cpu_percent - Arbeitsspeicher in Prozent:
100 * containly_host_memory_used_bytes / containly_host_memory_total_bytes - Disk in Prozent:
100 * containly_host_disk_used_bytes / containly_host_disk_total_bytes - Container mit Health-Problem:
containly_container_health{health="unhealthy"} == 1 - Nicht laufend:
containly_container_state{state!="running"} == 1 - Höchste CPU:
topk(10, containly_container_cpu_percent) - Arbeitsspeicher pro Stack:
sum by (endpoint, stack) (containly_container_memory_bytes) - Neustarts in der letzten Stunde:
delta(containly_container_restarts[1h]) > 0
Beispiel für eine Alarmregel:
groups:
- name: containly
rules:
- alert: ContainerUnhealthy
expr: containly_container_health{health="unhealthy"} == 1
for: 5m
labels: {severity: warning}
annotations:
summary: "{{ $labels.container }} auf {{ $labels.endpoint }} ist unhealthy"
Datenschutz
Der Export ist rein eingehend: Prometheus verbindet sich mit Containly, Containly sendet nichts weg. In der öffentlichen Demo wird der Export ausgeschaltet gezeigt.