Monitoring OCI instancí pomocí Prometheus (Service Discovery)

Cloudů je dneska plnej internet. Já vím, že když nepoužíváte AWS, tak jste totální loser, kterej si ani neumí zavázat tkaničky… (aspoň tak se mi to jeví podle některých siláckých prohlášení), ale já bych se dneska podíval na jinou cloudovou alternativu a hlavně — jak ji monitorovat.

OCI

Oracle Cloud Infrastructure (OCI) je IaaS platforma, která se — nejen z pohledu dnes probíraného monitoringu, ale třeba i architektury — nijak neliší od toho, co můžete potkat v AWS, Azure, nebo GCP. OCI se skládá z několika produktů, nicméně dneska se zaměřím pouze na Compute.

Jak název napovídá, Compute poskytuje výpočetní zdroje — můžeme nastartovat VM instance s požadovanými parametry (jako počet CPU a velikost paměti), tyto VM-ka běží ve specifické VCN (Virtual Cloud Network) a v daném subnetu atd. A samozřejmě, můžeme si nakonfigurovat nějaké load-balancery, nebo omezit síťovou komunikaci pomocí security lists.

Dobrá… máme nainstancovaná nějaká VM-ka a chtěli bychom je monitorovat — jak na to? Jedním, v cloudu velmi dobře etablovaným řešením na monitorování je Prometheus suita. Takže, jak zapřáhneme Prometheus, aby nám monitoroval OCI instance?

Prometheus

Cíle (targets), které Prometheus monitoruje, se definují pomocí scrape configuration. A ačkoliv out-of-the-box obsahuje Prometheus podporu pro service discovery většiny etablovaných cloudů, OCI mezi ně nepatří.

Nevadí, říkám si — napíšu si OCI Service Discovery sám. Proštudoval jsem si, jak funguje service discovery v AWS, v Azure, v GCP, v OpenStack, a v Kubernetes; forknul Prometheus a během celkem krátké doby napsal a odladil service discovery pro OCI.

Bohužel, vývojáři Promethea si uložili moratorium na přidávání nových poskytovatelů service discovery a můj pull request zamítli. Místo toho mi doporučili adaptovat file-based service discovery jako preferovanou alternativu.

Tento způsob discovery znamená, že Prometheus periodicky načítá určitý soubor (nebo množinu souborů), který obsahuje seznam monitorovaných cílů. Obsahem tohoto souboru je JSON struktura v následujícím formátu:

[
  {
    "targets": [ "<host>", ... ],
    "labels": {
      "<labelname>": "<labelvalue>", ...
    }
  },
  ...
]

Tudíž otázka je, jak tento soubor naplnit seznamem OCI instancí, ideálně s nějakými smysluplnými labely?

OCI Service Discovery

Long story short, napsal jsem oci-sd, které funguje úplně stejně, jako to, co jsem dopsal do Promethea, akorát nakonci vyprodukuje zmíněný soubor. Navíc se dá spustit jako command-line aplikace (daemon), nebo se dá naimportovat jako Golang package do jiné aplikace.

Sekvenční diagram OCI Service Discovery

Sekvenční diagram OCI Service Discovery

Jak je vidět z obrázku, OCI-SD se periodicky dotazuje OCI API pro získání seznamu instancí (v daném compartmentu). Potom instace transformuje na targets s určitými metadaty a na konci zapíše výsledek do souboru. Soubor je poté periodicky načítán Prometheem, který “pře-labeluje” (re-label) metadata a eventuálně zahodí cíle, které nemají být monitorovány.

Let’s try it!

Žijeme v “éře GitHubu”, takže mít dobrou dokumentaci a příklady/ukázky je kritické. Proto jsem jako součást oci-sd projektu připravil krátký tutoriál, kde je popsáno jak:

  • nastartovat testovací OCI instance pomocí Terraformu, každá instance s běžícím node_exporterem,
  • nakonfigurovat a spustit oci-sd aplikaci, která “objeví” spuštěné OCI instance,
  • nastartovat Prometheus s file_sd konfigurací, který začne instance monitorovat.

Testovací OCI instance

Potřebné testovací instance lze, samozřejmě, vytvořit ručně v OCI admin konzoli, nicméně současným trendem (hype? 😉) je Infrastructure as Code (IaC), tak proč to nevyužít? V adresáři example/terraform je sada Terraform skriptů, pro jejichž spuštění jsou potřeba dvě věci: Terraform binárka a OCI tenance s politikou, která umožňuje spravovat zdroje.

Pokud jste se pustili do tohoto scénáře, tak předpokládám, že pro vás není magií OCI CLI konfigurace. Pro spuštění Terraform skriptů je potřeba nastavit několik environment variables: nejjednodušší cesta je poeditovat soubor env-vars a uložit ho s vašima specifickýma hodnotama:

Pak můžeme proměnné vyexportovat a spustit Terraform:

  1. . env-vars
  2. terraform init
  3. terraform plan
  4. terraform apply -auto-approve

Během několika minut bychom měli vidět následující (zkrácený) Terraform výstup a rovněž běžící instance v OCI konzoli:

Apply complete! Resources: 8 added, 0 changed, 0 destroyed.

Outputs:

private-ips = [
    10.1.0.3,
    10.1.0.4,
    10.1.0.2
]
public-ips = [
    129.146.78.36,
    129.146.121.86,
    129.146.125.2
]
Přehled instancí v OCI konzoli

Přehled instancí v OCI konzoli

Na každé z těchto instancí by měl běžet node_exporter na portu 9100. Tento port by měl být otevřený v nakonfigurovaném security listu:

Security list s otevřeným portem pro node_exporter

Security list s otevřeným portem pro node_exporter

Že je všechno v pořádku můžeme zkontrolovat utilitkou curl:

curl <public-ip-of-your-instance>:9100/metrics

Pokud se v konzoli objeví následující (zkrácený) výstup (node_exporter metriky), jsme připraveni na service discovery.

# HELP go_gc_duration_seconds A summary of the GC invocation durations.
# TYPE go_gc_duration_seconds summary
go_gc_duration_seconds{quantile="0"} 2.5834e-05
go_gc_duration_seconds{quantile="0.25"} 5.6118e-05
go_gc_duration_seconds{quantile="0.5"} 6.008e-05
go_gc_duration_seconds{quantile="0.75"} 6.812e-05
go_gc_duration_seconds{quantile="1"} 0.000120973
go_gc_duration_seconds_sum 0.118491416
go_gc_duration_seconds_count 1997

oci-sd

Pro běh oci-sd jako standalone aplikace je potřeba dodat konfigurační soubor. Standardně se nazývá oci-sd.toml a měl by obsahovat všechny ty OCI přístupové hodnoty, které jsme už využili u Terraform skriptů:

Po spuštění oci-sd aplikace, např.

./oci-sd -c oci-sd.toml -o oci-sd.json

bychom měli (zhruba po 1 minutě) vidět obdobný obsah v souboru oci-sd.json:

Voilà, už to skoro máme!

Prometheus

Nakonfigurovat Prometheus, aby získal monitorované cíle ze souboru oci-sd.json, je jednoduché. Trochu náročnější může být re-labeling, tak tady je krátká ukázka:

Tato konfigurace řekne Prometheovi, aby:

  • načetl cíle ze souboru oci-sd.json,
  • sestavil URL monitorovaného cíle z veřejné IP adresy dané OCI instance a portu 9100,
  • pár jednoduchých pře-labelování (instance_id, instance_name atd.),
  • zahodil všechny cíle, které nemají free-form tag node_exporter

Pokud spustíme Prometheus s touto konfigurací, měli bychom v GUI vidět nové monitorované cíle:

Nové OCI instance jako Prometheus targets

Nové OCI instance jako Prometheus targets

Když se ještě vrátím k Prometheusovskému re-labelování — kompletní množinu dostupných meta-labelů lze najít v oci-sd dokumnetaci: Metadata labels.

Time to play!

Nyní můžeme monitorovat naše OCI instance v daném kompártmentu a tak je čas trochu prozkoumat, že service discovery je opravdu dynamické — můžeme zkusit zastavit, nebo zrušit nějakou instanci, vytvořit novou instanci manuálně, nebo Terraformem a tak dál.

Je dobré mít na paměti dvě věci. Za prvé, chviličku trvá, než se změny v Prometheovi objeví — propagace změny je výsledkem tří(!) refresh intervalů v oci-sd a v Prometheovi.

A za druhé, speciálně pro nově vytvářené instace, definovali jsme filtrování instancí pomocí free-form tagu, tak aby nás nezaskočilo, že instance bez tohoto tagu se neukazují jako cíle.

Tak, to je všechno! Happy monitoring a ozvěte se mi s vašimi nápady a problémy!