Centralized logging in swarm

From berki WIKI
Revision as of 22:27, 14 September 2018 by Adam (talk | contribs) (Kibana)

Jump to: navigation, search


Bevezető

ElasticSearch

https://www.elastic.co/products/elasticsearch
ElasticSearch established itself as one of the best databases for real-time search and analytics. It is distributed, scalable, highly available, and provides a sophisticated API.

Logstash

Áttekintés

https://www.elastic.co/products/logstash
LogStash allows us to centralize data processing. It can be easily extended to custom data formats and offers a lot of plugins that can fulfill almost any need. Finally

Ezt az elastic cég csinálta, ugyan az aki az elasticPath-t.

LogSpout is a log router for Docker containers that runs inside Docker. It attaches to all containers on a host, then routes their logs wherever we want. It also has an extensible module system. It's a mostly stateless log appliance. It's not meant for managing log files or looking at history. It is just a tool to get your logs out to live somewhere else, where they belong.

Hogyan működik a Logstash

https://www.elastic.co/guide/en/logstash/6.4/pipeline.html

Logspout

Telepítés

docker network create --driver overlay elk


ElasticSearch

Az Elastichsearch docker image a https://www.docker.elastic.co/ oldaláról tölthető le

Itt van a telepítési leírás:

https://www.elastic.co/guide/en/elasticsearch/reference/6.4/docker.html

Volume plugin

Ahogy azt már sokszor említettem, a konténerek legfelső, írható rétegét, nem szabad írás intenzíven használni, mivel az ottani overlay2 fájlrendszer nagyon lassan tudja csak kezelni a változásokat, legrosszabb esetben minden image-et végig kell nézzen, ami a konténert alkotja, hogy megtaláljon egy fájlt. Minden írás intenzív műveletet volume-okon kell elvégezni, azok arra lettek kitalálva.

Az ElsaticSearch konténer két mappáját fogjuk a Netshare volume plugin-al felcsatolni az NFS megosztásra. Az egyik az adatbázis mappa, a másik a config mappa, hogy


Elsőként az ElasticSearch image-et fel fogjuk standalone docker konténerként telepíteni hogy kimásoljuk belőle a konfigurációs mappájának a tartalmát, amit az NFS elasticsearch/config mappájába fogunk másolni, hogy ezt majd felcsatoljuk a swarm service alá.

# docker run -d --name elasticsearch \
-p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" \
docker.elastic.co/elasticsearch/elasticsearch:6.4.0

# docker cp -L elasticsearch:/usr/share/elasticsearch/config/ /home/adam/Projects/DockerCourse/persistentstore/elasticsearch/
# chmod 777 /home/adam/Projects/DockerCourse/persistentstore/elasticsearch/config
# mkdir /home/adam/Projects/DockerCourse/persistentstore/elasticsearch/data

# docker rm -f elasticsearch
ImportantIcon.png

Note
Az elasticsearch image elég nagy, 1 Giga körül van, így fontos, hogy legyen elég lemezterület az összes node-on. A base image CentOS 7.5


Telepítés

docker service create \
--detach=false \
--name elasticsearch \
--network elk \
--mount "type=volume,src=192.168.42.1/home/adam/Projects/DockerCourse/persistentstore/elasticsearch/config/\
,dst=/usr/share/elasticsearch/config,volume-driver=nfs" \
--mount "type=volume,src=192.168.42.1/home/adam/Projects/DockerCourse/persistentstore/elasticsearch/data/\
,dst=/usr/share/elasticsearch/data,volume-driver=nfs" \
-e "discovery.type=single-node" \
--reserve-memory 500m \
docker.elastic.co/elasticsearch/elasticsearch:6.4.0
# docker service ps elasticsearch 
ID                  NAME                IMAGE                                                 NODE 
phgs0as5w612        elasticsearch.1     docker.elastic.co/elasticsearch/elasticsearch:6.4.0   mg2 



Logstash

A LogStash image-et is az elastic oldaláról lehet letölteni:
https://www.elastic.co/guide/en/logstash/current/docker-config.html


Logstash konfigurációs fájl

https://www.elastic.co/guide/en/logstash/6.4/configuration.html


/home/adam/Projects/DockerCourse/persistentstore/logstash/logstash.conf

input {
  syslog { port => 51415 }
}

output {
  elasticsearch {
    hosts => ["elasticsearch:9200"]
  }
  # Remove in production
  stdout {
    codec => rubydebug
  }
}

A logstash-t is a elk nevű overlay hálózatra fogjuk kapcsolni. Az overlay hálózatokon egyrészt a konténerek közvetlen elérik egymást, így nincs szükség az ingress hálózatra publikált portokra, másrészt a swarm névfeloldást végez. A szolgáltatás nevére indított DNS lekérdezés visszaadja az összes a szolgáltatáshoz tartozó konténer IP címét a közös overlay hálózaton. Fontos, hogy a lekérdezést olyan konténerből indítsuk, ami ugyan arra az overlay hálózatra csatlakozik mint a keresett szolgáltatás.

Az ElasticSearch a 9200-es porton hallgatózik, amit nem publikáltunk az ingress hálózatra. Viszont a logstash a közös elk overlay hálózaton fel tudja oldani az elasticsearch domain nevet, ami megegyezik a szolgáltatás nevével.


A logstash az 51415-ös porton fogja várni a beérkező logokat, amit majd aztán továbbít a megfelelő alakra hozva a elasticsearch:9200-es címre az ElasticSearch-nek.

Telepítés

docker service create --name logstash \
--detach=false \
--mount "type=volume,src=192.168.42.1/home/adam/Projects/DockerCourse/persistentstore/logstash/config/\
,dst=/conf,volume-driver=nfs" \
--network elk \
--reserve-memory 100m \
-e "LOGSPOUT=ignore" \
docker.elastic.co/logstash/logstash:6.4.0 bin/logstash -f /conf/logstash.conf

A LOGSPOUT=ignore környezeti változóval azt mondjuk meg a logspout-nak, hogy erről a konténerről ne gyűjtse össze a logokat.


# docker service  logs -f logstash
...
[2018-09-12T20:01:26,403][INFO ][logstash.inputs.metrics  ] Monitoring License OK
[2018-09-12T20:01:27,999][INFO ][logstash.agent           ] Successfully started Logstash API endpoint {:port=>9600}

Testing logstash

A logger nevű programmal, mely része a legtöbb Linux disztribúciónak logot írhatunk egy távoli server syslog-jába a lokális socket helyett. A logger-test konténert is a elk nevű overlay hálózatra fogjuk kötni, így közvetlen el fogja tudni érni a logstash-t a 51415-ös porton. Az overlay hálózaton használhatjuk a szolgáltatás nevét mint domain nevet, a logstash domain nevet a swarm fel fogja oldani a logstash konténer IP címére.

docker service create \
--name logger-test \
--network elk \
--restart-condition none \
debian \
logger -n logstash -P 51415 hello world


# docker service logs logstash 
....
{
          "severity" => 0,
          "@version" => "1",
              "tags" => [
        [0] "_grokparsefailure_sysloginput"
    ],
    "severity_label" => "Emergency",
        "@timestamp" => 2018-09-12T20:24:29.085Z,
          "priority" => 0,
    "facility_label" => "kernel",
           "message" => "<13>1 2018-09-12T20:24:29.013823+00:00 a4f8651665ee root - - 
                                     [timeQuality tzKnown=\"1\" isSynced=\"0\"] hello world",
              "host" => "10.0.0.2",
          "facility" => 0
}


# eval $(docker-machine env mg0)
# docker service rm logger-test 



Logspout

https://hub.docker.com/r/gliderlabs/logspout/

ogspout will gather logs from other containers that are started without the -t option and are configured with a logging driver that works with docker logs (journald and json-file).

For now it only captures stdout and stderr, but a module to collect container syslog is planned.

Telepítés

docker service create --name logspout \
--detach=false \
--network elk \
--mode global \
--mount "type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock" \
-e SYSLOG_FORMAT=rfc3164 \
gliderlabs/logspout:v3.2.5 syslog://logstash:51415
# docker service ls
ID                  NAME          MODE       REPLICAS     IMAGE       
e0smhp3tn8ox        logspout      global     4/4          gliderlabs/logspout:v3.2.5 


A log végén meg kell jelenjen az alábbi sor, ami jelzi, hogy a logstash-ez kapcsolódik az 51415-ös porton.

# docker service logs logspout
logspout.0.lh7yq14rapf7@mg2    | #   ADAPTER	ADDRESS		CONTAINERS	SOURCES	OPTIONS
logspout.0.lh7yq14rapf7@mg2    | #   syslog	logstash:51415				map[]
ImportantIcon.png

Note
Ha nincs elég memória szabadon a node-on, akkor a logspout nem fog tudni elindulni.


Tesztelés

A logspout minden egyes node-on ott fut, és bármelyik node-on is keletkezzen log az stdout-on, azt el fogja küldeni a logstash-nek az 51415-ös portra. Mivel mind a ketten az elk nevű overlay hálózatra kapcsolódnak, a logspout közvetlen eléri a logstash-t az bármelyik node-on is legyen. A közös overlay hálózatokon a service nevet domain névként használhatjuk, a swarm DNS szervere visszaadja az összes konténer IP címét, ami a service-hez tartozik. Mivel a logstash-böl csak egy példány fut, így az összes logspout konténer közvetlen el tudja neki küldeni az összegyűjtött logokat.

Úgy fogjuk tesztelni, hogy elsőként elkezdjük figyelni interaktív módban (-f) a logstash log-ját. Majd egy tetszőleges node-on (mindegy melyiken, a logspout minden node-on fut) elindítunk egy ubuntu image-ből álló konténert, ami egy sort fog írni az stdout-ra. Ennek azonnal meg kell jelennie a logstash logjában. Az ubuntu-nak nem is kell swarm service-ként futnia, a logspout mivel a lokális docker démonra csatlakozik, a standalone docker konténerek logját is be tudja gyűjteni.


Indítsuk el a logstash log-nézőt:

# docker service logs -f logstash


Indítsuk el az ubuntu-t standalone docker konténerként, ami az stdout-ra fog írni a konténeren belül. Ezt az logspout-nak észre kell venni, és el kell küldeni a logstash-nek, aki már be tudja tölteni a megfelelő alakban az ElasticSarch-be. Az ubuntu konténer ahogy kiírta az üzenetet az stdout-ra le fog állni, így kapásból törölhetjük is. Fontos, hogy -d kapcsolóval futtassuk az ubuntu konténert, interaktív módban a logspout nem gyűjti be a logokat.

# docker run -d --rm --name ubunto ubuntu echo "hello logspout" > /dev/stdout

A --rm hatására az ubuntu konténer azonnal törölve lesz, ahogy lefutott az echo.


Szinte azonnal meg kell jelenjen a "hello logspout" üzenet a logstash logjában, amit interaktív módban figyelünk:

logstash.1.ggjdb8navgso@mg1    | {
logstash.1.ggjdb8navgso@mg1    |           "@version" => "1",
logstash.1.ggjdb8navgso@mg1    |          "timestamp" => "2018-09-14T20:31:00Z",
logstash.1.ggjdb8navgso@mg1    |            "program" => "ubunto",
logstash.1.ggjdb8navgso@mg1    |           "severity" => 6,
logstash.1.ggjdb8navgso@mg1    |     "facility_label" => "user-level",
logstash.1.ggjdb8navgso@mg1    |                "pid" => "3291",
logstash.1.ggjdb8navgso@mg1    |           "priority" => 14,
logstash.1.ggjdb8navgso@mg1    |         "@timestamp" => 2018-09-14T20:31:00.000Z,
logstash.1.ggjdb8navgso@mg1    |           "facility" => 1,
logstash.1.ggjdb8navgso@mg1    |      "timestamp8601" => "2018-09-14T20:31:00Z",
logstash.1.ggjdb8navgso@mg1    |     "severity_label" => "Informational",
logstash.1.ggjdb8navgso@mg1    |            "message" => "hello logspout\n",
logstash.1.ggjdb8navgso@mg1    |               "host" => "10.0.0.5",
logstash.1.ggjdb8navgso@mg1    |          "logsource" => "836892e1d7fa"
logstash.1.ggjdb8navgso@mg1    | }

Docker logger driver vs logspout

Kibana

https://www.elastic.co/products/kibana
https://www.elastic.co/guide/en/kibana/current/docker.html
Kibana is an analytics and visualization platform with intuitive interface sitting on top of ElasticSearch.


docker service create --name kibana \
--network elk \
-e ELASTICSEARCH_URL=http://elasticsearch:9200 \
--reserve-memory 50m \
--label com.df.notify=true \
--label com.df.distribute=true \
--label com.df.servicePath=/app/kibana,/bundles,/elasticsearch \
--label com.df.port=5601 \
docker.elastic.co/kibana/kibana:6.4.0


version: '2'
services:
  kibana:
    image: docker.elastic.co/kibana/kibana:6.4.0
    environment:
      SERVER_NAME: kibana.example.org
      ELASTICSEARCH_URL: http://elasticsearch.example.org


docker run --name kibana docker.elastic.co/kibana/kibana:6.4.0