Elasticsearch是一個開源搜索引擎,以易用性著稱。kibana是一個圖形界面,可以在上麵條件檢索存儲在ElasticSearch里數據,相當於提供了ES的可視化操作管理器。截圖如下:
這裡基本的架構是這樣的
這裡主要解決的問題是日誌查詢,日誌來源是docker。我們使用docker部署任務時,可以使用docker logs -f <容器id>查看日誌,也可以去/var/lib/docker/containers/<容器id>/<容器id>-json.log查看日誌文件。但是這都很難去做查詢,本文介紹的EFK就可以解決這個問題。
docker logs -f <容器id>
/var/lib/docker/containers/<容器id>/<容器id>-json.log
我們會創建四個容器:
請安裝最新的docker及docker-compose,老版本會有些問題。
這裡是我的版本
? docker version Client: Docker Engine - Community Version: 18.09.2 API version: 1.39 Go version: go1.10.8 Git commit: 6247962 Built: Sun Feb 10 04:12:39 2019 OS/Arch: darwin/amd64 Experimental: false
Server: Docker Engine - Community Engine: Version: 18.09.2 API version: 1.39 (minimum version 1.12) Go version: go1.10.6 Git commit: 6247962 Built: Sun Feb 10 04:13:06 2019 OS/Arch: linux/amd64 Experimental: false ? docker-compose version docker-compose version 1.23.2, build 1110ad01 docker-py version: 3.6.0 CPython version: 3.6.6 OpenSSL version: OpenSSL 1.1.0h 27 Mar 2018
Docker Compose是一個用於定義和運行多容器Docker應用程序的工具。
version: 2 services: web: image: httpd ports: - "1080:80" #避免和默認的80埠衝突 links: - fluentd logging: driver: "fluentd" options: fluentd-address: localhost:24224 tag: httpd.access fluentd: build: ./fluentd volumes: - ./fluentd/conf:/fluentd/etc links: - "elasticsearch" ports: - "24224:24224" - "24224:24224/udp" elasticsearch: image: elasticsearch:5.3.0 expose: - 9200 ports: - "9200:9200" kibana: image: kibana:5.3.0 links: - "elasticsearch" ports: - "5601:5601"
所有web里的日誌會自動發送到fluentd-address: localhost:24224,也就是fluentd容器。
web
fluentd-address: localhost:24224
fluentd
Elasticsearch 和 Kibana並不支持最新的版本,這裡選擇的是5.3.0,如果想要選擇更新的,可以去這裡查看
新建文件fluentd/Dockerfile,使用官方鏡像Fluentd』s official Docker image,安裝需要的插件
fluentd/Dockerfile
# fluentd/Dockerfile FROM fluent/fluentd:v0.12-debian RUN ["gem", "install", "fluent-plugin-elasticsearch", "--no-rdoc", "--no-ri", "--version", "1.9.7"]
然後新建文件fluentd/conf/fluent.conf,編寫Fluentd的配置文件
fluentd/conf/fluent.conf
# fluentd/conf/fluent.conf <source> @type forward port 24224 bind 0.0.0.0 </source> <match *.**> @type copy <store> @type elasticsearch host elasticsearch port 9200 logstash_format true logstash_prefix fluentd logstash_dateformat %Y%m%d include_tag_key true type_name access_log tag_key @log_name flush_interval 1s </store> <store> @type stdout </store> </match>
官方設置文檔config-file
在後台啟動,使用docker-compose up -d
docker-compose up -d
? docker-compose up -d Recreating temp_elasticsearch_1 ... done Recreating temp_kibana_1 ... done Recreating temp_fluentd_1 ... done Recreating temp_web_1 ... done
查看所有容器
? docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 03d589afc2fd httpd "httpd-foreground" About a minute ago Up About a minute 0.0.0.0:1080->80/tcp temp_web_1 e84d0753ee58 kibana:5.3.0 "/docker-entrypoint.…" About a minute ago Up About a minute 0.0.0.0:5601->5601/tcp temp_kibana_1 0f069b8b138f temp_fluentd "tini -- /bin/entryp…" About a minute ago Up About a minute 5140/tcp, 0.0.0.0:24224->24224/tcp, 0.0.0.0:24224->24224/udp temp_fluentd_1 fb4c6255e7ed elasticsearch:5.3.0 "/docker-entrypoint.…" 2 minutes ago Up About a minute 0.0.0.0:9200->9200/tcp, 9300/tcp temp_elasticsearch_1
原文是repeat 10 curl http://localhost:80/,但是我在docker-compose.yml中修改了埠,所以我這裡是
repeat 10 curl http://localhost:80/
? repeat 10 curl http://localhost:1080/ <html><body><h1>It works!</h1></body></html> <html><body><h1>It works!</h1></body></html> <html><body><h1>It works!</h1></body></html> <html><body><h1>It works!</h1></body></html> <html><body><h1>It works!</h1></body></html> <html><body><h1>It works!</h1></body></html> <html><body><h1>It works!</h1></body></html> <html><body><h1>It works!</h1></body></html> <html><body><h1>It works!</h1></body></html> <html><body><h1>It works!</h1></body></html>
打開http://localhost:5601,提示需要先建索引,輸入fluentd-*刷新即可
http://localhost:5601
fluentd-*
去Discover頁面,然後就可以看到之前的日誌了。
Discover
這裡是以docker-compose形式啟動的一個服務,如果還有別的任務需要將日誌發送到fluentd,需要這幾個步驟。
默認情況下,docker-compose會為我們的應用創建一個網路,服務的每個容器都會加入該網路中。這樣,容器就可被該網路中的其他容器訪問,不僅如此,該容器還能以服務名稱作為hostname被其他容器訪問。
所以我們首先需要找到我們現在創建的EFK的網路名,
? docker network ls NETWORK ID NAME DRIVER SCOPE fd428cfa7264 bridge bridge local e08505f7bfe6 docker-compose-efk_default bridge local 650f2f690175 docker-efk_default bridge local 35f17aeb61e9 docker-elk_elk bridge local db29d28aa5cc esnet bridge local 56ea915974c9 host host local 4d0207065fb8 none null local 3dd60d8ddfce temp_default bridge local cf1a06702ae8 web_default bridge local
我是在temp目錄下創建的docker-compose.yml文件,所以這裡默認的名字就是temp_default。
temp_default
再看看之前web的設置
web: image: httpd ports: - "1080:80" #避免和默認的80埠衝突 links: - fluentd logging: driver: "fluentd" options: fluentd-address: localhost:24224 tag: httpd.access
有幾個關鍵設置是:links和logging,link 用於容器直接的互通,logging則是日誌的輸出設置。
那我們這裡再啟動一個新docker需要這些設置
docker run --link temp_fluentd_1 --net temp_default --log-driver=fluentd --log-opt fluentd-address=localhost:24224 --log-opt tag=httpd.access -d hello-world
我們去kibana看看,果然,日誌已經發送到kibana了
將log添加到選擇欄位,日誌閱讀起來更佳
上面說到這裡選擇的是5.3.0,我們試試新版本6.7.1,再看看kibana。使用docker-compose stop停止服務,修改docker-compose文件再啟動。
5.3.0
6.7.1
docker-compose stop
但是已啟動es就掛了,最
後查看日誌docker-compose logs | grep elasticsearch_1,發現如下錯誤:
docker-compose logs | grep elasticsearch_1
"Native controller process has stopped - no new native processes can be started"
最後在giuhub上找到答案:es crashes with "Native controller process has stopped - no new native processes can be started"
解決方法是,提高docker可用內存,mac上是這樣設置,把內存從2G提高到4G,再啟動就成功了。
這裡是6.7.1的界面
最後想要做的就是如何在一台伺服器上搜集所有的日誌,理論上來說,只需要一台伺服器部署上EFK,暴露埠,其他伺服器去發送即可,實際上還沒試過。
如果有好的意見,歡迎來提。