ELK环境部署

Oct 25, 2016


前言

随着互联网的发展,分布式的集群环境越来越多被应用,这同时也带来了另一个问题,在分布式的环境中,各个节点的信息被分散到不同的物理机器上,这导致问题的排查也越来越困难,平时我们跟踪问题使用最多的方式就是查询日志,但是在分布式的环境中,要在成百上千的节点中找出错误日志也是非常困难的,ELK的出现解决了这个问题。

什么是ELK

ELK是Elasticsearch、Logstash、Kibana三个工具的简称:

  • Elasticsearch(ES)是个开源分布式搜索引擎,它的特点有:分布式,零配置,自动发现,索引自动分片,索引副本机制,restful风格接口,多数据源,自动搜索负载等。
  • Logstash是一个完全开源的工具,他可以对你的日志进行收集、分析,并将其存储供以后使用(如,搜索)。
  • Kibana也是一个开源和免费的工具,他Kibana可以为 Logstash 和 ElasticSearch 提供的日志分析友好的 Web 界面,可以帮助您汇总、分析和搜索重要数据日志。

想要了解一个系统,必须想了解系统的架构,我们先来看一下ELK的部署架构:

elk部署图

这个图说明,我们的应用节点把日志数据写入到Logstash之后,Logstash再将日志写入到ES中,然后由Kibana从ES中取出日志数据并进行统计分析,最后展示给用户浏览器。

在这个过程中,Logstash担任日志收集,ES负责存储,Kibana负责展示。

顺便说明一下,在ELK系统中,用来解决了分布式的日志收集存储和分析的问题。实际上ES是可以单独使用的,并且可以用来作为存储和搜索引擎,ES本身也提供了非常强大的rest api和查询语法。

部署ELK

本文使用的是最新的5.0.0-rc1版本,部署在fedora 24 64位操作系统上,下载链接:

现在我们开始部署ELK,从架构图中我们知道,ES是最基础的功能,因此必须先部署ES,ES依赖于JAVA,所以需要想安装jdk,建议使用jdk8或以上的版本,本文使用jdk8。

部署ES

先下载好ES的部署包,然后解压:

[kael@localhost ~]$ tar -xvf elasticsearch-5.0.0-rc1.tar.gz

解压,然后进入文件夹,查看一下文件:

es的文件结构

es的部署十分简单,作为实验性的部署,我们不用改任何配置,直接进入bin目前,启动es即可:

[kael@localhost ~]$ cd bin/
[kael@localhost ~]$ ./elasticsearch

可以看到如下启动日志:

es启动日志

这样就启动完成了,如果要停止的话直接按下ctrl+c即可。

注:这里es有一个启动异常,从错误信息看应该是某个功能在Linux的内核中没有,先不管他,不影响我们部署和查看效果,之后学习在解决这个问题。

es默认监听端口是9200,我们可以重新打开一个终端,输入:

[kael@localhost ~]$ curl http://localhost:9200

可以看到

[kael@localhost ~]$ curl http://localhost:9200
{
  "name" : "VBGdn28",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "1dnn9vtxRpmcnyLqV4vn9g",
  "version" : {
    "number" : "5.0.0-rc1",
    "build_hash" : "13e62e1",
    "build_date" : "2016-10-07T16:52:58.798Z",
    "build_snapshot" : false,
    "lucene_version" : "6.2.0"
  },
  "tagline" : "You Know, for Search"
}

展示了配置的cluster_name和name,以及安装的ES的版本等信息,这说明es已经启动完成。

部署Logstash

接下来我们部署Logstash,同样将部署包下载好,解压:

[kael@localhost Downloads]$ tar -xvf logstash-5.0.0-rc1.tar.gz

进入Logstash的目录:

logstash目录结构

这里我们需要做些配置,首先自己创建一个目录,建议将我们的配置文件放在config目录下:

[kael@localhost logstash-5.0.0-rc1]$ vim config/log4j_to_es.conf

这里我们直接创建log4j_to_es.conf文件,并编辑这个文件,内容如下:

# For detail structure of this file
# Set: https://www.elastic.co/guide/en/logstash/current/configuration-file-structure.html
input {
  # For detail config for log4j as input, 
  # See: https://www.elastic.co/guide/en/logstash/current/plugins-inputs-log4j.html
  log4j {
    mode => "server"
    host => "0.0.0.0" #allow all ip to connect
    port => 4567
  }
}
filter {
  #Only matched data are send to output.
}
output {
  # For detail config for elasticsearch as output, 
  # See: https://www.elastic.co/guide/en/logstash/current/plugins-outputs-elasticsearch.html
  elasticsearch {
    action => "index"          #The operation on ES
    hosts  => "localhost:9200" #ElasticSearch host, can be array.
    index  => "applog"         #The index to write data to.
  }
}

注意,这里配置了input和output两大块,input表示的是logstash收集日志的入口,也表示我们需要收集日志的应用请求的地址,output表示logstash写出的服务器,这里配置成es的地址。

编辑完成之后保存,使用如下命令启动logstash:

[kael@localhost logstash-5.0.0-rc1]$ ./bin/logstash -f config/log4j_to_es.conf 

可以看到如下启动日志:

logstash启动日志

为了测试logstash是否启动成功,我们写一个简单的java程序来测试,使用log4j,因为log4j可以很方便的支持远程写日志。

我们先创建好一个maven的java工程:

java工程结构

然后加入log4j的依赖:

<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

接下来写一个简单的Main函数:

package elk.demo;

import org.apache.log4j.Logger;

/**
 * Created by KAEL on 2016/10/24.
 */
public class Main {
    private static final Logger LOGGER = Logger.getLogger(Main.class);
    public static void main(String[] args) throws Exception {
        for (int i = 0; i < 10; i++) {
            LOGGER.error("Info log [" + i + "].");
            Thread.sleep(500);
        }
    }
}

只是直接通过log4j打10行错误日志而已,但是要把这个结果写入logstash,所以要配置一下log4j:

log4j.rootLogger=INFO,console

# for package com.demo.elk, log would be sent to socket appender.
log4j.logger.com.demo.elk=DEBUG, socket

# appender socket
log4j.appender.socket=org.apache.log4j.net.SocketAppender
log4j.appender.socket.Port=4567
log4j.appender.socket.RemoteHost=localhost
log4j.appender.socket.layout=org.apache.log4j.PatternLayout
log4j.appender.socket.layout.ConversionPattern=%d [%-5p] [%l] %m%n
log4j.appender.socket.ReconnectionDelay=10000

# appender console
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.target=System.out
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d [%-5p] [%l] %m%n

要注意这里的log4j.appender.socket.Portlog4j.appender.socket.RemoteHost需要配置logstash服务的ip和端口,然后我们运行 一下main函数:

写日志

没有报错说明我们日志写入成功,如果出现如下错误:

log4j:ERROR Could not connect to remote log4j server at [localhost]. We will try again later.

可以尝试关闭logstash服务器的防火墙,保证网络联通再试试。

部署Kibana

下载好Kibana的部署包并解压:

[kael@localhost Downloads]$ tar -xvf kibana-5.0.0-rc1-linux-x86_64.tar.gz

进入Kibana的目录:

Kibana目录结构

启动Kibana之前我们需要一些配置,这个配置文件在config/kibana.yml中:

[kael@localhost kibana-5.0.0-rc1-linux-x86_64]$ vim config/kibana.yml

将一下几行的注释去掉:

server.port: 5601
server.host: "localhost"
elasticsearch.url: "http://localhost:9200"
kibana.index: ".kibana"

Kibana配置

注意,这里的server.host最好是kibana所在的服务器ip,这样才能在其他的机器上访问。

修改完成后保存即可。

启动Kibana:

[kael@localhost kibana-5.0.0-rc1-linux-x86_64]$ ./bin/kibana

可以看到如下启动日志:

Kibana启动日志

现在我们可以通过kibana服务器的ip和端口访问kibana了:

Kibana启动日志

到这里我们就把完整的ELK环境部署好了,可以做进一步的学习和开发了。