Centralized logging in swarm

Revision as of 10:36, 16 September 2018 by Adam (talk | contribs) (Elasticsearch basics)

Revision as of 10:36, 16 September 2018 by Adam (talk | contribs) (Elasticsearch basics)


Contents

Bevezető

ElasticSearch

https://www.elastic.co/products/elasticsearch

Elasticsearch is an open-source, RESTful, distributed search and analytics engine built on Apache Lucene. Since the first version of Elasticsearch was released in 2010, it has quickly become the most popular search engine, and is commonly used for log analytics, full-text search, and operational intelligence use cases.

When coupled with Kibana, a visualization tool, Elasticsearch can be used to provide near-real time analytics using large volumes of log data. Elasticsearch is also popular because of its easy-to-use search APIs which allow you to easily add powerful search capabilities to your applications.

It scales horizontally to handle kajillions of events per second, while automatically managing how indices and queries are distributed across the cluster for oh-so smooth operations


  1. Log Analytics - Analyze un-structured and semi-structured logs generated by websites, mobile devices, servers, sensors, and more for a wide variety of applications such as digital marketing, application monitoring, fraud detection, ad tech, gaming, and IoT. Capture, pre-process, and load log data into Elasticsearch using Logstash, Amazon Kinesis Firehose, or Amazon CloudWatch Logs. You can then search, explore, and visualize the data using Kibana and the Elasticsearch query DSL to gain valuable insights about your users and applications.
  2. Full Text Search - Provide your customers with a rich search and navigation experience. Elasticsearch supports faceting, which allows your customers to narrow their search results by value ranges for fields like price, product characteristics, and brands; ability to create advanced search criteria filters; search-as-you-type suggesters; and near real-time index updates.
  3. Distributed Document Store - Power your application with an easy to use JSON document-oriented storage platform. Elasticsearch provides a simple REST API, fast performance, powerful search capabilities, so you can build highly performant applications that can store and retrieve billions of documents.
  4. Real-time Application Monitoring - Capture activity logs across your customer-facing applications and websites. Use Logstash to push these logs to your Elasticsearch cluster. Elasticsearch indexes the data and makes it available for analysis in near real-time (less than one second). You can then use Kibana to visualize the data and perform operational analyses like identifying outages and problems. With Elasticsearch’s geospatial analysis, you can identify the geographical region where the problem is occurring. Troubleshooting teams can then search the index and perform statistical aggregations to identify root cause and fix issues.

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

Elasticsearch basics

Az Elasticsearch adatbáziskezelő Elasticsearch node-okból épül fel. Mikor elindítunk egy node-ot, akkor az csatlakozni fog a konfigurációjában megadott cluster-hez. Ha a cluster még nem létezik, akkor létre fog hozni a node egy egy-node-os cluster-t. Egy környezetben (pl AWS) több Elasticsearch cluster-t is létrehozhatunk, lényeg, hogy a nevük különbözzön. Az alapértelmezett cluster név: elasticsearch

Tehát egy Elasticsearch adatbáziskezelőn mindig egy Elasticsearch cluster-t értünk.

Index

https://www.elastic.co/blog/what-is-an-elasticsearch-index
Az ElasticSearch-ben az Index megfelel egy adatbázisnak egy relációs adatbázis kezelőben.

  • MySQL => Databases => Tables => Columns/Rows
  • Elasticsearch => Indices => Types => Documents with Properties

Egy Elasticsearch cluster-ben tehát tetszőleges számú Index-et hozhatunk létre (adatbázist), amiben tetszőleges számú Type lehet (tábla). A type-okon belül Document-ek vannak (ezek a sorok), és a Document-nek vannak tulajdonságai, Property (ezek az oszlopok)

  • Index -> Adatbázis
  • Type -> Tábla
  • Document -> Row
  • Properties -> Column

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