Changes

Metrics and Monitoring in swarm

25,469 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
Bár erről már beszéltünk, itt most külön kiemelem, hogy mit nevezünk a Prometheus-ban time series-nek. Minden egyes metrika minden címke előfordulási fajtájával külön idősort képez.
 
 
===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.
* '''instance''': Egy job-on belül a példányneve, amit IP:port párossal ír le a Prometheus ha csak nem küld mást magáról a végpont.
 
Pl az alábbi metrikát a cAdvisor egyik konténere küldi. A Prometheus config-ban a job neve "cadivisor" (lást [[Metrics_and_Monitoring_in_swarm#Prometheus_konfigur.C3.A1ci.C3.B3|Prometheus konfig című fejezetet]])
container_cpu_system_seconds_total{id="/",'''instance'''="10.0.0.12:8080",'''job'''="cadvisor"}
 
 
Ezen felül még 4 beépített idősort is automatikusan létrehoz a Prometheus minden egyes végponthoz, tehát minden instance-hoz:
 
up{job="<job-name>", instance="<instance-id>"}
1 if the instance is healthy, i.e. reachable, or 0 if the scrape failed.
 
scrape_duration_seconds{job="<job-name>", instance="<instance-id>"}
Lekérdezés ideje
 
scrape_samples_post_metric_relabeling{job="<job-name>", instance="<instance-id>"}
the number of samples remaining after metric relabeling was applied.
 
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.
 
 
 
{{note|A docker démon is tud magáról metrikákat szolgáltatni, de ez egyenlőre csak kísérleti jelleggel működik ... leírni hogy kell ...}}
==Metrika típusok=, statisztika alapok=
https://www.weave.works/blog/promql-queries-for-the-rest-of-us/
https://prometheus.io/docs/concepts/metric_types/<br>
* pillanat vektor (instant vector)
* tartomány vektor (range vector)
PromQL nyelven kell írni a lekérdezéseket.
===Gauge (ɡeɪdʒ)===
A Gauge (mérő) a legegyszerűbb metrika a Prometheus-ban, ez egy egyszerű mérőszám, aminek fel és le is mehet az értéke, pl memória használat.
===Counter===
A számláló a második legegyszerűbb metrika fajta. Megmutatja, hogy a metrika lekérdezésének a pillanatában hány darabot számoltunk össze abból, amit a metrika jelképez, pl http lekérdezések száma egy webszerverben. A számlálónak csak nőhet az értéke, vagy reset-kor visszavált 0-ra. Persze ennek betartását a Prometheus nem ellenőrzi, számára ugyan olyan név-érték pár a számláló típusú metrika is mint bármelyik másik. Ha a hivatalos Java API-t használjuk az alkalmazásunkban, akkor ez az API biztosítja ennek a betartását. Pl:
<pre>
Na de mit csinál akkor a sum?? a lekérdezéseket majd külön megnézzük
= ==Histogram===
http://linuxczar.net/blog/2017/06/15/prometheus-histogram-2/<br>
https://statistics.laerd.com/statistical-guides/understanding-histograms.php<br>
http://www.leanforum.hu/index.php/szocikkek/167-hisztogram-2<br>
Fontos kifejezések: <br>
''distribution=eloszlás<br>
latency=eltelt idő az input és az output között bármilyen rendszerben <br>
frequency=gyakoriság<br>
cardinality=számosság<br>''
'''===Mi az a Hisztogram:'''===
A Hisztogram a gyakoriság eloszlását mutatja meg a mintának, amivel sokszor sokkal többre lehet menni, mint a hagyományos pl érték-idő diagramokból. A hisztogram egy minta elemzését segítő egyszerű statisztikai eszköz, amely a gyűjtött adatok (minta) alapján következtetések levonására ad lehetőséget. A hisztogram tulajdonképpen egy oszlopdiagram, amely X-tengelyén a tulajdonság osztályok (egy változó különböző értékei), Y-tengelyén pedig az előfordulási gyakoriságok találhatók. A hisztogram megmutatja az eloszlás alakját, középértékét és terjedelmét.
'''===Hisztogram fajták:''' ===
* Normál Hisztogram: Ezt láthattuk a fenti példában. Minden egyes osztályhoz tartozó oszlop azt mutatja meg, hogy a mintából hány darab tartozik az adott osztályba (a példában hány ember tartozik egy adott idősávba)
* Cumulative Histogram: itt az a különbség, hogy egy osztályhoz tatozó oszlop nem csak azt mutatja meg, hogy hány elem tartozik oda a mintából. A Cumulative Histogram-ban minden oszlop az összes előző oszlop összege (összes előző gyakoriság összege) + az adott osztályhoz tartozó gyakoriság
:[[File:ClipCapIt-180812-234346.PNG]]
{{note|A Prometheus cumulative Histogram-ot használ. Állítólag azért mert sokkal kevesebb erőforrásból lehet előállítani a kumulatív hisztogramot mint a simát<br>https://www.robustperception.io/why-are-prometheus-histograms-cumulative}}
 '''Histogram metrikák a Prometheus-ban:''' typically request durations or response sizes ===Apdex index, egy speciális histogram===
http://apdex.org/overview.html<br>
https://en.wikipedia.org/wiki/Apdex<br>
Az Apdex az összes metrikából nyert adatot egyetlen számmá alakítja 0 és 1 között, ahol 0=mindenki elégedetlen, 1=mindenki maximálisan elégedett. Ez a szám a rendszer teljesítmény, más szóval az Apdex értéke (Apdex value)
Az Apdex érték mindig a Target válaszidő függvénye, ami az általunk megállapított, szerintünk optimális válaszideje egy alkalmazásnak: Apdex<supsub>T</supsub> <br>Tehát ha szerintünk egy alkalmazásnak a Target válaszideje 2 másodperc kéne legyen, akkor ezen alkalmazásra kiszámolt Apdex indexet így jelölik: Apdex<supsub>2</supsub> = X<br>Tegyük fel hogy az univerzumunk 3 alkalmazásból áll, amikre a következő Apdex Target számokat határoztuk meg (optimális válaszidők) és a következő Apdex értékek jöttek ki a mérés alapján: * Adatbázis: T=1, Apdex <sub>1</sub> = 0.72* Email rendszer: T=8, Apdex <sub>8</sub> = 0.62* Webshop: T=2, Apdex <sub>2</sub> = 0.53
A begyűjtött válaszidőkből egy speciális hisztogramot csinálunk, három speciális nem egyenlő méretű vödörbe osztjuk az összes válaszidőt(emlékezzünk rá, hogy a histogram definíciója alapján nem kell hogy egyenlőek legyenek a vödrök):
* '''Satisfied''': The user is fully productiveAzon válaszok amik kisebbek, mint a Target válaszidő, vagyis gyorsabban kiszolgáltuk a felhasználókat. This represents the A response time value (0 és T seconds) below which users are not impeded by application response timeközött van.* '''Tolerating''': The user notices performance lagging within responses greater than A válaszidő nagyobb mint T, but continues the processde még az elfogadható határon belül van. A válaszidő T és F (elfogadhatatlan) között van, ahol F mindig 4*T a definíció szerint.* '''Frustrated''': Performance with a response time greater than A válaszidő nagyobb mint F seconds is unacceptable, and users may abandon the processvagyis az elfogadhatatlan kategória. A válaszidők F és végetlen között vannak.
:[[File:ClipCapIt-180904-221625.PNG]]
The Az Apdex formula is the number of satisfied samples plus half of the tolerating samples plus none of the frustrated samplesérték kiszámolásához a histogram értékeit kell összeadni a következő módon: (Satisfied vödör darabszáma + a fele a Tolerating vödör darabszámának, divided by all the samples:és az egész osztva az összes darabbal.
:[[File:ClipCapIt-180904-221645.PNG]]
So it is easy to see how this ratio is always directly related to users' perceptions of satisfactory application responsiveness. To understand the full meaning of the ratioPl ha van 100 mintánk, it is always presented as ahol a decimal value with a sub-script representing the target time T. For exampleTarget idő = 3s, if there are 100 samples with a target time of 3 seconds, where ahol 60 are below 3 secondsválaszidő van 3s alatt, 30 are between darab van 3 and és 12 seconds(4*3) között, and the remaining és a maradék 10 are above van 12 secondsfölött, the akkor az Apdex is:
:[[File:ClipCapIt-180904-221702.PNG]]
  ===Histogram a Prometheus-ban===https://prometheus.io/docs/practices/histograms/<br>https://prometheus.io/docs/concepts/metric_types/<br> A metrikák világában a hisztogramok általában válaszidőből és válasz méretből készülnek. A metrika base neve konvenció szerint megkapja a '''_bucket''' postfix-et. Ezen felül a vödör felső határát pedig az "'''le'''" címke tartalmazza. Mivel a Prometheus kumulatív hisztogramokkal dolgozik, a vödör midig 0-tól az "'''le'''" címkében megadott értékig tartalmazza a minták darabszámot. Az alábbi példában a prometheus_http_request_duration_seconds hisztogram 0-tól 0.4s-ig terjedő vödörhöz metrikáját láthatjuk. <pre> prometheus_http_request_duration_seconds_bucket{le="0.4"}</pre>  Fontos, hogy a Prometheus-ban minden egyes vödör egy külön idősor. A hisztogramot a metrikát szolgáltató rendszerben előre kitalálták, előre rögzítették a vödrök méretét, ez fix, ez az időben nem változik. Pl a fenti '''prometheus_http_request_duration_seconds''' hisztogramban 9 vödröt definiált az alkotó, a legelső 0-tól 0.1-ig terjed, az utolsó meg 0-tól 120s-ig. Tehát az alkotó úgy gondolta, hogy az összes válaszidő 0 és 120 közé fog esni. <br>Minden egyes minta begyűjtéskor a metrikát szolgáltató rendszer elküldi a Prometheus-nak az aktuális, teljes hisztogramot, tehát a hisztogramot a Prometheus készen kapja, nem ő számolja ki. Ebből adódik, hogy minden egyes hisztogram vödör egy külön idősort alkot, hiszen minden egyes lekérdezéskor változhat a hisztogram. Tehát a _bucket-el végződő metrikák egy hisztogram darabkái. A hisztogramot alkotó minták száma időben folyton nő ahogy egyre több request-et szolgál ki a szerver, úgy egyre több mintánk lesz, ebből kifolyólag majdnem minden vödör értéke is nőni fog (kivéve az a vödör, ami olyan kicsi request időt szimbolizál, amibe nem estek bele minták. Mivel a hisztogram kumulatív, az összes ettől nagyobb válaszidőt szimbolizáló vödör értéke nőni fog). Ahogy telik az idő, egyre több válaszidő értéke (mintája) lesz a hisztogramot szolgáltató rendszernek, tehát mindig egyre több mintából állítja elő a hisztogramot, a hisztogram rudacskái minden lekérdezéskor egyre nagyobbak. <br>A példában említett hisztogramot a következő metrikák (vödrök) alkotják: <pre>prometheus_http_request_duration_seconds_bucket{le="0.1"}prometheus_http_request_duration_seconds_bucket{le="0.2"}prometheus_http_request_duration_seconds_bucket{le="0.4"}prometheus_http_request_duration_seconds_bucket{le="1"}prometheus_http_request_duration_seconds_bucket{le="3"}prometheus_http_request_duration_seconds_bucket{le="8"}prometheus_http_request_duration_seconds_bucket{le="20"}prometheus_http_request_duration_seconds_bucket{le="60"}prometheus_http_request_duration_seconds_bucket{le="120"}</pre>  '''Speciális hisztogram metrikák'''<br>A '''_sum''' postfix-re végződő metrikában van az összes minta összege, de nem időben visszamenőleg, hanem az adott metrika begyűjtéskor aktuálisan kapott hisztogram-ban lévő minták összeg. Ezt egyfajta speciális számlálónak is felfoghatjuk, aminek az értéke szintén csak nőni tud, hiszen mindig egyre több mintából állítja elő a hisztogramot a mintákat szolgálató rendszer (pl cAdviser). Egy esetben tud nőni a _sum, ha negatív megfigyelések is lehetségesek, pl hőmérséklet esetén. prometheus_http_request_duration_seconds_sum  A '''_count''' postfix-re végződő hisztogram metrika az összes minta darabszámát adja vissza. A fent leírt okokból ez értelem szerűen csak nőni tud. prometheus_http_request_duration_seconds_count  Kötelezően kell legyen minden hisztogramban egy '''le=+Inf''' elem, aminek az értéke mindig megegyezik a '''_count''' metrikáéval. prometheus_http_request_duration_seconds_bucket{le="+Inf"}   ==Summary(kvantilis)===Na ezt még egyáltalán nem értem. quantiles A p-ed rendű kvantilis az a szám, amelynél az összes előforduló ismérvérték p-ed része nem nagyobb, (1-p)-ed része nem kisebb. Például az x<sub>2/5</sub> kvantilis esetében az adatok 40%-a nem nagyobb, 60%-a nem kisebb a meghatározott kvantilisnél. Meghatározásánál fontos az adatok sorrendbe való rendezése. 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]]
 
:[[File:ClipCapItNem jó az ábra!!! A Grafana a monitor hálózatra is csatlakozik, ott éri el a Prometheus-180821t. Ezen felül az ingress-201901re is, ott érjük el kívülről.PNG]]A Grafana ingress kapcsolatára a portot is rá kell írni, mert az publikálva lett!! 
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ó: Grafana=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
=Vizualizáció: Graphana=
==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 Volume plugins "KVM"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>  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