Kompozícia kontajnerov

alebo o tom, ako naraz spustiť niekoľko kontajnerov

Videá pre cvičenie

Motivácia

Zatiaľ vieme spustiť práve jeden kontajner. Bežne sa však vaše riešenie bude skladať z väčšieho množstva kontajnerov. Napríklad v prípade informačných systémov to môžu byť minimálne dva kontajnery: aplikácia informačného systému a databázový systém.

Na dnešnom cvičení vytvoríme kompozíciu pozostávajúcu zo štyroch služieb a vytvoríme tak jednoduchý tok dát, v ktorom najprv vypublikujeme údaje do MQTT brokera, prihlásime sa na ich odber a následne ich vizualizujeme.

Goals

  • zostaviť kompozíciu kontajnerov
  • naučiť sa pracovať so súborom docker-compose.yaml
  • zoznámiť sa s nástrojom Telegraf
  • zoznámiť sa s nástrojom Grafana
  • zoznámiť sa s MQTT brokerom Eclipse Mosquitto

Content

Čítanie údajov zo senzorov

Telegraf: prehľad systému zásuvných modulov (zdroj)

V prvom kroku sa zoznámime s nástrojom Telegraf, pomocou ktorého budeme zbierať dáta zo senzorov. Telegraf je agent pre zbieranie a preposielanie metrík a udalostí z databáz, rozličných systémov a IoT senzorov. V tomto prípade budeme zbierať dáta o aktuálnom zaťažení lokálneho systému (z angl. system load).

Task

V priečinku dnešného cvičenia vytvorte priečinok telegraf-cpu/, v ktorom vytvoríme konfiguračný súbor pre nástroj Telegraf s názvom telegraf.conf.

Obsah konfiguračného súboru bude vyzerať nasledovne:

[agent]
  interval = "1s"
  flush_interval = "1s"

[[inputs.cpu]]
  percpu = false
  totalcpu = true

[[outputs.file]]
  files = ["stdout"]

V rámci konfiguračného súboru je zadefinovaný jeden vstup a jeden výstup. Vstupom je aktuálne zaťaženie systému, ktoré sa bude zapisovať na štandardný výstup každú sekundu.

Task

Spustite kontajner z obrazu telegraf a pripojte k nemu lokálny priečinok telegraf-cpu/ do kontajnera k priečinku /etc/telegraf/:ro.

$ docker container run --rm \
  --name telegraf \
  --volume "$(pwd)/telegraf-cpu/:/etc/telegraf/:ro" \
  telegraf

Task

Upravte konfiguráciu tak, aby sa vo výsledku nachádzala len hodnota položky usage_system.

Na obrazovke sa v sekundových intervaloch budú zobrazovať záznamy, ako napr. tento:

cpu,cpu=cpu-total,host=9c857b52b59d usage_iowait=0.2528445006327,\
usage_softirq=0.37926675094904994,usage_steal=0,usage_guest_nice=0,\
usage_user=7.585335018969501,usage_system=2.4020227559962772,\
usage_idle=88.74841972202594,usage_nice=0,usage_irq=0.6321112515817499,\
usage_guest=0 1665169167000000000

Každý záznam je v tvare tzv. Line protokol-u databázového systému InfluxDB. Každý sa skladá z týchto štyroch častí:

measurementName,tagKey=tagValue fieldKey="fieldValue" 1465839830100400200
--------------- --------------- --------------------- -------------------
       |               |                  |                    |
  Measurement       Tag set           Field set            Timestamp

Ich význam je nasledovný:

  1. názov merania (measurement) - v našom prípade cpu
  2. zoznam značiek (tag set) - v našom prípade sa jedná o kľúče cpu a host
  3. zoznam položiek (field set) - v našom prípade sa jedná o kľúče s prefixom usage_
  4. časová značka (timestamp) - v našom prípade sa jedná o hodnotu 1665169167000000000

To, ako každý záznam bude vyzerať, môžeme upraviť v konfigurácii vstupu alebo výstupu. V našom prípade upravíme konfiguráciu vstupu, ktorá bude vyzerať nasledovne:

[[inputs.cpu]]
  percpu = false
  totalcpu = true

  name_override = "metrics"
  data_format = "influx"
  fieldpass = [
    "usage_system"
  ]
  tag_keys = [
    "cpu"
  ]

Po opätovnom spustení telegrafu s novou konfiguráciou bude výsledný záznam vyzerať takto:

metrics,cpu=cpu-total,host=13eac84cde29 usage_system=1.7654476670812262 1665170033000000000

Kompozícia kontajnerov

Zatiaľ sme spustili len jeden kontajner. Na vytvorenie dnešného scenára ich však potrebujeme spustiť ešte tri. Aby sme každý ďalší kontajner nemuseli spúšťať osobitne z príkazového riadku, vytvoríme konfiguračný súbor docker-compose.yaml, v ktorom zadefinujeme našu kompozíciu.

Task

V koreňovom priečinku cvičenia vytvorte súbor docker-compose.yaml a v ňom vytvorte konfiguráciu pre spustenie Telegraf-u na snímanie aktuálneho zaťaženia systému.

Do konfiguračného súboru docker-compose.yaml prepíšeme príkaz na spustenie kontajnera:

$ docker container run --rm \
  --name telegraf \
  --volume "$(pwd)/telegraf-cpu/:/etc/telegraf/:ro" \
  telegraf

Prepis bude vyzerať nasledovne:

version: "3"

services:
    telegraf-cpu:
        image: telegraf
        volumes:
        - ./telegraf-cpu/:/etc/telegraf/:ro

Task

Overte vytvorený konfiguračný súbor spustením kompozície.

Kompozíciu spustíme príkazom:

$ docker compose up

Ak sme postupovali správne, spustí sa kontajner a na obrazovke uvidíme každú sekundu záznam vo formáte line protokol-u o aktuálnom zaťažení systému.

Task

Ukončite vytvorenú kompozíciu.

Kompozíciu je možné ukončiť spustením nasledovnéhom príkazu z priečinku, v ktorom sa nachádza súbor s konfiguráciou docker-compose.yaml:

$ docker compose down

Vizualizácia údajov

Vizualizovanie dát pomocou aplikácie Grafana

Údaje o aktuálnom zaťažení systému sa zatiaľ vypisujú len na štandardný výstup. V tomto kroku rozšírime našu kompozíciu o populárny nástroj Grafana, ktorý slúži na vizualizáciu údajov.

Task

Rozšírte svoj súbor docker-compose.yaml o nástroj Grafana.

Pre službu nech platí:

  • službu nazvite grafana
  • nástroj Grafana spustite z obrazu grafana/grafana
  • pre službu otvorte port 3000
  • pre službu zabezpečte pomenované úložisko s názvom grafana vedúce do priečinku kontajnera /var/lib/grafana

Konfigurácia pre službu grafana bude vyzerať nasledovne:

grafana:
  image: grafana/grafana
  ports:
  - 3000:3000
  volumes:
  - grafana:/var/lib/grafana

Task

Spustite a overte vytvorenú kompozíciu.

Ak ste postupovali správne, po otvorení prehliadača na adrese http://localhost:3000 sa vám otvorí uvítacia obrazovka webového rozhrania nástroja Grafana.

Grafana: Prihlasovacia obrazovka

Task

Dokončite prvé spustenie prihlásením sa a zmenou hesla.

Prihláste sa do Grafany s používateľským menom admin a heslom admin. Následne si nastavte nové heslo.

Po úspešnom prihlásení uvidíte domovskú obrazovku Grafany.

Grafana: Domovská obrazovka

Task

V systéme Grafana vytvorte API token s rolou Admin.

API token vytvoríte kliknutím na Admin > API Tokens a následne na tlačidlo New API key. Pri vytváraní zadajte kľúča môžete použiť tieto metaúdaje:

  • názov kľúča - system monitoring
  • rola - Admin
  • TTL (Time To Live) - 1d

Kľúč si skopírujte - budeme ho potrebovať na autentifikáciu publikovania údajov do Grafany.

Task

Do konfigurácie Telegraf-u pridajte výstupný modul http, pomocou ktorého budete odosielať zosnímané údaje do aplikácie Grafana.

Do konfiguračného súboru telegraf.conf pridáme túto konfiguráciu:

[[outputs.http]]
  url = "http://grafana:3000/api/live/push/system_load"
  data_format = "influx"
  [outputs.http.headers]
    Authorization = "Bearer <Your API Key>"

Task

Overte upravenú konfiguráciu.

Ak ste postupovali správne, po spustení kompozície uvidíte v logoch nie len záznamy z Telegraf-u, ak ste nevypli výpis na štandardný výstup, ale aj záznamy z aplikácie Grafana o tom, že prijala záznam.

V aplikácii Grafana je však možné aj údaje, ktoré jej posielame naživo, priamo vizualizovať. To je možné vytvorením nového dashboard-u a následne pridaním nového panelu. V ňom následne vyberte:

  • ako zdroj dát vyberte -- Grafana --
  • ako Query type vyberte položku Live Measurements
  • ako Channel vyberte položku stream/system_load/metrics
  • zo zoznamu položiek vyberte usage_system

Aby ste videli údaje naozaj v reálnom čase, nastavte si zobrazenie za posledných 5 minút.

Grafana: živý stream

Vytvorený panel ako aj dashboard si môžete uložiť.

Publikovanie dát cez MQTT

Finálna kompozícia

Komunikačný protokol MQTT je jedným z najpopulárnejších komunikačných protokolov v IoT. A keďže ho budeme pre naše riešenia používať tiež, potrebujeme vlastný MQTT broker, ktorý bude slúžiť na komunikáciu našich zariadení a služieb v našej architektúre. Na tento účel použijeme otvorený MQTT broker Eclipse Mosquitto.

Task

Do kompozície pridajte novú službu s názvom mosquitto, ktorá do kompozície pridá podporu pre komunikačný protokol MQTT.

Pre novú službu mosquitto nech platí:

  • službu spustite z obrazu eclipse-mosquitto
  • služba bude navonok komunikovať na porte 1883
  • pre jej konfiguráciu vytvorte priečinok mosquitto/ a pripojte ho do kontajnera k priečinku /mosquitto/config/

Do lokálneho priečinku mosquitto/ pridajte konfiguráciu v súbore mosquitto.conf:

listener 1883
allow_anonymous true

Výsledná konfigurácia v súbore docker-compose.yaml môže vyzerať nasledovne:

mosquitto:
  image: eclipse-mosquitto
  ports:
  - 1883:1883
  volumes:
  - ./mosquitto:/mosquitto/config

Task

Pridajte do konfigurácie Telegraf-u výstup do MQTT a odstráňte z neho výstup do aplikácie Grafana.

Výsledný konfiguračný súbor bude po úpravách vyzerať takto:

[agent]
  interval = "1s"
  flush_interval = "1s"

[[inputs.cpu]]
  percpu = false
  totalcpu = true

[[outputs.mqtt]]
  servers = [ "mosquitto:1883" ]
  topic_prefix = "kpi/iot1"
  keep_alive = 30

Task

Overte funkčnosť upravenej konfigurácie agenta Telegraf.

Funkčnosť vieme overiť pomocou ľubovoľného MQTT klienta. Kontajner mosquitto má nainštalované nástroje mosquitto_pub a mosquitto_sub a môžeme ich použiť na overenie funkčnosti konfigurácie.

Najprv spustíme príkazový riadok v bežiacom kontajneri/službe v kompozícii:

$ docker compose exec mosquitto sh

V kontajneri sa následne prihlásime na odber všetkých správ z témy kpi/iot1/ príkazom:

$ mosquitto_sub -h mosquitto -t "kpi/iot1/#" -F "%t %p"

Ak je konfigurácia v poriadku, každú sekundu uvidíte na obrazovke výpis údajov z MQTT brokera.

Task

Pridajte do kompozície ďalšieho agenta Telegraf, ktorý tentokrát bude údaje preposielať z MQTT do aplikácie Grafana.

Pre realizáciu tejto úlohy budeme potrebovať vytvoriť samostatnú službu do kompozície so samostatnou konfiguráciou. Službu môžeme nazvať telegraf-mqtt a k nej vytvoríme zodpovedajúci priečinok s kongiruáciou.

Konfiguračný súbor telegraf.conf teda uložíme do nového priečinku telegraf-mqtt/ a bude vyzerať takto:

[agent]
  interval = "1s"
  flush_interval = "1s"

[[inputs.mqtt_consumer]]
  servers = [ "mosquitto:1883" ]
  topics = [
    "kpi/iot1/#"
  ]

[[outputs.http]]
  url = "http://grafana:3000/api/live/push/system_load"
  data_format = "influx"

  [outputs.http.headers]
    Authorization = "Bearer <Your API Key>"

Konfigurácia služby v konfiguračnom súbore docker-compose.yaml bude vyzerať nasledovne:

telegraf-mqtt:
    image: telegraf
    volumes:
    - ./telegraf-mqtt/:/etc/telegraf/:ro

Task

Otestujte vytvorenú kompozíciu.

Ak sú vaše vytvorené zmeny v poriadku, aplikácia Grafana bude aj naďalej zobrazovať aktuálne zaťaženie systému. Tentokrát však bude zaťaženie nebude publikované priamo, ale prostredníctvom komunikačného protokolu MQTT, ktorý sa nachádza medzi zdrojom dát a ich vizualizáciou.

Závislé spúšťanie služieb

V niektorých prípadoch sa vyžaduje, aby sa niektoré služby spúšťali až potom, ako naštartujú iné služby. V našom scenári by sme takto vedeli identifikovať napríklad:

  • najprv je potrebné spustiť MQTT broker a až potom službu, ktorá bude do neho publikovať údaje
  • najprv je potrebné spustiť aplikáciu Grafana a až potom službu, ktorá do nej bude posielať údaje

V opačnom prípade môže dôjsť k pádu služby, ktorá sa neúspešne snaží posielať údaje do nespustenej služby. Tomu vieme zabrániť vhodným použitím elementu depends_on v príslušnej závislej službe.

Task

Aktualizujte vašu kompozíciu tak, aby sa závislé služby spustili až po nezávislých službách.

V našom prípade pôjde o tieto závislosti:

  • služba telegraf-cpu sa môže spustiť až po službe mosquitto
  • služba telegraf-mqtt sa môže spustiť až po službách mosquitto a grafana
  • služba grafana sa môže spustiť až po službe mosquitto

Task

Overte funkčnosť vašej aktualizovanej kompozície.

Ďalšie odkazy