Changes

Jump to: navigation, search

Metrics and Monitoring in swarm

19,024 bytes added, 10:53, 18 July 2019
Summary (kvantilis)
[[Docker|<< Back to Docker main]]
 
:[[File:ClipCapIt-180919-234053.PNG|280px]]
==Idősorok (time series)==
A TSDB-ben idősorokat tárol el az adatbázis. Miden végpont minden metrikájához tárol egy idősort. Lekérdezéskor elmenti a metrika új értékét a lekérdezési időpontjával együtt Pl az alábbi példában 1 másodpercenként kérdezi le a '''roxy_http_request_total''' értékét:
roxy_http_request_totalproxy_http_request_total
1. 2018.08.19 13:12:01 - 23
2. 2018.08.19 13:12:02 - 23
Fontos, hogy az idősorokat a Prometheus végpontonként tárolja. Ha pl 20 swarm worker-em van, és mind a 20 "beszámol" a '''roxy_http_request_totalproxy_http_request_total''' nevű metrikáról, akkor ezek nem lesznek összemosva egy közös idősorba, hanem húsz különböző idősort (time series) fognak képezni.
NODE1: roxy_http_request_total
1. 2018.08.19 13:12:01 - 23
===Beépített címkékés metrikák===https://prometheus.io/docs/concepts/jobs_instances/<br>
Azt már említettük, hogy a Prometheus nem mossa össze a különböző végpontoktól begyűjtött mintákat, külön-külön idősorban menti el őket. De hogy éri ezt el. Úgy, hogy automatikusan két beépített címkét illeszt minden egyes begyűjtött metrikához:
* '''job''': A Prometheus config-ban konfigurált job neve, ami azonos konténereket fog össze. Pl cAdivsior vagy node-exporter konténerek.
scrape_samples_scraped{job="<job-name>", instance="<instance-id>"}
the number of samples the target exposed.
 
 
<br>
==Honnan jön a metrika==
Metrikát magáról nagyon sok rendszer tud szolgáltatni, pl a ''Traefik'' reverse proxy, vagy ahogy azt majd látni fogjuk, akár a docker daemon is képes metrikákat szolgáltatni saját magáról. Ezen felül nagyon sokféle metrika exporter is elérhető, amik OS szinten is képesek metrikákat szolgáltatni. Általában a metrika lekérdezésére egy http interfészt biztosít a metrikát adó rendszer, amit a '''/metrics''' URL-en lehet elérni. A http interfészek esetében PULL metrika begyűjtésről beszélünk, vagyis a Prometheus (vagy bármelyik másik TSDB) a konfigurációja alapján periodikusan (pár másodpercenként) meghívja a megfelelő URL-t, ahol visszakapja az aktuális metrika listát (név-érték párokat), amit beír az adatbázisba.
Léteik Létezik PUSH alapú metrika gyújtés gyűjtés is.
Tehát továbbra sem a Prometheus szolgáltatja metrikát, a Prometheus csak összegyűjti azt, de a kezünkbe ad egy API-t, amivel a saját rendszerünkbe nagyon könnyen építhetünk metrika szolgáltató interfészt.
 
 
 
==Summary(kvantilis)==
Na ezt még egyáltalán nem értem.
quantiles
https://www.tankonyvtar.hu/hu/tartalom/tamop425/0027_MA3-7/ch01s07.html
 
 
 
 
 
https://povilasv.me/prometheus-tracking-request-duration/
<br>
=Prometheus architektúra=
Ellenben fontos, hogy a Prometheus a '''monitor''' overlay hálózatra is csatlakozzon, hogy közvetlenül el tudja érni a node-okon futó '''node-exporter'''-t és a '''cAdvisor'''-t (emlékezzünk, hogy ezen konténereknek nem nyitottunk portot a host felé, így ezek kizárólag a '''monitor''' overlay hálózaton érhetőek el). A Grafana már csak az '''ingress''' hálózatra kell hogy csatlakozzon, mert csak a Prometheus-ból végez majd lekérdezéseket.
:[[File:ClipCapIt-180926-194910.PNG]]
 
 
 
Nem jó az ábra!!! A Grafana a monitor hálózatra is csatlakozik, ott éri el a Prometheus-t. Ezen felül az ingress-re is, ott érjük el kívülről. A Grafana ingress kapcsolatára a portot is rá kell írni, mert az publikálva lett!!
:[[File:ClipCapIt-180821-201901.PNG]]
Itt leírni, hogy minden egyes node VM en indítani kell egy egy node-exporter-t és cAdvisor-t, és hogy melyik pontosan mit fog csinálni...
"^/(sys|proc|dev|host|etc)($|/)"
</pre>
 
 
<pre>
# docker-machine ssh mg0 docker ps
--collector.filesystem.ignored-mount-points \
"^/(sys|proc|dev|host|etc)($|/)"
</pre>
 
 
Létezik egy módosított változata is a node-exporter-nek, ami képes a swarm node nevét is belerakni a metrika címkéjébe, így nem csak egy IP címet látunk majd a Prometheus-ban/Grafana-ban, ahem egy beszédes node nevet, pl: mg0
<pre>
docker service create --detach=false \
--name node-exporter \
--mode global \
--network monitor \
--mount type=bind,source=/proc,target=/host/proc \
--mount type=bind,source=/sys,target=/host/sys \
--mount type=bind,source=/,target=/rootfs \
--mount type=bind,source=/etc/hostname,target=/etc/host_hostname \
-e HOST_HOSTNAME=/etc/host_hostname \
basi/node-exporter:latest \
--path.procfs /host/proc \
--path.sysfs /host/sys \
--collector.filesystem.ignored-mount-points "^/(sys|proc|dev|host|etc)($|/)" \
--collector.textfile.directory /etc/node-exporter/
</pre>
==Fontos függvények és operátorok=====rate function===A rate függvény megmutatja range vektorokra az egy másodperce jutó változást: rate(<metrika név>[intervallum hossz]) Elsőnek nézzünk egy range vektort: prometheus_http_request_duration_seconds_count{handler="/query",instance="prometheus:9090",job="prometheus"}[10s] Mivel 5 másodpercre állítottuk a Prometheus adatbegyűjtését, ezért 10s-re visszamenve a jelenből, két minta lesz benne: 139 @1536269070.221 141 @1536269075.221 Láthat hogy a 10s ezelőtti begyűjtéskor a request-ek száma 139-volt, de szorgosan kattintgattam az ezt követő 5 másodpercben, ezért a következő begyűjtéskor már 141-volt. Vegyük ennek a range értékét, vagyis nézzük meg, hog 1 másodperce mekkora változás jutott: rate(prometheus_http_request_duration_seconds_count{handler="/query",instance="prometheus:9090",job="prometheus"}[10s]) Az eredmény 0.5 lesz, tehát a 10s hosszú intervallumban 0.5-öt nőt a számláló másodpercenként.  <br>Ha a '''range vektorunk''' selector-a nem csak egy metrikára illeszkedik, akkor a '''rate''' is több eredményt fog visszaadni, minden egyes range vektor találatra egyet.<br>Tegyük fel, hogy van két counter típusú metrikánk (az alap nevük megegyezik, csak a címkében különböznek) example_metric{type="Y"} example_metric{type="X"} Nézzük az alábbi range vektort: example_metric[10s]Ennek az eredménye a következő lesz, ha 5 másodpercenként mintavételezünk: example_metric{type="X"} 1 @1536433370.221 2 @1536433375.221  example_metric{type="Y"} 5 @1536433370.221 10 @1536433375.221 Ha erre alkalmazzuk a '''rate''' függvényt, két eredményt kapunk: rate(example_metric[10s]) {type="X"} 0.1 {type="Y"} 0.5 ===aggregation operators===Egy instant vektor összes találatára kijött metrika összegét mondja meg. Ezek a metrikák csak címkékben különbözhetnek egymástól, mivel a metrika alap nevét (a címke nélküli részt) kötelező tejesen megadni. Az instant vektor-os keresés találatai a keresésben nem megadott címkék értékeiben különbözhetnek csak egymástól.  Pl: ha vannak ilyen metrikáim: prometheus_http_request_duration_seconds_count{handler="...",instance="...",job="..."}Ha az instant vektor keresésekor csak az alapnevet adom meg (prometheus_http_request_duration_seconds_count) akkor az összes címke variánst meg fogom találni: prometheus_http_request_duration_seconds_count{handler="/query",instance="prometheus:9090",job="prometheus"} 1 prometheus_http_request_duration_seconds_count{handler="/graph",instance="prometheus:9090",job="prometheus"} 3 prometheus_http_request_duration_seconds_count{handler="/label/:name/values",instance="prometheus:9090",job="prometheus"} 4 prometheus_http_request_duration_seconds_count{handler="/metrics",instance="prometheus:9090",job="prometheus"} 10619 prometheus_http_request_duration_seconds_count{handler="/query",instance="prometheus:9090",job="prometheus"} 168 prometheus_http_request_duration_seconds_count{handler="/static/*filepath",instance="prometheus:9090",job="prometheus"} 8  De ha pontosítom a keresést a '''handler="/query"''' címével, akkor már csak két elemű lesz a találat: prometheus_http_request_duration_seconds_count{handler="/query",instance="prometheus:9090",job="prometheus"} 1 prometheus_http_request_duration_seconds_count{handler="/query",instance="prometheus:9090",job="prometheus"} 168  Nam most, az összes aggregation operator ezen instant vektor találatokkal csinál valamit, pl a sum(..) ezen találatok értékét adja össze: sum(prometheus_http_request_duration_seconds_count) 10841  Továbbiak: * sum (calculate sum over dimensions)* min (select minimum over dimensions)* max (select maximum over dimensions)* avg (calculate the average over dimensions)* count (count number of elements in the vector)* count_values (count number of elements with the same value)   ===Aggregation operatorsoperation eredmény csoportosítása=== Ha a by vagy a without kulcssavakat az aggregation operátor lekérdezés mögé írunk, és megadunk ott egy címke listát, akkor az eredmény a címke lista lapján lesz csoportosítva. <aggr-op>([parameter,] <vector expression>) [without|by (<label list>)] 
'''by (label list)'''<br>
Ha a by mögé megadunk egy címkét, akkor az aggregation operator elsőként csoportokat fog képezni azokból a mintákból, ahol a címke(ék) megegyeznek, és azokra fogja végrehajtani az aggregálást.
Nézzük az alábbi nagyon egyszerű példát, ahol a metrika alapnév=example_metric:
example_metric{job="A", type="X"} = 1
example_metric{job="A", type="Y"} = 2
example_metric{job="B", type="X"} = 4
example_metric{job="B", type="Y"} = 5
Ekkor a sum by nélküli eredménye:
sum(example_metric)
Element Value
{} 12
De ha hozzáadjuk a by (job)-ot, akkor két választ kapunk, egyet az A sum-ra, egyet a B-sum-ra:
sum(example_metric) by (job)
Element Value
{job="A"} 3
{job="B"} 9
 
 
 
'''without (label list)'''<br>
A without-al pont az ellenkezőjét mondjuk meg, hogy mi szerint ne csoportosítson mielőtt össze adná a csoportok eredményét, tehát minden más szerint csoportosítani fog. A fenti példával ekvivalens eredményt kapunk, ha a '''by (job)''' helyett '''without (type)''' -ot írunk.
sum(example_metric) without (type)
Element Value
{job="A"} 3
{job="B"} 9
 
 
<br>
==Lekérdezés példák==
 Átlag válaszidő az elmúlt 5 percben <br>A http_request_duration_seconds hisztogramnak van egy _sum és egy _count metrikája. Vegyük az összes _sum értéket az elmúlt 5 percben [5], majd vegyük ennek a <pre> rate(http_request_duration_seconds_sum[5m])/ rate(http_request_duration_seconds_count[5m])</pre> =Vizualizáció: GraphanaGrafana=Ugyan a Prometheus-ban tudunk magunk lekérdezéseket írni, és bizonyos keretek között ezt a Prometheus meg is tudja jeleníteni, produkciós környezetben szükségünk van egy vizualizációs eszközre, ami a mi esetünkben a Grafana lesz. Grafana a piacvezető Time Series DB vizualizációs eszköz. Out of the box támogatja az elterjedt TSDB-ket: * Graphite* Elasticsearch* InfluxDB* OpenTSDB* KairosDB* Prometheus  ==Telepítés== ===Volume plugin használata===A konténerek írható rétegét nem szabad írás intenzíven használni, írás intenzív alkalmazásokhoz (mint amilyen a Granafa is) volume-okta kell használni. Ehhez a már ismert '''Netshare''' volume plugin-t fogjuk használni nfs protokollal. Ezen felül a grafana konfigurációs mappáját is át fogjuk helyezni az on-demand volume megosztásra.
A Grafan adatbázis a konténeren belül a '''/var/lib/grafana''' mappában található. Ezt szimplán mount-olni fogjuk az NFS megosztás '''grafana/data''' mappájába. A konfigurációs állomány a '''/etc/grafana''' mappában van. Ezt fogjuk mount-olni az NFS megosztás grafana/config mappájába, de előtte át kell oda másolni az '''/etc/grafana''' mappa tartalmát, ugyan úgy ahogy ezt a Prometheus telepítésénél is tettük. Elsőként feltelepítjük standalone docker konténerként, majd kimásoljuk belőle a konfigurációs mappát:
<pre>
docker run --name grafana \
grafana/grafana:5.2.4
</pre>
<pre>
# docker cp -L grafana:/etc/grafana /home/adam/Projects/DockerCourse/persistentstore/grafana/config/
# cd /home/adam/Projects/DockerCourse/persistentstore/grafana/config/grafana/provisioning/
# mv grafana/ config/
# chmod 777 -R config/
</pre>
docker Volume plugins "KVM"
A használni kívánt datasource-okat (jelen esetben a Prometheus-t) vagy kézzel állítjuk be a Grafana webes konfigurációs felületén, vagy készítünk egy datasource yaml konfigurációs fájlt a '''/etc/grafana/provisioning/datasource''' mappába, így telepítéskor automatikusan létre fogja hozni a Prometheus adatkapcsolatot. grafana/provisioning/datasources/datasource.yaml<syntaxhighlight lang="C++">apiVersion: 1 datasources: - name: Prometheus type: prometheus access: proxy url: http://prometheus:9090</syntaxhighlight> A Grafana is a '''monitor''' nevű overlay hálózathoz fog csatlakozni, így közvetlenül el tudja érni a Promethues konténert. Mivel közös overlay hálózaton vannak, a Docker DNS fel tudja oldani a szolgáltatás nevét a konténer overlay hálózatbeli IP címére ha olyan rendszer indítja a névfeloldást, aki ugyan azon az overlay hálózaton van.    Ugyan így a '''grafana/provisioning/dashboards/''' mappába előre hozzáadhatunk dashboard-okat a Grafana-hoz, ami telepítés után azonnal rendelkezésre fog állni.  <br> ===Service létrehozása=== A Grafana-t ugyan úgy a monitor nevű overlay hálózathoz fogjuk csatlakoztatni. Két volume-ot fogunk felcsatolni a Netshare volume plugin segítségével, egyet a konfigurációnak, egyet pedig az adatbázisnak. Publikáljuk az '''ingress''' hálózatra a 3000-as portot. <pre>docker service create \--detach=false \--name grafana \--network monitor \--mount "type=volume,src=192.168.42.1/home/adam/Projects/DockerCourse/persistentstore/grafana/config/,dst=/etc/grafana,volume-driver=nfs" \--mount "type=volume,src=192.168.42.1/home/adam/Projects/DockerCourse/persistentstore/grafana/data/,dst=/var/lib/grafana,volume-driver=nfs" \-p 3000:3000 \grafana/grafana:5.2.4</pre> <pre># docker service lsID NAME MODE REPLICAS IMAGE PORTS959l8hlvh4u8 grafana replicated 1/1 grafana/grafana:5.2.4 *:3000->3000/tcpcbg79ex3db2g portainer replicated 1/1 portainer/portainer:latest *:9000->9000/tcpdzha5bvpjx67 node-exporter global 4/4 prom/node-exporter:v0.16.0 x035ni7e3qhi prometheus replicated 1/1 prom/prometheus:v2.3.2 *:9090->9090/tcpz60yg7cemg7p cadvisor global 4/4 google/cadvisor:v0.28.5 </pre> ==Login to Grafana== Mindegy is melyik node-ra került föl, az mg0 IP címével nyissuk meg az előbb publikált 3000 portot: <br> http://192.168.123.141:3000/login<br>A default user/password: '''admin/admin''' Miután megadtuk az új jelszót első belépéskor a settings képernyőn landolunk, ahol megjelenik az előre hozzáadott Prometheus data source. :[[File:ClipCapIt-180909-122943.PNG]]  ==Adding dashboards== ===Terhelés a node-okon===Elsőként generáljuk egy kis forgalmat a node-okon, ehhez a '''progrium/stress''' docker konténert fogjuk használni. <br>https://github.com/SvenDowideitprogrium/docker-stress<pre>docker service create \--detach=false \--mode global \--name loadgenerator \progrium/stress --cpu 2 --io 1 --vm 2 --vm-bytes 128M --timeout 30s</pre> A progrium/stress mindig csak 30s-ig fog futni, de ahogy leáll a swarm újra fogja indítani, tehát pár perc után töröljük: <pre># docker service rm loadgenerator</pre> ===CPU idle grafikon===Menjünk a bal oldali "+" jelre, majd "Dashboard" majd Graph (bal felső sarok). Data source-nak válasszuk ki a Prometheus-t, majd adjuk meg a következő lekérdezést: irate(node_cpu_seconds_total{mode="idle"}[5m]) :[[File:ClipCapIt-180910-231059.PNG]] Ezután a Time range fülön adjuk meg hogy 1 óra legyen a felbontás: :[[File:ClipCapIt-180910-231250.PNG]] Ekkor mind a 4 node-ra mutatni fogja, hogy a CPU hány százalékban idle: :[[File:ClipCapIt-180910-231334.PNG]]A jobb felső sarokban lévő save ikonnal mentsük el.   ===Node Exporter Server Metrics===https://grafana.com/dashboards/405 :[[File:ClipCapIt-180910-223918.PNG]]Importálhatunk komplett Dashboard-okat, ami előre van gyártva. A NodeExporter metrikákhoz pl több Dashboard is készült, ilyen pl a '''Node Exporter Server Metrics''', ahol az összes node-ot akár egyszerre is láthatjuk. Az a baj, hogy a Node listában nem csak a Node Exporter-ek vannak, hanem az összes hoszt, aki a '''monitor''' nevű overlay hálózatra csatlakozik. A node exporter-hez ebből a hosszú listából csak 4 IP tartozik  =Swarm stack= Az egész fentebb leírt architektúrát létrehozhatjuk swarm stack-ként egyetlen egy docker compose fájlal.  ===compose fájl=== '''docker-compose.yml'''<syntaxhighlight lang="C++">version: '3'services: cadvisor: image: google/cadvisor:v0.28.5 networks: - monitor volumes: - "/:/rootfs" - "/var/run:/var/run" - "/sys:/sys" - "/var/lib/docker:/var/lib/docker" deploy: mode: global restart_policy: condition: on-failure node-exporter: image: basi/node-exporter:v1.15.0 networks: - monitor volumes: - "/proc:/host/proc" - "/sys:/host/sys" - "/:/rootfs" - "/etc/hostname:/etc/host_hostname" command: - "--path.procfs=/host/proc" - "--path.sysfs=/host/sys" - "--collector.filesystem.ignored-mount-points=^/(sys|proc|dev|host|etc)($$|/)" - "--collector.textfile.directory=/etc/node-exporter/" environment: - HOST_HOSTNAME=/etc/host_hostname deploy: mode: global restart_policy: condition: on-failure prometheus: image: prom/prometheus:v2.3.2 ports: - "9090:9090" networks: - monitor volumes: - "prometheus-conf:/etc/prometheus" - "prometheus-data:/prometheus" grafana: image: grafana/grafana:5.2.4 ports: - "3000:3000" networks: - monitor volumes: - "grafana-conf:/etc/grafana" - "grafana-data:/var/lib/grafana"  networks: monitor: driver: overlay volumes: prometheus-conf: driver: nfs driver_opts: share: 192.168.42.1:/home/adam/Projects/DockerCourse/persistentstore/prometheus/config prometheus-data: driver: nfs driver_opts: share: 192.168.42.1:/home/adam/Projects/DockerCourse/persistentstore/prometheus/data grafana-conf: driver: nfs driver_opts: share: 192.168.42.1:/home/adam/Projects/DockerCourse/persistentstore/grafana/config grafana-data: driver: nfs driver_opts: share: 192.168.42.1:/home/adam/Projects/DockerCourse/persistentstore/grafana/data</syntaxhighlight> Kiemelendők: * A '''Netshare''' NFS volume-okat csak a globális '''volumes''' szekcióban lehet definiálni, mert csak a globális volumes szekciónak van '''driver''' és '''driver_opts''' paramétere. A service definíción belüli '''volumes''' szekciónak nincs. * A Netshare 0.35-ös verziójában bevezették a '''share''' paraméter kezelését. Korábbi verziókat még nem lehetett swarm stack-ben (compose) használni. A globális '''volumes''' szekcióban a volume forrását elvileg nem kell megadni, az a swarm-ra van bízva, hogy hol hozza létre, ezért nincs neki src paramétere. Az egyetlen erre használható paraméter a '''driver_opts''' share paramétere, amit a korábbi verziók még nem tudtak kezelni. (Emlékezzünk vissza, hogy a swarm service definícióban ez nem okoz gondot, mert ott a forrást is meg tudtuk adni)* Mivel a globális '''networks''' szekcióban nem adtuk meg az external paramétert, a '''monitor''' nevű overlay hálózatot minden alkalommal létre fogja hozni a swarm stack telepítése előtt, és le is fogja törölni ha töröljük a stack-et.* A node-exporter command line paramétereibe kötőjelet kell használni, és nem kell dupla macskakörmöt használni a paraméter értékének megadásakor. A "&" jelet még egy "&" jellel kell escape-elni. ===Stack telepítése=== A stack-et az alábbi paranccsal hozhatjuk létre. docker stack deploy --compose-file <yaml fájl név> <stack név>  A megadott stack nevet minden létrehozott szolgáltatáshoz hozza fogja fűzni prefix-ként, ezzel jelezve, hogy azok egy swarm stack részei. Még a monitor nevű overlay hálózat neve elég is oda fogja rakni a stack nevét.   Legyen a stack neve monitor: <pre># docker stack deploy --compose-file docker-compose.yml monitorCreating network monitor_monitorCreating service monitor_prometheusCreating service monitor_cadvisorCreating service monitor_node-exporterCreating service monitor_grafana</pre>  Ezzel létrejött a monitor_monitor nevű overlay hálózatunk, ezen felül 4 swarm service, szintén a monitor prefix-el: <pre># docker network lsNETWORK ID NAME DRIVER SCOPE...nar4kl8o8tat monitor_monitor overlay swarm</pre><pre># docker stack lsNAME SERVICESmonitor 4</pre><pre># docker service lsID NAME MODE REPLICAS IMAGE PORTSfb3poq1m3my0 monitor_cadvisor global 4/4 google/cadvisor:v0.28.5 pidw51mgpc0e monitor_node-exporter global 4/4 basi/node-exporter:v1.15.0 pu4z76b6oijq monitor_grafana replicated 1/1 grafana/grafana:5.2.4 *:3000->3000/tcpterni4ylw5ca monitor_prometheus replicated 1/1 prom/prometheus:v2.3.2 *:9090->9090/tcp</pre>  Keressük meg az egyik node ingress hálózatbeli címét, hogy tesztelni tudjuk a Prometheus és Grafana konzolt: # docker-machine ssh worker0 ifconfig | grep -A 1 eth0 | grep "inet addr" inet addr: '''<span style="color:red">192.168.123.252</span>''' Bcast:192.168.123.255 Mask:255.255.255.0
http://netshare.containx.io/docs/nfs
httpsMost lépjünk be a Prometheus-ba és a Grafana-ba. Mivel mind a kettő az NFS megosztásból szedi a beállításait és az adatbázisát is, már semmilyen beállításra nincs szükség, ezeket már korábban mind elvégeztük. * Grafana: http://netapp-trident192.168.readthedocs123.io252:3000* Prometheus: http:/en/stable-v18192.168.07/docker/install/host_config123.html252:9090

Navigation menu