Overvåking med Zabbix

Applikasjonsovervåking

Man må gjøre 2 ting for å aktivere automatisk overvåking av en applikasjon:

  1. Definere noen "annotation" parametere i Openshift som definerer metadataen som trenges for å aktivere/konfigurere overvåking i zabbix.
  2. Levere status informasjon for applikasjonen via HTTP protokollen under e.g. https://applikasjonsnavn.domene/health

"annotation" parametere i Openshift som må defineres per applikasjon som skal overvåkes er:

I tillegg brukes det disse interne metadata parametere i openshift for en applikasjon:

['metadata']['namespace']
['metadata']['name']
['spec']['host']

Formatet som må brukes for å definere status informasjonen for versjon 3 er følgende:

{
  "metadata": {
    "updated": 1581397535091,
    "health-file-version": 3
  },

  "components": {

    "component-1": {
      "status": true,
      "severity": "warning"
    },

    "component-2": {
      "status": true,
      "severity": "warning"
    },

    "component-N": {
      "status": true,
      "severity": "warning"
    }
  }
}

Verdier som brukes i json dokumentet er:

Antall komponenter i uio.no/zabbix.monitor.url url'en er avhengig av applikasjonen som leverer status informasjon.

Status på disse komponenter er fra applikasjonssynspunktet, e.g. hvis en applikasjon trenger en database for å fungere, kan det hende at databasen er oppe og fungerer uten problemer, men hvis applikasjonen ikke kan koble seg til databasen (e.g. problemer med nettet eller autentisering) vil status på database komponenten i status url'en være 'false' (error).

Det er applikasjonen som må teste internt og finne ut status på alle komponentene den bruker og vil levere status for.

Man trenger ikke å levere statusinformasjon for noen komponenter hvis applikasjonen ikke er avhengig av eksterne komponenter, eller ikke har funksjonalitet for å finne ut om den har problemer med en eller flere komponenter. I dette tilfellet er det bare url'en til applikasjonen som overvåkes.

Hvis man ikke kan/vil levere status informasjon for noen komponenter, trenger man kun levere json-blokken med 'metadata'-informasjon.

Overvåking av Kubernetes-relaterte objekter

Hvordan fungerer Kubernetes-overvåking med Zabbix?

Før du begynner å lage overvåkingsregler, er det nyttig å forstå hvordan disse systemene jobber sammen:

PrometheusRule (din YAML-fil)
     ↓ (evaluerer PromQL expressions kontinuerlig)
Prometheus (samler metrics fra pods/containers)
     ↓ (når en regel triggers)
AlertManager (mottar alerts)
     ↓ (sender kun alerts med severity: critical)
Zabbix scraper-script på zabbix-proxy-servere, som henter alle alert-definisjoner og tilstand.
     ↓ (oppretter items og triggers)
Zabbix (viser alarmer i dashboards)

Hvordan komponentene fungerer sammen:

Viktig å vite:

Hvordan navngis items og triggers i Zabbix?

Når du oppretter en PrometheusRule, vil Zabbix automatisk generere et item med et langt navn. Å forstå hvordan dette navnet bygges opp hjelper deg med å finne dine alarmer i Zabbix.

Navneformatet:

lld for alert manager rules - critical: Alert manager rules - critical: [GROUP_NAME]_[ALERT_NAME]_critical

Hvordan navnet bygges opp:

Del av navnet Kommer fra Eksempel
lld for alert manager rules - critical: Alert manager rules - critical: Fast prefix fra Zabbix (alltid samme) -
[GROUP_NAME] .spec.groups[].name i din PrometheusRule amedov-test-app
[ALERT_NAME] .spec.groups[].rules[].alert i din PrometheusRule PodCpuUsageExceedingRequest
_critical .spec.groups[].rules[].labels.severity critical

Konkret eksempel:

Hvis du har denne PrometheusRule:

spec:
  groups:
  - name: amedov-test-app              # Dette blir GROUP_NAME
    rules:
    - alert: PodCpuUsageExceedingRequest  # Dette blir ALERT_NAME
      labels:
        severity: critical              # Dette blir _critical suffix

Vil itemet i Zabbix hete:

lld for alert manager rules - critical: Alert manager rules - critical: amedov-test-app_PodCpuUsageExceedingRequest_critical

Best practices for navngiving:

CPU og minne-overvåking

Hvis man ønsker å overvåke metrics fra Kubernetes-objekter, som f.eks minnebruk eller CPU-bruk for en pod, og få alarm på dette, så trenger du først å opprette en PrometheusRule, hvor du definerer en Prometheus expression for det du ønsker å generere en alert for. Denne vil så generere en alert i AlertManager når expression returnerer riktig resultat.

Hva denne regelen gjør

Dette eksemplet overvåker om pods i ditt namespace bruker mer CPU enn de har bedt om (request). Hvis en pod bruker over 100% av requested CPU i mer enn 10 minutter, får du alarm i Zabbix. Dette er nyttig for å oppdage pods som trenger mer ressurser enn de har fått tildelt.

Eksempel på CPU-overvåking

Nedenfor følger eksempel på hvordan du genererer en alert for CPU-bruk:

apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: pod-cpu-request-exceeded-alert # Navnet på PrometheusRule-objektet
  namespace: amedov-test # Prosjektet du skal overvåke
spec:
  groups:
  - name: amedov-test-app # F.eks om du skal overvåke en spesifikk komponent av din app, kan du sette navnet her. F.eks nettskjema-backend
    rules:
    - alert: PodCpuUsageExceedingRequest # Dette blir det faktiske navnet på alarmen i Zabbix, sammen med gruppenavnet overfor
      expr: |
        # Hvor mye CPU podet faktisk bruker (målt over siste 5 min)
        sum(rate(container_cpu_usage_seconds_total{container!="",container!="POD"}[5m])) by (pod, namespace)
        /
        # Hvor mye CPU du har requested for poden
        sum(kube_pod_container_resource_requests{resource="cpu",unit="core"}) by (pod, namespace)
        > 1  # Trigger når faktisk bruk er over 100% av request (1.0 = 100%)
      for: 10m # Alarmen triggers kun når CPU-bruken har vært over grensen i 10 minutter sammenhengende
      labels:
        severity: critical # Det er kun severity = critical som blir generert alarmer for i Zabbix
        okd_service: amedov-test # Dette blir generert som en tag på itemet i Zabbix, slik at du enkelt kan filtrere på den
      annotations: # Disse annotations blir aldri videresendt til Zabbix, men vises i AlertManager
        summary: "Pod {{ $labels.pod }} exceeding CPU request"
        description: "Pod {{ $labels.pod }} is using {{ $value | humanizePercentage }} of requested CPU"

Hvordan tilpasse denne regelen

Du kan enkelt tilpasse denne regelen til dine behov:

Endre terskelen for CPU-bruk:

> 1     # Trigger ved 100% av request
> 0.8   # Trigger ved 80% av request
> 1.5   # Trigger ved 150% av request

Endre måleperioden (hvor lenge CPU-bruk måles):

[5m]    # Måler gjennomsnittlig CPU-bruk over siste 5 minutter
[10m]   # Måler gjennomsnittlig CPU-bruk over siste 10 minutter
[1m]    # Måler gjennomsnittlig CPU-bruk over siste 1 minutt

Endre hvor lenge problemet må vare før alarm:

for: 10m    # Alarm etter 10 minutter med høy CPU
for: 5m     # Alarm etter 5 minutter med høy CPU
for: 1m     # Alarm etter 1 minutt med høy CPU

Overvåke kun spesifikke pods:

expr: |
  sum(rate(container_cpu_usage_seconds_total{container!="",container!="POD",pod=~"my-app-.*"}[5m])) by (pod, namespace)
  /
  sum(kube_pod_container_resource_requests{resource="cpu",unit="core",pod=~"my-app-.*"}) by (pod, namespace)
  > 1

Overvåke minnebruk i stedet for CPU:

expr: |
  sum(container_memory_working_set_bytes{container!="",container!="POD"}) by (pod, namespace)
  /
  sum(kube_pod_container_resource_requests{resource="memory",unit="byte"}) by (pod, namespace)
  > 1  # Trigger når minnebruk er over 100% av request

Etter at den blir lagt til i et prosjekt, tar det det ca. 5 min før automatikken i Zabbix fanger det opp, og genererer en item.

For å se at itemen er på plass, logger du deg inn på Zabbix, hvor du søker opp host-objektet til clusteret som innholder itemene, ie. api.<cluster-navn>, f.eks api.okd-dev.uio.no, og ser etter det nye itemet. For eksempelet over, vil itemet bli kalt lld for alert manager rules - critical: Alert manager rules - critical: amedov-test-app_PodCpuUsageExceedingRequest_critical. Alarmen vil bli trigget når alerten har status Firingi AlertManager, mens selve triggeren i Zabbix vil ha severity Average, så ha det i bakhodet når du genererer dashboardet hvor du vil inkludere denne alarmen.

Hvis du genererer en alert som ikke ryddes vekk automatisk, så vil den bli liggende igjen i Zabbix til du enten løser det som genererer alerten, eller silencer alerten i Openshift.
For alarmen over, så vil den løse seg automatisk, når podens CPU-bruk har gått ned.

Overvåking av CronJobs

Dette eksemplet overvåker om CronJobs i ditt namespace kjører som de skal. Hvis en CronJob ikke har hatt en vellykket kjøring på over 2 minutter, får du alarm. Dette er nyttig for å oppdage CronJobs som feiler eller har stoppet opp.

Viktig: Denne regelen er kun et eksempel. Du må tilpasse tidsvinduet (2 minutter i eksemplet) til hvor ofte din CronJob skal kjøre. Hvis CronJobben kjører hver time, bør du sette terskelen til f.eks 70 minutter for å få alarm hvis den ikke kjører.

Følgende regel kan brukes for å overvåke en K8S CronJob:

apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: cronjob-test
  namespace: amedov-test
spec:
  groups:
  - name: app-cronjob  # Gruppenavn som identifiserer hvilken CronJob/komponent dette gjelder
    rules:
    - alert: cronJobNotRunning
      annotations:
        description: 'cronjob is not running'
        summary: cronjob is not running
      expr: (time() - kube_cronjob_status_last_successful_time{namespace="amedov-test"})/60 > 2
      # Forklaring av expression:
      # time() = nåværende tid (i sekunder siden epoch)
      # kube_cronjob_status_last_successful_time = tidspunkt for siste vellykkede kjøring
      # Differansen deles på 60 for å få minutter
      # > 2 betyr at alarmen triggers hvis det har gått mer enn 2 minutter siden siste vellykkede kjøring
      for: 1m  # Alarmen triggers hvis tilstanden har vart i 1 minutt
      labels:
        severity: critical  # Kun critical alerts sendes til Zabbix
        okd_service: "amedov-test"  # Tag for filtrering i Zabbix

Denne alerten vil dukke opp i Zabbix som lld for alert manager rules - critical: Alert manager rules - critical: app-cronjob_cronJobNotRunning_critical.

Tilpass tidsvinduet til hvor ofte CronJobben kjører:

# CronJob som kjører hvert 5. minutt - alarm hvis ikke kjørt på 7 minutter:
expr: (time() - kube_cronjob_status_last_successful_time{namespace="amedov-test"})/60 > 7

# CronJob som kjører hver time - alarm hvis ikke kjørt på 70 minutter:
expr: (time() - kube_cronjob_status_last_successful_time{namespace="amedov-test"})/60 > 70

# CronJob som kjører daglig - alarm hvis ikke kjørt på 25 timer:
expr: (time() - kube_cronjob_status_last_successful_time{namespace="amedov-test"})/3600 > 25

Overvåke en spesifikk CronJob (hvis du har flere):

expr: (time() - kube_cronjob_status_last_successful_time{namespace="amedov-test",cronjob="my-cronjob-name"})/60 > 70

Få alert hvis CronJob feiler (i stedet for bare ikke kjører):

- alert: cronJobFailed
  expr: kube_cronjob_status_failed{namespace="amedov-test"} > 0
  for: 5m
  labels:
    severity: critical
    okd_service: "amedov-test"
  annotations:
    summary: "CronJob {{ $labels.cronjob }} has failed"
    description: "CronJob {{ $labels.cronjob }} has {{ $value }} failed jobs"

Feilsøking og verifisering

Når du har opprettet en PrometheusRule, er det viktig å verifisere at den fungerer som forventet. Her er en steg-for-steg guide for å sjekke at alt er satt opp riktig.

Verifisere at PrometheusRule er opprettet

Første steg er å sjekke at PrometheusRule er opprettet i Kubernetes:

# Se alle PrometheusRules i ditt namespace
oc get prometheusrule -n <namespace>

# Se detaljer om en spesifikk regel
oc describe prometheusrule <rule-name> -n <namespace>

Hvis PrometheusRule ikke finnes, sjekk at YAML-filen er korrekt og kjør oc apply -f <fil.yaml>.

Sjekke at itemet dukker opp i Zabbix

Etter at PrometheusRule er opprettet:

  1. Vent 5 minutter - Zabbix-automatikken sjekker for nye alerts hvert 5. minutt
  2. Logg inn på Zabbix: https://monitor.uio.no
  3. Søk etter host: api.<cluster-navn> (f.eks api.okd-dev.uio.no)
  4. Gå til "Items" for hosten
  5. Søk etter ditt item: Bruk gruppenavn eller alert-navn for å finne det

Itemet vil hete: lld for alert manager rules - critical: Alert manager rules - critical: <group-name>_<alert-name>_critical

Sjekke alerts i AlertManager

For å se om din PrometheusRule faktisk triggers og sender alerts til AlertManager:

  1. Åpne Alerts-fanen under Obvserve i Openshift web ui: https://console-openshift-console.apps.<cluster>.uio.no/dev-monitoring/ns/amedov-test/alerts/
    • Eksempel: https://console-openshift-console.apps.okd-dev.uio.no/dev-monitoring/ns/amedov-test/alerts
  2. Sjekk alert status:
    • Inactive: Regelen er ok, ingen problemer detektert
    • Pending: Regelen har trigget, men venter på for: perioden
    • Firing: Alerten er aktiv og sendt til Zabbix

Teste PromQL expressions

Hvis du er usikker på om PromQL-uttrykket ditt fungerer:

Åpne nettleseren på https://console-openshift-console.apps.okd-dev.uio.no/dev-monitoring/ns/amedov-test/metrics og gå til "Metrics"-fanen. Her kan du:

Vanlige problemer og løsninger

Problem: Itemet dukker ikke opp i Zabbix

Mulige årsaker:

Problem: Alarmen trigger ikke selv om problemet eksisterer

Mulige årsaker:

Problem: Alarmen forsvinner ikke når problemet er løst

Mulige årsaker:

Løsning: Gå til Alerts-fanen og silence alerten manuelt hvis den ikke auto-resolves. For CronJobs, sørg for at jobben kjører på nytt.

Problem: Kan ikke finne itemet i Zabbix

Mulige årsaker: