7,540
edits
Changes
→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:
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.
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 ...}}
https://www.weave.works/blog/promql-queries-for-the-rest-of-us/
https://prometheus.io/docs/concepts/metric_types/<br>
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.
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
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>''
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.
* 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}}
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]]
:[[File:ClipCapIt-180904-221645.PNG]]
:[[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]]
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
==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