详解安装配置Elastic Stack 6并分析nginx日志

0x01 前言

在写这篇文章的前几个月,Elastic已经发布了6.0版本。这篇文章内的所有内容都是以最新版本为基础进行编写的。

我之前已经写过好多篇关于elasticstack这个技术栈的文章,而今天我将这些文章做一个整合处理,将所有知识点和要点重新梳理,形成一篇elasticstack技术栈的入门文章。

更为详细的使用手册可以参考官方网站的文档:

0x02 准备

安装的过程可以参考以下文章,以便与本篇文章进行互补:

我依旧采用centos7作为底层系统,使用我家中的的镜像作为源地址,如果本地没有可用的源镜像,那么推荐使用清华大学的镜像:

1

https://mirrors.tuna.tsinghua.edu.cn/elasticstack/yum/elastic-6.x/

在/etc/yum.repos.d目录下新建以下文件并写入内容即可:

1

2

3

4

5

6

7

8

9

[root@elk6-t1 ~]# cat /etc/yum.repos.d/elasticsearch-6.x.repo

 

[elasticsearch-6.x]

name=Elasticsearch repository for 6.x packages

baseurl=https://mirrors.tuna.tsinghua.edu.cn/elasticstack/yum/elastic-6.x/

gpgcheck=0

enabled=1

autorefresh=1

type=rpm-md

然后先清理yum缓存再安装jdk与elasticstack套件:

1

[root@elk6-t1 ~]# yum install java-1.8.0-openjdk kibana logstash filebeat elasticsearch

再继续之前先讲解elasticstack的基础知识,首先常用的套件包含以上4个独立的软件,而这些软件都依赖java环境,所以需要安装openjdk。

其中各个软件的功用如下:

  • kibana:一个用户友好的GUI控制界面,可从elasticsearch中读取数据并生成各种酷炫的图表;

  • Beats平台:Beast都是以agent的形式存在系统中并展开监视工作,读取后的数据可以发送至logstash进行处理或发送至elasticsearch进行存储。比较典型的有Packetbeat,、Filebeat、Metricbeat和Winlogbeat:

  • Packetbeat:主要收集数据包的代理;

  • Filebeat:主要收集文本日志的代理;

  • Metricbeat:主要收集系统和软件的性能或其他指标数据的代理;

  • Winlogbeat:主要收集windows系统日志的代理。

  • logstash:一个开源的实时数据处理与收集引擎。

以上软件的工作流程如下图:

以上图片来自elastic官网

从上图可以看出Beast一侧主要工作为收集数据;收集到的数据可以发送至logstash进行分词处理再进行归档存储,也可以直接发送至elasticsearch归档存储;最终用户通过kibana从elasticsearch中搜索数据并进行可视化操作。

安装完成后需要先修改配置文件,官方推荐的配置顺序为elasticsearch–>kibana–>beast。但我更倾向于先配置kibana,然后再配置elasticsearch等。

0x03 kibana

先检查service启动文件:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

[root@elk6-t1 ~]# cat /etc/systemd/system/kibana.service

[Unit]

Description=Kibana

[Service]

Type=simple

User=kibana

Group=kibana

# Load env vars from /etc/default/ and /etc/sysconfig/ if they exist.

# Prefixing the path with '-' makes it try to load, but if the file doesn't

# exist, it continues onward.

EnvironmentFile=-/etc/default/kibana

EnvironmentFile=-/etc/sysconfig/kibana

ExecStart=/usr/share/kibana/bin/kibana "-c /etc/kibana/kibana.yml"

Restart=always

WorkingDirectory=/

 

[Install]

WantedBy=multi-user.target

可以看出可执行文件与配置文件的路径,下面先修改配置文件,请根据实际情况进行修改:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

#默认监听TCP 5601端口,如果有需要,可以改为80或其他端口

server.port: 5601

 

#监听的IP,默认为localhost,我将它改为0.0.0.0,即监听所有IP

server.host: "localhost"

 

#kibana服务器名称,如果有多个kibana节点,建议修改这个参数以便识别

server.name: "your-hostname"

 

#elasticsearch的地址,如果elasticsearch与kibana安装在不同服务器上,需要手动指定地址

elasticsearch.url: "http://localhost:9200"

 

#kibana会在elasticsearch中创建一个索引用于存储kibana的设置,索引名称可以自定义。一般无需修改

kibana.index: ".kibana"

 

#elasticsearch请求超时阈值,如果数据量及其庞大,可适当增加该值

elasticsearch.requestTimeout: 30000

其他参数诸如elasticsearch用户名与密码,这个需要安装x-pack后才需要配置,SSL的配置将在以后文章中详细说明。完成配置后即可启动kibana:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

#立即启动kibana

[root@elk6-t1 ~]# systemctl start kibana.service

 

#将kibana设为开机启动

[root@elk6-t1 ~]# systemctl enable kibana.service

Created symlink from /etc/systemd/system/multi-user.target.wants/kibana.service to /etc/systemd/system/kibana.service.

 

#检查kibana的状态

[root@elk6-t1 ~]# systemctl status kibana.service

kibana.service - Kibana

   Loaded: loaded (/etc/systemd/system/kibana.service; enabled; vendor preset: disabled)

   Active: active (running) since Sun 2018-01-21 19:43:39 CST; 7s ago

Main PID: 4247 (node)

   CGroup: /system.slice/kibana.service

           └─4247 /usr/share/kibana/bin/../node/bin/node --no-warnings /usr/share/kibana/bin/../src/cli -c /etc/kibana/kibana.yml

如果一切正常,那么你将看到以下界面:

因为还没有配置elasticsearch,所以服务状态为Red,同时plugin:elasticsearch@6.1.1存在告警:

1

Unable to connect to Elasticsearch at http://localhost:9200.

这是因为kibana无法连接到elasticsearch,无法读取.kibana这个索引的内容。

0x04 elasticsearch

接下来配置elasticsearch,和kibana一样,elasticsearch的bin目录与配置文件路径分别如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

#elasticsearch配置文件路径

[root@elk6-t1 ~]# ll -alh /etc/elasticsearch/

total 28K

drwxr-s---   2 root elasticsearch   72 Jan 21 14:41 .

drwxr-xr-x. 90 root root          8.0K Jan 21 14:42 ..

-rw-rw----   1 root elasticsearch 2.9K Dec 18 04:24 elasticsearch.yml

-rw-rw----   1 root elasticsearch 2.7K Dec 18 04:24 jvm.options

-rw-rw----   1 root elasticsearch 5.0K Dec 18 04:24 log4j2.properties

 

#elasticsearch可执行文件路径

[root@elk6-t1 ~]# ll -alh /usr/share/elasticsearch/

total 224K

drwxr-xr-x    6 root root  110 Jan 21 14:41 .

drwxr-xr-x. 111 root root 4.0K Jan 21 14:42 ..

drwxr-xr-x    2 root root  135 Jan 21 14:41 bin

drwxr-xr-x    2 root root 4.0K Jan 21 14:41 lib

-rw-r--r--    1 root root  12K Dec 18 04:22 LICENSE.txt

drwxr-xr-x   15 root root 4.0K Jan 21 14:41 modules

-rw-r--r--    1 root root 188K Dec 18 04:24 NOTICE.txt

drwxr-xr-x    2 root root    6 Dec 18 04:24 plugins

-rw-r--r--    1 root root 9.2K Dec 18 04:22 README.textile

elasticsearch配置文件中的内容不多,但绝大部分都需要手动配置:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

#配置集群名称,无论是否计划建立集群,建议配置一个名称

cluster.name: my-application

 

#该elasticsearch节点的名称,如果需要建立集群,该节点名称不可重复!!!

node.name: node-1

 

#elasticsearch数据存储和日志的路径

path.data: /var/lib/elasticsearch

path.logs: /var/log/elasticsearch

 

#监听的IP与端口,默认为127.0.0.1:9200,如果需要监听其他IP,请手动配置。但端口一般保持默认。

network.host: 0.0.0.0

http.port: 9200

 

#默认情况下,elasticsearch会自动搜索同一网络中所有可用的节点,当然,节点配置的集群名称必须相同。

#如果节点存在于不同的网络或网络不可达,那么就需要手动配置以下参数,单机运行则不需要配置。

discovery.zen.ping.unicast.hosts: ["host1", "host2"]

 

#如果启用了集群模式,那么以下参数至关重要。

#主要是为了方式脑裂现象的发生,且必须有一半以上的节点处于可用状态,否则将导致服务崩溃。

#该数值建议的计算公式为:(master_eligible_nodes / 2) + 1

discovery.zen.minimum_master_nodes: 3

 

#设定当多少个节点介入该集群后即开始数据恢复工作

gateway.recover_after_nodes: 2

 

#另外为了方便使用,可以在配置文件最底部加入以下内容,

#允许通过任何途径在elasticsearch中创建索引。

#注意!请勿在生产环境中使用,会有安全问题!

action.auto_create_index: +*

数据存储的路径可以有多个值,理想情况下可以均衡负载。但我在实际使用中发现配置生效的时间必须早于索引建立的时间才有效。

多个数据存储路径的配置格式如下:

1

2

3

4

5

path:

  data:

    - /mnt/elasticsearch_1

    - /mnt/elasticsearch_2

    - /mnt/elasticsearch_3

完成配置后即可通过以下命令启动elasticsearch:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

#立即启动elasticsearch

[root@elk6-t1 ~]# systemctl restart elasticsearch.service

 

#将elasticsearch设为开机启动

[root@elk6-t1 ~]# systemctl enable elasticsearch.service

Created symlink from /etc/systemd/system/multi-user.target.wants/elasticsearch.service to /usr/lib/systemd/system/elasticsearch.service.

 

#检查状态

[root@elk6-t1 ~]# systemctl status elasticsearch.service

elasticsearch.service - Elasticsearch

   Loaded: loaded (/usr/lib/systemd/system/elasticsearch.service; disabled; vendor preset: disabled)

   Active: active (running) since Sun 2018-01-21 20:20:24 CST; 3s ago

     Docs: http://www.elastic.co

Main PID: 4403 (java)

   CGroup: /system.slice/elasticsearch.service

           └─4403 /bin/java -Xms1g -Xmx1g -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly -XX:+AlwaysPreTouch -server -Xss1m -Djava.awt.headless=true -Dfile.encoding=UTF-8 -Djna.nosys=true -XX:-OmitStackTraceInFastThro...

 

Jan 21 20:20:24 elk6-t1 systemd[1]: Started Elasticsearch.

Jan 21 20:20:24 elk6-t1 systemd[1]: Starting Elasticsearch...

如果一切正常,那么刷新kibana后即可看到以下界面:

如果还是提示无法连接elasticsearch,请重新检查kibana的配置文件与elasticsearch服务是否已经启动,必要时可以重启kibana服务。

0x05 logstash

logstash功能非常强大,不仅仅是分析传入的文本,还可以作监控与告警之用。在这里主要讲解分析的配置与使用经验。

logstash的bin目录与配置文件路径都与kibana和elasticsearch类似:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

#logstash配置文件路径

[root@elk6-t1 ~]# ll -alh /etc/logstash/

total 32K

drwxr-xr-x   3 root root  102 Jan 21 14:41 .

drwxr-xr-x. 90 root root 8.0K Jan 21 14:42 ..

drwxrwxr-x   2 root root    6 Dec 18 05:51 conf.d

-rw-r--r--   1 root root 1.7K Dec 18 05:51 jvm.options

-rw-r--r--   1 root root 1.4K Dec 18 05:51 log4j2.properties

-rw-r--r--   1 root root 6.3K Jan 21 14:41 logstash.yml

-rw-r--r--   1 root root 1.7K Dec 18 05:51 startup.options

 

#logstash可执行文件路径

[root@elk6-t1 ~]# ll -alh /usr/share/logstash/

total 76K

drwxr-xr-x   10 logstash logstash 4.0K Jan 21 14:41 .

drwxr-xr-x. 111 root     root     4.0K Jan 21 14:42 ..

drwxr-xr-x    2 logstash logstash 4.0K Jan 21 14:41 bin

-rw-r--r--    1 logstash logstash 2.3K Dec 18 05:51 CONTRIBUTORS

drwxrwxr-x    2 logstash logstash    6 Dec 18 05:51 data

-rw-r--r--    1 logstash logstash 3.8K Dec 18 05:51 Gemfile

-rw-r--r--    1 logstash logstash  21K Dec 18 05:51 Gemfile.lock

drwxr-xr-x    5 logstash logstash   62 Jan 21 14:41 lib

-rw-r--r--    1 logstash logstash  589 Dec 18 05:51 LICENSE

drwxr-xr-x    4 logstash logstash  108 Jan 21 14:41 logstash-core

drwxr-xr-x    3 logstash logstash   55 Jan 21 14:41 logstash-core-plugin-api

drwxr-xr-x    4 logstash logstash   52 Jan 21 14:41 modules

-rw-rw-r--    1 logstash logstash  27K Dec 18 05:51 NOTICE.TXT

drwxr-xr-x    3 logstash logstash   29 Jan 21 14:41 tools

drwxr-xr-x    4 logstash logstash   31 Jan 21 14:41 vendor

logstash的配置文件完全不需要修改:

1

2

3

4

5

6

7

8

#logstash数据存储路径,保持默认即可

path.data: /var/lib/logstash

 

#logstash动态加载的配置文件,所有自定义的输入、输出和过滤配置都放置在这个目录中并以.conf结尾

path.config: /etc/logstash/conf.d/*.conf

 

#logstash日志文件路径,保持默认即可

path.logs: /var/log/logstash

0x05.1 输入配置

在启动之前需要先编写输入、输出和过滤的配置文件,以下是我常用的一些配置文件,不同类型的配置文件可加上数字前缀,以便区分:

1

2

3

4

5

6

7

8

9

10

11

[root@logstash6-node1 ~]# ll /etc/logstash/conf.d/

total 36

-rw-r--r-- 1 root root  121 Dec 11 16:32 00-8014.conf

-rw-r--r-- 1 root root  290 Dec 11 16:32 01-8015.conf

-rw-r--r-- 1 root root   41 Dec 11 16:32 02-8016.conf

-rw-r--r-- 1 root root  169 Dec 11 16:32 03-8017.conf

-rw-r--r-- 1 root root 3336 Dec 11 16:33 10-nginx-fliter.conf

-rw-r--r-- 1 root root  591 Dec 11 16:35 11-cdn-fliter.conf

-rw-r--r-- 1 root root  774 Dec 11 16:35 12-dhcp-fliter.conf

-rw-r--r-- 1 root root  462 Dec 11 16:35 13-snort-fliter.conf

-rw-r--r-- 1 root root 1524 Dec 17 23:12 99-output.conf

如果需要与best通过公网进行通讯,建议使用SSL加密,那么输入的配置文件如下:

1

2

3

4

5

6

7

8

9

10

11

[root@logstash6-node1 ~]# cat /etc/logstash/conf.d/01-8015.conf

input {

  beats {

    port => 8015

    ssl => true

    ssl_certificate_authorities => ["/etc/logstash/elk_server_crt/ca.crt"]

    ssl_certificate => "/etc/logstash/elk_server_crt/server.crt"

    ssl_key => "/etc/logstash/elk_server_crt/server.key"

    ssl_verify_mode => "force_peer"

  }

}

相关的数字证书可自行签发,签发过程可参考以下文章:

如果需要监听514端口,则logstash需要以root用户启动,请手动修改以下文件:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

#修改以下文件

[root@logstash6-node1 ~]# vim /etc/systemd/system/logstash.service

 

#将user与group修改为root即可

[Unit]

Description=logstash

 

[Service]

Type=simple

User=logstash

Group=logstash

# Load env vars from /etc/default/ and /etc/sysconfig/ if they exist.

# Prefixing the path with '-' makes it try to load, but if the file doesn't

# exist, it continues onward.

EnvironmentFile=-/etc/default/logstash

EnvironmentFile=-/etc/sysconfig/logstash

ExecStart=/usr/share/logstash/bin/logstash "--path.settings" "/etc/logstash"

Restart=always

WorkingDirectory=/

Nice=19

LimitNOFILE=16384

 

[Install]

WantedBy=multi-user.target

如果需要监听其他TCP或UDP端口,可以参考以下配置:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

#监听TCP与UDP的8014端口

[root@logstash6-node1 ~]# cat /etc/logstash/conf.d/00-8014.conf

input {

  tcp {

    type => "syslog"

    port => 8014

  }

}

 

input {

  udp {

    type => "syslog"

    port => 8014

  }

}

logstash还支持多种输入方式,具体请参考官方的说明:

0x05.2 输出配置

logstash可以在上层配置一个负载均衡器实现集群,在实际应用中,logstash服务需要处理多种不同类型的日志或数据,处理后的日志或数据需要存放在不同的elasticsearch集群或索引中,那么就需要对日志进行分门别类。

更多相关的信息可以参考官方的文档:

而我的logstash服务节点只有一个,需要处理多达6种不同类型的日志,所以我的输出配置如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

[root@logstash6-node1 ~]# cat /etc/logstash/conf.d/99-output.conf

output {

  if "server_ngx_access_log" in [tags] {

    elasticsearch {

      hosts => ["es6-node1.t.com:9200", "es6-node2.t.com:9200", "es6-node3.t.com:9200"]

      manage_template => false

      index => "public-ngx-alias"

    }

  } else if "tencent_cdn" in [tags] {

    elasticsearch {

      hosts => ["es6-node1.t.com:9200", "es6-node2.t.com:9200", "es6-node3.t.com:9200"]

      manage_template => false

      index => "tencent-cdn-%{+YYYY}"

    }

  } else if "dhcp_log" in [tags] {

    elasticsearch {

      hosts => ["es6-node1.t.com:9200", "es6-node2.t.com:9200", "es6-node3.t.com:9200"]

      manage_template => false

      index => "dhcp_log-%{+YYYY}"

    }

  }  else if "snort_log" in [tags] {

    elasticsearch {

      hosts => ["es6-node1.t.com:9200", "es6-node2.t.com:9200", "es6-node3.t.com:9200"]

      manage_template => false

      index => "snort-alias"

    }

  } else if "modsec_audit_log" in [tags] {

    elasticsearch {

      hosts => ["es6-node1.t.com:9200", "es6-node2.t.com:9200", "es6-node3.t.com:9200"]

      manage_template => false

      index => "modsec_audit_log-%{+YYYY}"

    }

  } else if "win32_log" in [tags] {

    elasticsearch {

      hosts => ["es6-node1.t.com:9200", "es6-node2.t.com:9200", "es6-node3.t.com:9200"]

      manage_template => false

      index => "win32_log-%{+YYYY}"

    }

  } else {

    elasticsearch {

      hosts => ["es6-node1.t.com:9200", "es6-node2.t.com:9200", "es6-node3.t.com:9200"]

      manage_template => false

      index => "log-content-%{+YYYY}"

    }

  }

}

通过在output配置中设定判断语句,将处理后的数据存放到不同的索引中。而这个tags的添加有以下三种途径:

  1. 在filebeat读取数据后,向logstash发送前添加到数据中;

  2. logstash处理日志的时候,向tags标签添加自定义内容;

  3. 在logstash接收传入数据时,向tags标签添加自定义内容。

在这里先说明第3中情况:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

[root@logstash6-node1 ~]# cat /etc/logstash/conf.d/03-8017.conf

input {

  tcp {

    type => "syslog"

    port => 8017

    tags => "win32_log"

  }

}

 

input {

  udp {

    type => "syslog"

    port => 8017

    tags => "win32_log"

  }

}

从上面的输入配置文件中可以看出,在logstash接收到从TCP或UDP 8017端口传入的数据时,随机在tags标签加上自定义的win32_log标签。

这个操作除非在后续处理处理数据的时候手动将其删除,否则将永久存在该数据中。

elasticsearch字段中的各参数的意义如下:

  • hosts:指定elasticsearch地址,如有多个节点可用,可以设为array模式,可实现负载均衡;

  • manage_template:如果该索引没有合适的模板可用,默认情况下将由默认的模板进行管理;

  • index:指定存储数据的索引