Loading

第16章: ELK+K8S

 

 

ELK+K8S

 

 

作者

刘畅

时间

2021-07-26

 

 

环境: CentOS7.5

主机名称

IP

软件

controlnode

172.16.1.120

[48G]

kafka环境[zookeeper-3.7.0kafka_2.13-2.8.0jdk1.8.0_45]

ELK环境[nginxtomcatES-7.13.4ElasticHDlogstash-7.13.4filebeat-7.13.4kibana-7.13.4]

slavenode1

172.16.1.121

[24G]

kafka环境[zookeeper-3.7.0kafka_2.13-2.8.0jdk1.8.0_45]

ELK环境[ES-7.13.4logstash-7.13.4]

slavenode2

172.16.1.122

[24G]

kafka环境[zookeeper-3.7.0kafka_2.13-2.8.0jdk1.8.0_45]

ELK环境[ES-7.13.4]

k8s-admin

172.16.1.70

[24G]

K8S控制端

k8s-node1

172.16.1.71

[48G]

k8s slave01

k8s-node2

172.16.1.72

[48G]

k8s slave02

(1) : 本文档不记录zookeeper+kafkak8s的搭建过程。

(2) ELK官方文档: https://www.elastic.co/guide/index.html

(3) ELK下载地址: https://www.elastic.co/downloads/

(4) elasticsearchlogstash自带jdk环境。

(5) elk属于比较消耗资源的服务,不建议采用docker方式部署,docker主要是简化部署,有助于后面的升级。该文档主要采用二进制方式部署,也可以采用rpm包的方式部署。

(6) 测试文件创建

# touch /tmp/test.log && chmod 777 /tmp/test.log

# touch /tmp/prod.log && chmod 777 /tmp/prod.log

# touch /tmp/unknown.log && chmod 777 /tmp/unknown.log

# touch /tmp/out_result.txt && chmod 777 /tmp/out_result.txt

# touch /tmp/filebeat_out.txt && chmod 777 /tmp/filebeat_out.txt

 

 

 

 

目录

1 ELK介绍 1

1.1 需求背景 1

1.2 ELK介绍 1

1.3 ELK架构 1

2 Elasticsearch集群部署 2

2.1 Elasticsearch介绍 2

2.2 安装 2

2.3 Elasticsearch服务加入systemd 3

2.4 图形页面管理ES 5

3 Logstash部署 8

3.1 Logstash介绍 8

3.2 安装 9

3.3 Logstash服务加入systemd 10

3.4 Logstash标准输入输出 11

3.5 输入插件input(输入阶段,从哪里获取日志) 12

3.5.1 常用插件 12

3.5.2 通用配置字段 12

3.5.3 输入插件file 13

3.5.4 输入插件Beats 15

3.6 过滤插件filter(过滤阶段,将日志格式化处理) 15

3.6.1 常用插件 15

3.6.2 通用配置字段 16

3.6.3 过滤插件json 16

3.6.4 过滤插件kv 17

3.6.5 过滤插件grok 18

3.6.6 过滤插件geoip 22

3.7 输出插件output(将处理完成的日志推送到远程数据库存储) 24

3.7.1 常用插件 24

3.7.2 输出插件elasticsearch 24

3.8 条件判断 26

3.8.1 操作符 26

3.8.2 示例 27

4 Filebeat部署 29

4.1 Filebeat介绍 29

4.2 安装 30

4.3 filebeat服务加入systemd 30

4.4 推送日志到Logstash 31

4.5 推送日志到ES 35

5 收集k8s日志 35

5.1 应用程序日志记录方式 35

5.2 logstash配置文件 36

5.3 标准输出方式采集日志 38

5.4 日志文件方式采集日志 40

6 Kibana部署 41

6.1 Kibana介绍 42

6.2 安装 42

6.3 Kibana服务加入systemd 43

6.4 Kibana基本使用 43

7 架构优化 50

7.1 增加数据缓冲队列 50

7.2 未来架构扩展思路 52

7.3 其它优化点 52

8 Filebeat->Logstash->Kafka->Logstash->ES->Kibana 53

8.1 架构图 53

8.2 配置Filebeat->logstash 53

8.3 配置logstash->kafka 57

8.4 配置kafka->es 58

8.5 kibana可视化展示日志 60

9 知识拾遗 62

9.1 elasticsearch单实例部署 62

9.2 elasticsearch集群设置证书验证 64

9.3 kibanalogstash带密码方式访问elasticsearch 68

9.4 filebeat优化 71

9.5 logstash优化 72

9.6 kibana优化 72

9.7 kibana监控的使用 73

9.8 elasticsearch索引分片及副本的设置 81

 


1 ELK介绍

1.1 需求背景

1 业务发展越来越庞大,服务器越来越多。

2 各种访问日志、应用日志、错误日志量越来越多。

3 开发人员排查问题,需要到服务器上查日志,效率低、权限不好控制。

4 运维需实时关注业务访问情况。

1.2 ELK介绍

1 ELK是三个开源软件的缩写,提供一套完整的企业级日志平台解决方案。

 

2 ELK分别是

(1) Elasticsearch # 搜索、分析和存储数据。

(2) Logstash # 采集日志、格式化、过滤,最后将数据推送到Elasticsearch存储。

(3) Kibana # 数据可视化。

 

3 Beats

# 集合了多种单一用途数据采集器,用于实现从边缘机器向LogstashElasticsearch发送数据。是应用最多的,是一个轻量级日志采集器。

1.3 ELK架构

wps1 

2 Elasticsearch集群部署

172.16.1.120121122节点上操作

2.1 Elasticsearch介绍

1 Elasticsearch(简称ES)是一个分布式、RESTful风格的搜索和数据分析引擎,用于集中存储日志数据。

 

2 Elasticsearch术语

(1) Index # 索引是多个文档的集合。

(2) Document  # Index里每条记录称为Document,若干文档构建一个Index

(3) Type # 一个Index可以定义一种或多种类型,将Document逻辑分组。

(4) Field # ES存储的最小单元。

 

3 ES与关系型数据库术语对比

Elasticsearch

关系型数据库

Index

Database

Type

Table

Document

Row

Filed

Colume

2.2 安装

1 下载二进制包

https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.13.4-linux-x86_64.tar.gz

 

2 修改配置文件

# tar -xzf elasticsearch-7.13.4-linux-x86_64.tar.gz

# mv elasticsearch-7.13.4/ /usr/local/elasticsearch/

# mkdir -p /usr/local/elasticsearch/logs

# mkdir -p /usr/local/elasticsearch/data

# useradd -M -s /sbin/nologin elasticsearch

# id elasticsearch

uid=1002(elasticsearch) gid=1002(elasticsearch) groups=1002(elasticsearch)

# chown -R elasticsearch.elasticsearch /usr/local/elasticsearch/

 

# grep "^[a-Z]" /usr/local/elasticsearch/config/elasticsearch.yml

cluster.name: elk-cluster

# 集群名称

node.name: es01

# 集群节点名称,172.16.1.120节点为es01172.16.1.121节点为es02172.16.1.122节点为es03

path.data: /usr/local/elasticsearch/data

# 数据目录

path.logs: /usr/local/elasticsearch/logs

# 日志目录

bootstrap.memory_lock: true

# 锁定物理内存地址,防止es内存和swap进行交换

network.host: 172.16.1.120

# 监听地址,三个节点分别为172.16.1.120172.16.1.121172.16.1.122

http.port: 9200

# 监听地址端口

transport.tcp.port: 9300

# 集群内部节点之间通信端口

discovery.seed_hosts: ["172.16.1.120", "172.16.1.121", "172.16.1.122"]

# 集群节点列表

cluster.initial_master_nodes: ["172.16.1.120", "172.16.1.121", "172.16.1.122"]

# 首次启动指定的Master节点,这里指定所有node节点,会自动选举

http.cors.enabled: true

http.cors.allow-origin: "*"

# 开启elasticsearch跨域访问功能

2.3 Elasticsearch服务加入systemd

1 调整进程最大打开文件数数量

# ulimit -SHn 65535

# cat >> /etc/security/limits.conf << EOF

    * soft nofile 65535

    * hard nofile 65535

EOF

 

2 调整进程最大虚拟内存区域数量

# echo "vm.max_map_count=262144" >> /etc/sysctl.conf

# sysctl -p

 

3 jvm堆大小设置为大约可用内存的一半

# vim /usr/local/elasticsearch/config/jvm.options

-Xms512m

-Xmx512m

 

4 elasticsearch.service文件

# vim /usr/lib/systemd/system/elasticsearch.service

[Unit]

Description=elasticsearch server

Requires=network.target

After=network.target

[Service]

# 不限制内存大小

LimitMEMLOCK=infinity

# 指定此进程可以打开的最大文件描述符

LimitNOFILE=65535

# 指定最大进程数

LimitNPROC=4096

# 不限制虚拟内存大小

LimitAS=infinity

# 不限制最大文件大小

LimitFSIZE=infinity

# JVM接收到SIGTERM信号时,它将退出,并返回代码143

SuccessExitStatus=143

Type=simple

Environment=JAVA_HOME=/usr/local/elasticsearch/jdk

ExecStart=/usr/local/elasticsearch/bin/elasticsearch

ExecReload=/bin/kill -HUP $MAINPID

KillMode=process

Restart=on-failure

User=elasticsearch

Group=elasticsearch

[Install]

WantedBy=multi-user.target

 

5 启动服务

# systemctl daemon-reload

# systemctl start elasticsearch.service

# systemctl enable elasticsearch.service

 

6 查看集群信息

(1) 查看端口信息

# netstat -tunlp

tcp6       0      0 172.16.1.120:9200       :::*                    LISTEN      3177/java

tcp6       0      0 172.16.1.120:9300       :::*                    LISTEN      3177/java

 

(2) 查看集群状态

1) 查看集群节点信息

[root@controlnode tools]# curl -XGET 'http://172.16.1.120:9200/_cat/nodes?pretty'

172.16.1.120 54 35 2 0.02 0.25 0.24 cdfhilmrstw * es01

172.16.1.121 17 96 5 0.05 0.59 0.51 cdfhilmrstw - es02

172.16.1.122 24 97 5 0.07 0.56 0.49 cdfhilmrstw - es03

 

2) 查询集群健康状态

[root@controlnode tools]# curl -i -XGET http://172.16.1.120:9200/_cluster/health?pretty

wps2 

 

3) 查看指定es节点基本信息

[root@controlnode ~]# curl -XGET '172.16.1.120:9200/?pretty'

wps3 

2.4 图形页面管理ES

172.16.1.120节点上操作

1 下载

推荐插件: ElasticHDcerebroelasticsearch-head,这里使用ElasticHD

https://github.com/360EntSecGroup-Skylar/ElasticHD/releases/download/1.4/elasticHD_linux_amd64.zip

 

2 启动

# unzip -q elasticHD_linux_amd64.zip

# mv ElasticHD /usr/bin/

# nohup ElasticHD -p 172.16.1.120:9800 >/dev/null 2>&1 &

# chmod +x /etc/rc.d/rc.local

# cat >>/etc/rc.local<< EOF

source /etc/profile

nohup ElasticHD -p 172.16.1.120:9800 >/dev/null 2>&1 &

EOF

 

3 访问

URL: http://172.16.1.120:9800/

wps4 

 

4 补充: cerebro的使用

(1) 下载

https://github.com/lmenezes/cerebro/releases/download/v0.9.4/cerebro-0.9.4.zip

 

(2) 安装

# unzip -q cerebro-0.9.4.zip

# mv cerebro-0.9.4/ /usr/local/cerebro/

 

(3) 启动

# nohup /usr/local/cerebro/bin/cerebro -Dhttp.port=9000 >/dev/null 2>&1 &

# chmod +x /etc/rc.d/rc.local

# cat >>/etc/rc.local<< EOF

source /etc/profile

nohup /usr/local/cerebro/bin/cerebro -Dhttp.port=9000 >/dev/null 2>&1 &

EOF

 

# netstat -tunlp | grep 9000

tcp6       0      0 :::9000                 :::*                    LISTEN      2553/java 

 

(4) 访问

URI: http://172.16.1.120:9000

wps5 

概要信息:

wps6 

3 Logstash部署

172.16.1.120节点上操作

3.1 Logstash介绍

Logstash能够将采集日志、格式化、过滤,最后将数据推送到Elasticsearch存储

Logstash不只是一个input|filter|output的数据流,而是一个input|decode|filter|encode|output的数据流。codec就是用来decodeencode 事件的。所以codec常用在inputoutput中,常用的codec插件有plainjsonmultiline等。

服务名

logstash input默认解码方式

logstash output默认编码方式

redis

json

json

kafka

plain

plain

file

plain

json_lines

beats

plain

不支持

tcp

line

json

elasticsearch

json

-

rabbitmq

json

json

stdin

line

不支持

stdout

不支持

rubydebug

(1) json

1) 此编解码器可用于解码(通过输入)和编码(通过输出)完整的JSON消息。如果发送的数据是其根处的JSON 数组,则将创建多个事件(每个元素一个)。如果您正在流式传输由"\n"分隔的JSON消息,请参阅"json_lines"编解码器。

2) 编码将产生一个紧凑的JSON表示(没有行终止符或缩进),如果此编解码器从无效JSON的输入中收到有效负载,则它将回退到纯文本并添加标签"_jsonparsefailure"JSON失败时,有效负载将存储在该message字段中。

3) "charset"默认值为"UTF-8"

4) 解码和编码都是jsonjson数据不添加任何内容。

(2) plain

1) "plain"编解码器用于纯文本,事件之间没有分隔。这主要用于在其传输协议中已经定义了框架的输入和输出(例如zeromqrabbitmqredis等)

2) "charset"默认值为"UTF-8"

(3) json_lines

1) 此编解码器将解码以换行符分隔的流式JSON。编码将发出一个以"@delimiter"注释结尾的JSON字符串如果您的源输入是面向行的JSON,例如redis或文件输入,请不要使用此编解码器。而是使用json编解码器。

2) 此编解码器期望接收换行符终止行的流(字符串)。文件输入将产生一个没有换行符的行串。因此,此编解码器不能与面向行的输入一起使用。

3) "charset"默认值为"UTF-8"

4) "delimiter"默认值为 "\n"

(4) line

1) 面向行的文本数据。

2) 解码行为:只会发出整行事件。

3) 编码行为:每个事件都将与尾随换行符一起发出。

4) "charset"默认值为"UTF-8"

4) "delimiter"默认值为 "\n"

(5) rubydebug

rubydebug编解码器将使用 Ruby Amazing Print 库输出您的 Logstash 事件数据。

 

wps7 

(1) Input 输入,输入数据可以是StdinFileTCPRedisSyslog等。

(2) Filter 过滤,将日志格式化。有丰富的过滤插件:Grok正则捕获、Date时间处理、Json编解码

Mutate数据修改等。

(3) Output:输出,输出目标可以是StdoutFileTCPRedisES等。

3.2 安装

1 下载二进制软件包

https://artifacts.elastic.co/downloads/logstash/logstash-7.13.4-linux-x86_64.tar.gz

 

2 修改配置文件

# tar -xzf logstash-7.13.4-linux-x86_64.tar.gz

# mv logstash-7.13.4/ /usr/local/logstash/

# useradd -M -s /sbin/nologin logstash

# id logstash

uid=1003(logstash) gid=1003(logstash) groups=1003(logstash)

# mkdir -p /usr/local/logstash/conf.d/

# mkdir -p /usr/local/logstash/logs/

# chown -R logstash.logstash /usr/local/logstash/

 

# egrep -v "^$|^#" /usr/local/logstash/config/logstash.yml

pipeline:

  batch:

    size: 125

delay: 5

# 管道配置

pipeline.ordered: auto

path.config: /usr/local/logstash/conf.d

# 自定义inputoutput流处理文件路径

config.reload.automatic: false

# 关闭定期检查配置是否修改,并重新加载管道(我们使用SIGHUP信号手动触发)

config.reload.interval: 3s

# 检查配置是否修改的时间间隔。

http.enabled: true

# 开启http API

http.host: 172.16.1.120

# 监听的IP

http.port: 9600-9700

# 监听的端口

log.level: info

# 日志级别

path.logs: /usr/local/logstash/logs

# 日志路径

 

补充:

logstash默认数据存储目录为: "path.data: LOGSTASH_HOME/data"

3.3 Logstash服务加入systemd

1 logstash.service配置文件

# vim /usr/lib/systemd/system/logstash.service

[Unit]

Description=logstash server

After=network.target

[Service]

SuccessExitStatus=143

Type=simple

Environment=JAVA_HOME=/usr/local/logstash/jdk

ExecStart=/usr/local/logstash/bin/logstash

ExecReload=/bin/kill -HUP $MAINPID

KillMode=process

Restart=on-failure

User=logstash

Group=logstash

[Install]

WantedBy=multi-user.target

 

2 启动服务

# systemctl daemon-reload

# systemctl start logstash.service

# systemctl enable logstash.service

 

注意:

上面启动了logstash服务,但由于logstash服务进程没有可处理的数据,过一会logstash服务会自动停止运行,所以看不到logstash9600端口号。

3.4 Logstash标准输入输出

1 编写配置文件

# cat /usr/local/logstash/conf.d/input_stdin-output_stdout.conf

input{

  stdin{}

}

 

output{

  stdout{

    codec=>rubydebug

  }

}

 

2 验证配置文件是否有语法错误

# /usr/local/logstash/bin/logstash -f /usr/local/logstash/conf.d/input_stdin-output_stdout.conf -t

wps8 

 

3 从配置文件启动logstash

# /usr/local/logstash/bin/logstash -f /usr/local/logstash/conf.d/input_stdin-output_stdout.conf

wps9 

说明:

message # 输入的信息

默认给日志加了如下三个字段:

(1) "@timestamp" # 标记事件发生的时间点,写入es时索引用到的" %{+YYYY.MM.dd} "变量就来自这里。

(2) "host" # 标记事件发生的主机

(3) "@version"

 

4 查看logstash节点基本信息

# curl -XGET '172.16.1.120:9600/?pretty'

wps10 

 

5 logstash命令行参数说明

(1) -f

# 指定配置文件在shell终端启动logstash

logstash -f <file_name>.conf

(2) -t

# 验证配置文件是否有语法错误

logstash -f <file_name>.conf -t

(3) -e

# shell终端启动配置的logstash

logstash -e 'input{stdin{}}output{stdout{codec=>rubydebug}}'

注意:

使用该方式启动logstash,需要先注释掉"/usr/local/logstash/config/logstash.yml"配置文件中的

"path.config:"参数,否则会报如下错误。

ERROR: Settings 'path.config' (-f) and 'config.string' (-e) can't be used simultaneously.

3.5 输入插件input(输入阶段,从哪里获取日志)

3.5.1 常用插件

1 stdin # 一般用于调试

2 File

3 Redis

4 beats # 列如filebeat

3.5.2 通用配置字段

1 add_field # 添加一个字段到一个事件,放到事件顶部,一般标记日志来源。例如属于哪个项目,哪个应用。值类型是hash

add_field => {

  "project" => "microservice"

  "app" => "product"

}

2 tags # 添加任意数量的标签,用于标记日志的其它属性。例如表名是访问日志还是错误日志。

值类型是arraytags => ["web","nginx"]

3 type # 为所有输入添加一个字段,例如表明日志的类型。

值类型是stringtype => "access"

3.5.3 输入插件file

file插件用于读取指定日志的文件。

 

1 常用字段

(1) path # 日志文件路径,可以使用通配符。

值类型是arraypath => ["/tmp/test.log","/tmp/test1.log"]

(2) exclude # 排除采集的日志文件。

(3) discover_interval # 多久检查被监听的目录下是否有新文件,默认15s

(4) sincedb_write_interval # 多久写一次sincedb文件,默认15s

(5) stat_interval # 多久检查被监听文件的状态默认1s

(6) start_position # 指定日志文件从什么位置开始读,默认从结尾开始,一般仅在初次读取文件时起作用,如果文件已被记录在sincedb中,则根据pos

 

注意:

(1) logstash默认从日志文件的末尾开始读取,指定beginning表示从头开始读日志文件,但这也仅限于第一次读取文件时有效,读取完成后会记录日志的位置(.sincedb_xxxx),下次从记录的位置开始读。如果日志被清理导致实际位置点比记录的位置点小,那么logstash会从头开始读取日志。如果想要所有收集的日志文件都从开头读取,先stop logstash,然后删除logstash数据目录下的所有数据,再启动logstash即可(rm -rf /usr/local/logstash/data/*)

(2) logstash收集日志配置文件中设置如下内容,可以实现读取的目标文件未经修改,而仅修改了conf文件,实现每次重新运行logstash都从文件头开始收集日志。如果日志收集完成,重启logstash不想再从头收集日志,把添加的配置去掉,实现重启logstash后从日志末尾开始收集日志。

input {

  file {

    path => ["/tmp/test.log"]

    start_position => "beginning"

    sincedb_path => "/dev/null"

  }

}

 

2 示例: 读取日志文件并输出到文件

(1) 配置文件

# cat /usr/local/logstash/conf.d/input_file-output_file.conf

input {

  file {

    path => "/tmp/test.log"

    exclude => "error.log"

    start_position => "beginning"

    tags => "web"

    tags => "nginx"

    type => "access"

    add_field => {

      "project" => "microservice"

      "app" => "product"

    }

  }

}

 

output {

  file {

    path => "/tmp/out_result.txt"

  }

}

 

(2) 检查配置文件

/usr/local/logstash/bin/logstash -f /usr/local/logstash/conf.d/input_file-out_file.conf -t

……

Configuration OK

……

 

(3) 重启logstash

# systemctl status logstash.service

wps11 

# kill -HUP 3386

查看logstash日志,确定logstash已经重新启动

# tailf /usr/local/logstash/logs/logstash-plain.log

 

(4) 测试

# echo "input_file-test" >>/tmp/test.log

通过/tmp/out_result.txt文件找到输出日志,通过在线json效验网站将输出内容进行格式化。

https://www.bejson.com/

wps12 

 

(5) 说明

下面的相关测试按照此方式进行,但会省略一些重复的步骤,只贴出配置文件和输出结果。

3.5.4 输入插件Beats

Beats插件接收来自Beats数据采集器发来的数据,例如Filebeat

常用字段: host—监听地址,port—监听端口。

 

用法:

# vim input_beats-output_file.conf

input {

  beats {

    host => "0.0.0.0"

    port => 5044

  }

}

 

filter {

}

 

output {

  file {

    path => "/tmp/out_result.txt"

  }

}

3.6 过滤插件filter(过滤阶段,将日志格式化处理)

3.6.1 常用插件

jsonkvgrokgeoipdate

3.6.2 通用配置字段

1 add_field # 如果过滤成功,添加一个字段到这个事件。

2 add_tags # 如果过滤成功,添加任意数量的标签到这个事件。

3 remove_field # 如果过滤成功,从这个事件移除任意字段。

4 remove_tag # 如果过滤成功,从这个事件移除任意标签。

3.6.3 过滤插件json

1 说明

JSON插件接收一个json数据,将其展开为Logstash事件中的数据结构,放到事件的顶层。

 

2 常用字段

(1) source # 值类型为string,指定要解析的字段,一般是原始消息message字段。

(2) targe t # 值类型为string,将解析的结果放到指定字段,如果不指定,默认在事件的顶层。如果该target字段已经存在,它将被覆盖。

(3) remove_field  # 值类型为array,如果此过滤器成功,则从此事件中删除任意字段。

 

3 示例: 解析HHTP请求日志

(1) 配置文件

# cat /usr/local/logstash/conf.d/filter_json-output_file.conf

input {

  file {

    path => "/tmp/test.log"

    start_position => "beginning"

  }

}

 

filter {

  json {

    source => "message"

  }

}

 

output {

  file {

    path => "/tmp/out_result.txt"

  }

}

 

(2) 收集的日志

echo '{"remote_addr":"223.5.5.5","url":"/index.html","status":"200"}' >>/tmp/test.log

 

wps13 

3.6.4 过滤插件kv

1 说明

kv插件接收一个键值数据,按照指定分割符解析为logstash事件中的数据结构,放到事件顶层。

 

2 常用字段

field_split # 指定键值分隔符,默认是空

 

3 示例: 解析URL中的参数

(1) 配置文件

# cat /usr/local/logstash/conf.d/filter_kv-output_file.conf

input {

  file {

    path => "/tmp/test.log"

    start_position => "beginning"

  }

}

 

filter {

  kv {

    field_split => "?&"

  }

}

 

output {

  file {

    path => "/tmp/out_result.txt"

  }

}

 

(2) 收集日志

echo 'www.baidu.com?id=19&name=cctv1&content=show' >>/tmp/test.log

wps14 

3.6.5 过滤插件grok

1 说明

(1) 如果采集的日志格式是非结构化的,可以写正则表达式提取,grok是正则表达式支持的实现。

 

(2) Logstash内置的正则匹配模式,在安装目录下可以看到,路径如下:

vendor/bundle/jruby/2.5.0/gems/logstash-patterns-core-4.3.1/patterns/legacy/grok-patterns

 

(3) 正则匹配模式语法格式

%{SYNTAX:SEMANTIC}

1) SYNTAX # 模式名称,模式文件中的第一列

2) SEMANTIC # 匹配文件的字段名

例如: %{IP:client}

 

(4) 正则符号说明

wps15 

 

2 常用字段

1) match # 正则匹配模式

2) patterns_dir # 自定义正则模式文件

 

3 示例

(1) 使用内置正则匹配http请求日志

1) 模拟数据

223.5.5.5 GET /index.html 55632 0.013

2) 正则

%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration}

3) kibana上验证

wps16 

 

(2) 自定义正则匹配http请求日志

1) 自定义匹配规则

CID [0-9]{5,6}

TAG \w+

2) 自定义匹配日志示例1

223.5.5.5 GET /index.html 55632 0.013 123456

%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration} %{CID:cid}

3) 自定义匹配日志示例2

223.5.5.5 GET /index.html 55632 0.013 123456 abcdef

%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration} %{CID:cid} %{TAG:tag}

 

(3) logstash中匹配多格式日志

如果一个日志文件下有多个日志格式怎么办,例如项目新版本添加一个日志字段,需要兼容旧日志匹配使用多模式匹配,写多个正则表达式,只要满足其中一条就能匹配成功。 

注意:

logstash多模式匹配时,正则匹配规则遵循从前往后进行匹配,如果输入的日志字段比较长,而短日志字段匹配正则排在前面,那么会丢失日志字段,所以在排列正则时匹配字段较长的正则排在匹配字段较小的正则之前。

 

1) 配置文件

# mkdir -p /usr/local/logstash/patterns/

# cat /usr/local/logstash/patterns/patterns.conf

CID [0-9]{5,6}

TAG \w+

 

# cat /usr/local/logstash/conf.d/filter_grok-output_file.conf

input {

  file {

    path => "/tmp/test.log"

    start_position => "beginning"

  }

}

 

filter {

  grok {

    patterns_dir => "/usr/local/logstash/patterns"

    # 单模式匹配

    #match => {

    #  "message" => "%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration} %{CID:cid}"

    #}

    # 多模式匹配

    match => [

      "message","%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration} %{CID:cid} %{TAG:tag}",

      "message","%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration} %{CID:cid}"

    ]

  }

}

 

output {

  file {

    path => "/tmp/out_result.txt"

  }

}

 

2) 查看输出

echo '223.5.5.5 GET /index.html 55632 0.013 123456' >>/tmp/test.log

wps17 

 

echo '223.5.5.5 GET /index.html 55632 0.013 123456 abcdef' >>/tmp/test.log

wps18 

3.6.6 过滤插件geoip

1 说明

(1) GeoIP插件根据Maxmind GeoLite2数据库中的数据添加有关IP地址位置信息。使用多模式匹配,写多个正则表达式,只要满足其中一条就能匹配成功。

(2) 下载地址[需要注册登录才能下载]

https://www.maxmind.com/en/accounts/current/geoip/downloads

wps19 

 

2 常用字段

(1) source # 指定要解析的IP字段,结果默认保存到geoip字段

(2) database GeoLite2 # 数据库文件的路径

(3) fields # 保留解析的指定字段

 

3 示例

(1) 配置文件

# tar -xzf GeoLite2-City_20210727.tar.gz

# mv GeoLite2-City_20210727/ /usr/local/logstash/

# cat /usr/local/logstash/conf.d/filter_geoip-output_file.conf

input {

  file {

    path => "/tmp/test.log"

    start_position => "beginning"

  }

}

 

filter {

  grok {

    patterns_dir => "/usr/local/logstash/patterns"

    # 单模式匹配

    match => {

      "message" => "%{IP:client} %{WORD:method} %{URIPATHPARAM:request} %{NUMBER:bytes} %{NUMBER:duration}"

    }

  }

  geoip {

    source => "client"

    database => "/usr/local/logstash/GeoLite2-City_20210727/GeoLite2-City.mmdb"

    # 指定保留geoip解析的字段,国家编码、国家名、省会名、城市名

    fields => ["country_code2", "country_name", "region_name", "city_name"]

    # 保存到geoip字段(默认)

    target => "geoip"

  }

}

 

output {

  file {

    path => "/tmp/out_result.txt"

  }

}

 

(2) 输出结果

echo '223.5.5.5 GET /index.html 55632 0.013' >>/tmp/test.log

 

wps20 

 

# 未指定保留geoip字段内特定内容的geoip字段输出结果。

wps21 

3.7 输出插件output(将处理完成的日志推送到远程数据库存储)

3.7.1 常用插件

fileElasticsearch

3.7.2 输出插件elasticsearch

1 说明

Elasticsearch插件将数据推送到ES存储。

 

2 常用字段

(1) hosts # 指定ES主机地址。

值类型是arrayhosts => ["172.16.1.120","172.16.1.121","172.16.1.122"]

设置远程实例的主机。如果给定一个数组,它将在hosts参数中指定的主机之间对请求进行负载平衡。

 

(2) index # 指定写入的ES索引名称,一般按日期ec划分。

 

3 示例

(1) 配置文件

# cat /usr/local/logstash/conf.d/input_file-output_es.conf

input {

  file {

    path => "/tmp/test.log"

    start_position => "beginning"

    tags => "web"

    tags => "nginx"

    type => "access"

    add_field => {

      "project" => "microservice"

      "app" => "product"

    }

  }

}

 

output {

  elasticsearch {

    hosts => ["172.16.1.120","172.16.1.121","172.16.1.122"]

    index => "microservice-product-%{+YYYY.MM.dd}"

  }

}

 

(2) 查看输出

# echo "hello elasticsearch" >>/tmp/test.log

wps22 

3.8 条件判断

注意:

(1) /usr/local/logstash/conf.d/目录下自定义的所有日志收集配置文件,实际上所有的配置都在一个文件内,如果logstash在收集日志时不根据日志类型做条件判断,会导致一个input输入同时写入多个output中的情况(如果有的output做了判断,有的output没有做判断,那么没有做判断的output是所有日志的总和)logstash可以同时有多个input和多个output

(2) 如何在一台服务器上起多台logstash实例

1) 方法一

另安装一个logstash实例,修改配置文件,启动logstash即可。多个logstash实例的端口号依次排序为96009601……9700

2) 方法二

使用"/usr/local/logstash/bin/logstash -f /usr/local/logstash/conf.d/logstash1.conf --path.data=/tmp/data1"方式指定配置文件启动logstash

实例," --path.data=/tmp/data1 "表示实例的数据目录(该目录需要自己创建,注意权限),每个实例的数据目录都不相同,如果不指

定该参数启动logstash,会报' Logstash could not be started because there is already another instance using the configured data directory. If

you wish to run multiple instances, you must change the "path.data" setting. '的错误。

-f  # 覆盖logstash.yml文件中的" path.config: /usr/local/logstash/conf.d "参数。

--path.data  # 覆盖logstash.yml文件中的" path.data: LOGSTASH_HOME/data "参数。

3.8.1 操作符

1 比较操作符

==!=<><=>=

if [type] == " access" {}

# []代表引用的字段值,该值可能是单值或是一个列表。

# 单值字段 # type字段、通过field添加的字段,或者其它字段。

# 列表字段 # 比如tags字段。

 

2 正则匹配操作符

=~(匹配正则)!~(不匹配正则)

 

3 成员操作符

in(包含)not in(不包含)

if "nginx " in [tags]{}

 

4 逻辑操作符

and()or()nand(非与)nor(非或)

 

5 一元运算符

!(取反)()(复合表达式)!()(对复合表达式结果取反)

3.8.2 示例

1 典型应用场景

根据日志来源字段写入不同索引名称。

日志来源字段可以为项目名称、应用名或测试环境、生产环境等。

 

2 配置文件

# cat /usr/local/logstash/conf.d/input_mutate-output_es.conf

input {

  file {

    path => "/tmp/test.log"

    add_field => {

      "log_type" => "test"

    }

    start_position => "beginning"

  }

  file {

    path => "/tmp/prod.log"

    add_field => {

      "log_type" => "prod"

    }

    start_position => "beginning"

  }

  file {

    path => "/tmp/unknown.log"

    add_field => {

      "log_type" => "unknown"

    }

    start_position => "beginning"

  }

}

 

filter {

  if [log_type] in ["test","dev"] {

    mutate {

      add_field => {

        "[@metadata][target_index]" => "test-%{+YYYY.MM}"

      }

    }

  } else if [log_type] == "prod" {

    mutate {

      add_field => {

        "[@metadata][target_index]" => "prod-%{+YYYY.MM.dd}"

      }

    }

  } else {

    mutate {

      add_field => {

        "[@metadata][target_index]" => "unknown-%{+YYYY}"

      }

    }

  }

}

 

output {

  elasticsearch {

    hosts => ["172.16.1.120","172.16.1.121","172.16.1.122"]

    index => "%{[@metadata][target_index]}"

  }

}

 

说明:

Logstash 1.5开始,我们可以在logstash配置中使用metadatametadata不会在output中被序列化输出,这样我们便可以在metadata中添加一些临时的中间数据,而不需要去删除它。

 

3 查看输出

# echo "test" >>/tmp/test.log

# echo "prod" >>/tmp/prod.log

# echo "unknown" >>/tmp/unknown.log

wps23 

4 Filebeat部署

172.16.1.120节点上操作

4.1 Filebeat介绍

Filebeat是一个轻量级的日志采集器,将采集的数据推送到LogstashES存储。

wps24 

服务名

filebeat output默认编码方式

redis

json

kafka

json

file

json

elasticsearch

-

logstash

-

4.2 安装

1 安装包下载

(1) 二进制包

https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.13.4-linux-x86_64.tar.gz

(2) RPM(生产建议使用)

https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.13.4-x86_64.rpm

 

2 解压安装包

# tar -xzf filebeat-7.13.4-linux-x86_64.tar.gz

# mv filebeat-7.13.4-linux-x86_64/ /usr/local/filebeat/

# mkdir -p /usr/local/filebeat/data/

# mkdir -p /usr/local/filebeat/logs/

# useradd -M -s /sbin/nologin filebeat

# id filebeat

uid=1005(filebeat) gid=1005(filebeat) groups=1005(filebeat)

# chown -R filebeat.filebeat /usr/local/filebeat/

4.3 filebeat服务加入systemd

1 filebeat.service配置文件

# cat filebeat.service

[Unit]

Description=filebeat server

After=network.target

[Service]

Type=simple

ExecStart=/usr/local/filebeat/filebeat --path.config /usr/local/filebeat -c filebeat.yml --path.data /usr/local/filebeat/data --path.home /usr/local/filebeat --path.logs /usr/local/filebeat/logs

ExecReload=/bin/kill -HUP $MAINPID

KillMode=control-group

Restart=on-failure

User=filebeat

Group=filebeat

[Install]

WantedBy=multi-user.target

 

2 启动服务

# systemctl daemon-reload

# systemctl start filebeat.service

# systemctl enable filebeat.service

4.4 推送日志到Logstash

注意: 

(1) filebeat日志输入类型可以有多个,输出只能有一个,否则会报如下错误。

Exiting: error unpacking config data: more than one namespace configured accessing 'output' (source:'/usr/local/filebeat/filebeat.yml')

(2) filebeat默认第一次读取文件时从头开始读取,并记录日志的位置,下次从记录的位置开始读,如果日志被清理导致实际位置点比记录的位置点小,那么filebeat会从头开始读取日志。如果想要所有收集的日志文件都从开头读取,先stop filebeat,然后删除

filebeat数据目录下的所有数据,再启动filebeat即可。rm -rf /usr/local/filebeat/data/*

 

1 filebeat配置文件

# cat /usr/local/filebeat/filebeat.yml

filebeat.inputs:

# 配置不同的输入

- type: log

  # 是否启用该输入配置

  enabled: true

  # 采集的日志文件路径,可以通配

  paths:

    - /tmp/test.log

  # 正则匹配要排除的行,这里以DBG开头的行都过滤掉

  exclude_lines: ['^DBG']

  # 正则匹配要采集的行,这里以ERR/WARN开头的行都采集

  #include_lines: ['^ERR', '^WARN']

  # 排除的文件,默认采集所有

  exclude_files: ['.gz$']

  # 添加标签

  tags: ["web","nginx"]

  # 添加类型,改参数已经在filebeat6.0时被取消

  # document_type: "access"

  # 下面fields添加的字段默认是在fields.xxx,可以设置在顶级对象下

  fields_under_root: true

  # 自定义添加的字段,一般用于标记日志来源

  fields:

    project: microservice

    app: product

 

# 输出到文件

output.file:

  path: "/tmp"

  enabled: false

  filename: "filebeat_out.txt"

 

# 输出到logstash

output.logstash:

  hosts: ["172.16.1.120:5044"]

  # logstash服务器地址,可以有多个

  enabled: true

  # 是否开启输出至logstash,默认即为true

  worker: 1

  # 工作线程数

  compression_level: 3

  # 压缩级别

  # loadbalance: true

  # 多个输出的时候开启负载

 

# 输出到es

setup.ilm.enabled: false

setup.template.name: "filebeat-es"

setup.template.pattern: "filebeat-es-*"

output.elasticsearch:

  hosts: ["172.16.1.120:9200","172.16.1.121:9200","172.16.1.122:9200"]

  index: "filebeat-es-%{+yyyy.MM.dd}"

  enabled: false

 

# 添加模块

filebeat.config.modules:

  path: ${path.config}/modules.d/*.yml

  reload.enabled: false

  reload.period: 10s

 

# 添加主机信息

processors:

  - add_host_metadata:

      when.not.contains.tags: forwarded

  - add_cloud_metadata: ~

  - add_docker_metadata: ~

  - add_kubernetes_metadata: ~

 

补充:

(1) - type: log

1) backoff: 1s # backoff选项指定Filebeat如何积极地抓取新文件进行更新。默认1sbackoff选项定义Filebeat在达到EOF之后再次检查文件之前等待的时间。

2) max_backoff: 10s # 在达到EOF之后再次检查文件之前Filebeat等待的最长时间,默认10s

3) scan_frequency: 10s # Filebeat在指定用于收集的路径中检查新文件的频率,即Filebeat使用指定的频率扫描目录中是否有新文件产生,默认10s

backoff <= max_backoff <= scan_frequency

4) tail_files: false # 如果此选项设置为true,则Filebeat在每个文件的末尾而不是开头开始读取新文件。默认为false

5) max_bytes: 10485760 # 单个日志消息可以具有的最大字节数,默认值为10MB (10485760)

6) paths

paths:

  - /tmp/test.log

  - /var/log/*/*.log

/var/log/*/*.log,这将从/var/log的子文件夹中获取所有.log文件。它不会从/var/log文件夹本身获取日志文件。

7) tags: ["nginx","web"] # 标签列表

 

(2) output.logstash:

1) loadbalance: false

如果设置为 true 并且配置了多个 Logstash 主机,则输出插件会将发布的事件负载平衡到所有 Logstash 主机上。如果设置为 false,输出插件将所有事件仅发送到一个主机(随机确定),如果所选主机无响应,则将切换到另一台主机。默认值为false

2) compression_level: 3

gzip压缩级别。将此值设置为 0 将禁用压缩。压缩级别必须在 1(最佳速度)到 9(最佳压缩)的范围内。提高压缩级别会降低网络使用率,但会增加 CPU 使用率。默认值为 3

3) worker: 1

每个配置的主机发布事件到 Logstash 的工作线程数量,最好在启用负载平衡模式的情况下使用,和logstash数量保持一致。

没有默认值。

 

(3) enabled: true

enabled的配置是一个布尔设置,用于启用或禁用输入输出。如果设置为 false,则禁用输入输出。默认值为true

 

2 logstash配置文件

# cat /usr/local/logstash/conf.d/kubernetes_filebeat-logstash-es.conf

input {

  beats {

    host => "0.0.0.0"

    port => 5044

  }

}

 

output {

  elasticsearch {

    hosts => ["172.16.1.120","172.16.1.121","172.16.1.122"]

    index => "filebeat-logstash-es-%{+YYYY.MM.dd}"

  }

}

 

3 查看输出

# echo "filebeat-logstash-es" >>/tmp/test.log

 

(1) ES管理界面中查看收集的日志索引

wps25 

 

(2) filebeat输出的日志内容为

wps26 

4.5 推送日志到ES

Filebeat--->ELasticSearch,一般不推荐这么操作,因为filebeat的客户端很多,长时间对es进行tcp连接的话会导致es的压力很大,当然如果客户端比较少是可以的。

 

1 /usr/local/filebeat/filebeat.yml文件末尾追加如下内容

setup.ilm.enabled: false

setup.template.name: "filebeat-es"

setup.template.pattern: "filebeat-es-*"

output.elasticsearch:

  hosts: ["172.16.1.120:9200","172.16.1.121:9200","172.16.1.122:9200"]

  index: "filebeat-es-%{+yyyy.MM.dd}"

  enabled: true

 

2 ES管理界面上查看输出

# echo "filebeat-es" >>/tmp/test.log

wps27 

5 收集k8s日志

172.16.1.707172节点上操作

5.1 应用程序日志记录方式

1 标准输出

容器日志输出到控制台,使用kubectl logs可以看到,以DaemonSet方式在每个Node上部署一个日志收集程序,将每个Node/var/lib/docker/containers/目录以hostPath Volume方式挂载到日志收集容器中。

wps28 

补充: hostPath Volume

hostPath Volumepod挂载宿主机上的目录或文件,使得容器可以使用宿主机的高速文件系统进行存储。缺点是,在k8s中,pod都是动态在各node节点上调度。当一个pod在当前node节点上启动并通过hostPath存储了文件到本地以后,下次调度到另一个节点上启动时,就无法使用在之前节点上存储的文件。当删除pod后,hostPath Volume不会被删除。

但是比较适用于DaemonSet方式部署的Pod

 

2 日志文件

容器日志写到容器文件系统的文件中,将容器日志目录映射到pod调度到Node上的emptyDir Volume上,在Pod中增加一个容器运行日志采集器并共享该emptyDir Volume

wps29 

补充: emptyDir Volume

emptyDir Volume类型的volumepod分配到node上时被创建,kubernetes会在node上自动分配一个目录,因此无需指定宿主机node上对应的目录文件。这个目录的初始内容为空,当Podnode上移除时,emptyDir中的数据会被永久删除。

emptyDir Volume主要用于某些应用程序无需永久保存的临时目录,多个容器的共享目录等。

5.2 logstash配置文件

172.16.1.120节点

[root@controlnode ~]# cat /usr/local/logstash/conf.d/kubernetes_filebeat-logstash-es.conf

input {

  beats {

    host => "0.0.0.0"

    port => 5044

  }

}

 

filter {

  if [app] == "product" {

    mutate {

      add_field => {

        "[@metadata][target_index]" => "microservice-product-%{+YYYY.MM}"

      }

    }

  } else if [app] == "gateway" {

    mutate {

      add_field => {

        "[@metadata][target_index]" => "microservice-gateway-%{+YYYY.MM.dd}"

      }

    }

  } else if [app] == "nginx" {

    mutate {

      add_field => {

        "[@metadata][target_index]" => "microservice-nginx-%{+YYYY.MM.dd}"

      }

    }

  } else {

    mutate {

      add_field => {

        "[@metadata][target_index]" => "kubernetes-docker-containers-log-%{+YYYY}"

      }

    }

  }

}

 

output {

  elasticsearch {

    hosts => ["172.16.1.120:9200","172.16.1.121:9200","172.16.1.122:9200"]

    index => "%{[@metadata][target_index]}"

  }

}

5.3 标准输出方式采集日志

1 创建nginx pod

# 创建资源

[root@k8s-admin ~]# kubectl create deployment nginx --image=nginx

# 发布应用

[root@k8s-admin ~]# kubectl expose deployment nginx --port=80 --type=NodePort --target-port=80 --name=nginx

 

2 查看k8s上部署的nginx pod信息

[root@k8s-admin ~]# kubectl get pod -o wide

wps30 

[root@k8s-admin ~]# curl 10.244.2.6

[root@k8s-admin ~]# kubectl logs nginx-86c57db685-rrhzp

[root@k8s-node2 ~]# docker ps | grep "nginx-86c57db685-rrhzp"

wps31 

# cat /var/lib/docker/containers/6046a3470cc675cb0769456b391c4e07755ac67dd09def48467eca20d1e32e66/6046a3470cc675cb0769456b391c4e07755ac67dd09def48467eca20d1e32e66-json.log

wps32 

 

3 修改filebeat-kubernetes.yaml文件

# filebeat官方配置

curl -L -O https://raw.githubusercontent.com/elastic/beats/7.13/deploy/kubernetes/filebeat-kubernetes.yaml

 

(1) 参数修改

wps33 

1) 注释掉云验证配置

2) 注释掉日志输出到elasticsearch的配置

3) 添加日志输出到logstash的配置

 

(2) filebeat存储说明

1) filebeat data存储到每个Node/var/lib/filebeat-data目录下

- name: data

hostPath:

   path: /var/lib/filebeat-data

   type: DirectoryOrCreate

2) 每个Node的本地容器日志目录挂到filebeat pod

- name: varlibdockercontainers

hostPath:

   path: /var/lib/docker/containers

 

(3) 部署

[root@k8s-admin ~]# kubectl apply -f filebeat-kubernetes.yaml

wps34 

[root@k8s-admin ~]# kubectl get daemonset -n kube-system | grep filebeat

filebeat          2         2         2       2            2           <none>                        5m26s

[root@k8s-admin ~]# kubectl get pod -o wide -n kube-system | grep filebeat

wps35 

 

4 查看es中接收到的kubernetes数据

wps36 

5.4 日志文件方式采集日志

1 nginx-deployment.yaml测试文件内容概述

使用deployment方式部署3pod,每个pod中包含一个filebeat容器和一个nginx容器,filebeat容器用于收集nginx容器的日志。将nginx容器日志目录/usr/local/nginx/logs/映射到pod分配到NodeemptyDir Volume上,日志采集容器filebeat共享该emtyDir Volume,达到让日志采集器读取到nginx日志文件的目的。

# 日志标签

wps37 

 

2 部署

[root@k8s-admin ~]# kubectl apply -f nginx-deployment.yaml

deployment.apps/nginx-log-demo created

configmap/filebeat-nginx-config created

 

[root@k8s-admin ~]# kubectl get pod -o wide

wps38 

# 访问日志

wps39 

 

3 查看收集到的日志

wps40 

6 Kibana部署

172.16.1.120节点上操作

6.1 Kibana介绍

Kibana 是一个图形页面系统,用于对 Elasticsearch 数据可视化。

6.2 安装

1 下载二进制包

https://artifacts.elastic.co/downloads/kibana/kibana-7.13.4-linux-x86_64.tar.gz

 

2 修改配置文件

# tar -xzf kibana-7.13.4-linux-x86_64.tar.gz

# mv kibana-7.13.4-linux-x86_64/ /usr/local/kibana/

# mkdir -p /usr/local/kibana/logs/

# useradd -M -s /sbin/nologin kibana

# id kibana

uid=1004(kibana) gid=1004(kibana) groups=1004(kibana)

# chown -R kibana.kibana /usr/local/kibana/

 

# egrep -v "^#|^$" /usr/local/kibana/config/kibana.yml

server.port: 5601

# 端口号

server.host: "172.16.1.120"

# 监听IP地址

elasticsearch.hosts: ["http://172.16.1.120:9200","http://172.16.1.121:9200","http://172.16.1.122:9200"]

# es集群列表,必须是同一个集群

logging.dest: /usr/local/kibana/logs/logging.log

# 日志文件配置

i18n.locale: "zh-CN"

# kibana语言改为中文

logging:

  appenders:

    file:

      type: file

      fileName: /usr/local/kibana/logs/kibana.log

      layout:

        type: pattern

  root:

    appenders: [default, file]

# 收集日志配置

 

补充:

# kibana默认数据目录

<kibana安装目录>/data

6.3 Kibana服务加入systemd

1 kibana.service配置文件

# vim /usr/lib/systemd/system/kibana.service

[Unit]

Description=kibana server

After=network.target

[Service]

Type=simple

ExecStart=/usr/local/kibana/bin/kibana

ExecReload=/bin/kill -HUP $MAINPID

KillMode=control-group

Restart=on-failure

User=kibana

Group=kibana

[Install]

WantedBy=multi-user.target

 

2 启动服务

# systemctl daemon-reload

# systemctl start kibana.service

# systemctl enable kibana.service

 

3 查看端口号

[root@controlnode ~]# netstat -tunlp | grep 5601

tcp        0      0 172.16.1.120:5601       0.0.0.0:*               LISTEN      10666/node

6.4 Kibana基本使用

1 索引模式

(1) ES索引关联到kibana

wps41 

 

wps42 

 

(2) discover菜单查看

wps43 

 

2 数据搜索

(1) 语法

Key:Value的形式构建查询条件,Value使用双引号为精确查询,相反为非精确查询。

wps44 

 

(2) 基本查询

# 查询agent.namek8s-node1的日志

agent.name: "k8s-node1"

wps45 

 

(3) 逻辑组合查询(orand)

# 查询message字段中包含200304的日志

message: "200" or message: "304"

message: ("200" or "304")

wps46 

 

(4) 复合查询

# 查询message字段中包含200agent.namek8s-node1

# kubernetes.namespacekubernetes-dashboard的日志

message:"200" and (agent.name: "k8s-node1" or kubernetes.namespace: "kubernetes-dashboard")

wps47 

 

(5) 结果取反查询

# 查询agent.name不是k8s-node1的日志

not agent.name: "k8s-node1"

wps48 

 

(6) 范围查询

支持 >>=<<=

# 查询持续时间大于1的日志

duration: >1 

(7) 通配符查询

# 查询kubernetes.pod.ip字段以172.16开头的日志

kubernetes.pod.ip: 172.16*

wps49 

 

3 Kibana可视化和仪表盘

(1) Kibana可视化(Visualize): 基于ES查询,通过一系列聚合来提取和处理数据,将结果进行图表展示。另外,在创建图表需选择一个索引模式。比较常用图表有指标、折线图、饼图、数据表。

wps50 

wps51 

wps52 

 

(2) Kibana仪表盘: 显示可视化和搜索的集合,统一展示。可以随意排列,调整大小和编辑仪表盘内容等,非常灵活。

wps53 

 

wps54 

7 架构优化

7.1 增加数据缓冲队列

1 架构

使用Redis作为消息队列,起到数据缓冲作用,也就是峰值处理能力。

wps55 

 

2 实现步骤

(1) 找一台服务器安装Redis

# yum install redis -y

# vim /etc/redis/redis.conf

bind 0.0.0.0

requirepass 123456

 

(2) filebeat配置输出到redis

output.redis:

  hosts: ["172.16.1.120:6379"]

  password: "123456"

  key: "filebeat"

  db: 0

  datatype: list

enabled: true

 

(3) 检查redis是否有数据

# redis-cli -a 123456

127.0.0.1:6379> keys *

1) "filebeat" 

(4) logstash配置从redis中读日志

input {

  redis {

    host => "172.16.1.120"

    port => 6379

    password => "123456"

    db => 0

    data_type => "list"

    key => "filebeat"

  }

}

7.2 未来架构扩展思路

如果日志量每天100G以上,还需要增加更多的服务器支撑。需要扩容LogstashElasticsearch

wps56 

7.3 其它优化点

1 在预算充足情况下,服务器硬件配置尽量高。

2 根据业务,规划好索引,不用的索引可以删除或者关闭。

(1) 关闭索引

# curl -XPOST "http://172.16.1.120:9200/kubernetes-docker-containers-log-*/_close?pretty"

wps57 

# 查看索引状态

# curl -XGET http://172.16.1.120:9200/_cat/indices?v |egrep "kubernetes-docker-containers-log-*"

wps58 

 

(2) 开启索引

# curl -XPOST "http://172.16.1.120:9200/kubernetes-docker-containers-log-*/_open?pretty"

wps59 

# 查看索引状态

# curl -XGET http://172.16.1.120:9200/_cat/indices?v |egrep "kubernetes-docker-containers-log-*"

wps60 

 

(3) 删除索引

# curl -XDELETE "http://172.16.1.120:9200/kubernetes-docker-containers-log-*"

{"acknowledged":true}

8 Filebeat->Logstash->Kafka->Logstash->ES->Kibana

8.1 架构图

wps61 

172.16.1.120节点上安装nginxtomcat(8080端口和我本地的服务有冲突,我这里改成8081),这里不赘述了。

8.2 配置Filebeat->logstash

172.16.1.120节点上操作

1 nginx访问日志改为json记录方式

# vim /etc/nginx/nginx.conf

……

http {

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '

    #                  '$status $body_bytes_sent "$http_referer" '

    #                  '"$http_user_agent" "$http_x_forwarded_for"';

 

    #access_log  /var/log/nginx/access.log  main;

 

    log_format access_json '{"@timestamp":"$time_iso8601",'

                           '"server_addr":"$server_addr",'

                           '"remote_addr":"$remote_addr",'

                           '"body_bytes_sent":"$body_bytes_sent",'

                           '"request_time":"$request_time",'

                           '"upstream_response_time":"$upstream_response_time",'

                           '"upstream_addr":"$upstream_addr",'

                           '"uri":"$uri",'

                           '"http_referer":"$http_referer",'

                           '"http_user_agent":"$http_user_agent",'

                           '"http_x_forwarded_for":"$http_x_forwarded_for",'

                           '"remote_user":"$remote_user",'

                           '"request":"$request",'

                           '"status":"$status"}';

    access_log  /var/log/nginx/access.log  access_json;

……

# systemctl restart nginx.service

 

补充: logstash中通过正则匹配方式匹配nginx日志,将nginx日志字段放到json顶层。

# cat input_nginx_access_log-output_file.conf

input {

  file {

    path => "/var/log/nginx/access.log"

    start_position => "beginning"

  }

}

 

filter {

  grok {

    match => {

      "message" => "%{IPV4:remote_addr} - (%{USERNAME:remote_user}|-) \[%{HTTPDATE:time_local}\] \"%{WORD:request_method} %{URIPATHPARAM:request_uri} HTTP/%{NUMBER:http_protocol}\" %{NUMBER:http_status} %{NUMBER:body_bytes_sent} \"%{GREEDYDATA:http_referer}\" \"%{GREEDYDATA:http_user_agent}\" \"(%{IPV4:http_x_forwarded_for}|-)\""

    }

  }

}

 

output {

  file {

    path => "/tmp/out_result.txt"

  }

}

 

2 配置filebeat收集tomcat堆栈和nginx访问日志

(1) 给日志赋权,确保filebeat对日志文件可读

# chmod 755 /var/log/nginx/ && chmod 644 /var/log/nginx/access.log

# chmod 755 /usr/local/tomcat/logs/ && chmod 644 /usr/local/tomcat/logs/catalina.out

# 注意: 重启tomcatnginx会让其日志权限变为640,导致收集不到日志。

 

# filebeat多行日志匹配规则

multiline:

  pattern: '^\s'

  negate: false

  match: after

wps62 

negate是否定的意思,所以negate: false负负得正,negate: true负正得负。

 

(2) filebeat.yml文件配置

# cat /usr/local/filebeat/filebeat.yml

filebeat.inputs:

- type: log

  enabled: true

  paths:

    - /var/log/nginx/access.log

  tags: ["web","nginx-access-log"]

  exclude_lines: ['^DBG','^$']

  exclude_files: ['.gz$']

  fields:

    project: microservice

    app: gateway

  fields_under_root: true

 

- type: log

  enabled: true

  paths:

    - /usr/local/tomcat/logs/catalina.out

  tags: ["web","catalina-out-log"]

  exclude_lines: ['^DBG','^$']

  exclude_files: ['.gz$']

  multiline:

    pattern: '^\s'

    negate: false

    match: after

  fields:

    project: microservice

    app: product

  fields_under_root: true

 

output.file:

  path: "/tmp"

  enabled: false

  filename: "filebeat_out.txt"

 

output.logstash:

  hosts: ["172.16.1.120:5044"]

  enabled: true

  worker: 1

  compression_level: 3

  #loadbalance: true

 

filebeat.config.modules:

  path: ${path.config}/modules.d/*.yml

  reload.enabled: false

  reload.period: 10s

 

processors:

  - add_host_metadata:

      when.not.contains.tags: forwarded

  - add_cloud_metadata: ~

  - add_docker_metadata: ~

  - add_kubernetes_metadata: ~

 

# systemctl restart filebeat.service

8.3 配置logstash->kafka

172.16.1.120节点上操作

1 logstash-kafka.conf配置文件

# cat /usr/local/logstash/conf.d/logstash-kafka.conf

input {

  beats {

    host => "0.0.0.0"

    port => 5044

  }

}

 

output {

  if "nginx-access-log" in [tags] {

    kafka {

      topic_id => "nginx-access-log"

      bootstrap_servers => "172.16.1.120:9092,172.16.1.121:9092,172.16.1.122:9092"

      codec => "json"

    }

    # stdout { codec => rubydebug }

    # 调试时使用,使用"journalctl -u logstash.service"命令可以看到输出到kafka的日志

  }

 

  if "catalina-out-log" in [tags] {

    kafka {

      topic_id => "catalina-out-log"

      bootstrap_servers => "172.16.1.120:9092,172.16.1.121:9092,172.16.1.122:9092"

      codec => "json"

    }

    # stdout { codec => rubydebug }

  }

}

 

# systemctl restart logstash.service

 

2 查看zookeeper中的topic

[root@controlnode ~]# /usr/local/kafka/bin/kafka-topics.sh --list --bootstrap-server 172.16.1.120:9092,172.16.1.121:9092,172.16.1.122:9092

__consumer_offsets

catalina-out-log

nginx-access-log

[root@controlnode ~]# /usr/local/kafka/bin/kafka-topics.sh --describe --bootstrap-server 172.16.1.120:9092,172.16.1.121:9092,172.16.1.122:9092 --topic nginx-access-log

Topic: nginx-access-log TopicId: nMrlePWJTgiytL9L1o83dg PartitionCount: 1 ReplicationFactor: 1 Configs: segment.bytes=1073741824

Topic: nginx-access-log Partition: 0 Leader: 3 Replicas: 3 Isr: 3

 

补充:

当有日志网kafka中推送时才会创建topic,创建的topic只有1partition1replication,如果有需求可以自定义创建topic

# /usr/local/kafka/bin/kafka-topics.sh --create --bootstrap-server 172.16.1.120:9092,172.16.1.121:9092,172.16.1.122:9092 --partitions 3 --replication-factor 3 –topic nginx-access-log

8.4 配置kafka->es

172.16.1.121节点上操作

1 logstash input kafka配置说明

kafka {

  bootstrap_servers => "172.16.1.120:9092,172.16.1.121:9092,172.16.1.122:9092"

  # kafka集群地址

 

  topics => ["nginx-access-log"]

  # 要消费的kafka主题,topics值类型是arraylogstash集群需要相同。

  # topics_pattern => "nginx-access-.*"

  # 使用正则表达式匹配topic主题,使用此配置时将忽略topics配置。

 

  group_id => "nginx-access-log-group"

  # consumerConsumerGrouplogstash集群时需要相同。

 

  codec => "json"

  # 指定编码

 

  consumer_threads => 1

  # 1) 消费者线程数,即consumer数量,一般最佳配置是"同一个组内consumer个数=topic的分区数"

  # 这样consumer就会均分topic的分区,达到比较好的均衡效果。线程数多于partition数意味着某些

  # 线程将处于空闲状态。

  # 2) 如果是Logstash集群,那就让"logstash实例个数 * consumer_threads=topic分区数"即可。

  # 3) topic的一个分区不会让同一个ConsumerGroup里面的多个consumer去消费,一个consumer

  # 可以去消费多个分区的数据。

 

  decorate_events => true

  # 添加kafka标记(topicoffsetgrouppartition)等信息到message

 

  auto_offset_reset => "latest"

  # Kafka中没有消费者组的初始偏移量或偏移量超出范围时该怎么办,不定义任默认值。

  # 1) earliest       # 自动将偏移量重置为最早的偏移量

  # 2) latest         # 自动将偏移量重置为最新的偏移量

  # 3) none           # 如果没有找到消费者组的先前偏移量,则向消费者抛出异常

  # 4) anything else  # 向消费者抛出异常

}

 

2 kafka-es.conf配置文件

[root@slavenode1 ~]# cat /usr/local/logstash/conf.d/kafka-es.conf

input {

  kafka {

    bootstrap_servers => "172.16.1.120:9092,172.16.1.121:9092,172.16.1.122:9092"

    topics => ["nginx-access-log"]

    group_id => "nginx-access-log-group"

    codec => "json"

    consumer_threads => 1

    decorate_events => true

    auto_offset_reset => "latest"

  }

 

  kafka {

    bootstrap_servers => "172.16.1.120:9092,172.16.1.121:9092,172.16.1.122:9092"

    topics => ["catalina-out-log"]

    group_id => "catalina-out-log-group"

    codec => "json"

    consumer_threads => 1

    decorate_events => true

    auto_offset_reset => "latest"

  }

}

 

filter {

  if [app] == "product" {

    mutate {

      add_field => {

        "[@metadata][target_index]" => "microservice-product-%{+YYYY.MM.dd}"

      }

    }

  } else if [app] == "gateway" {

    mutate {

      add_field => {

        "[@metadata][target_index]" => "microservice-gateway-%{+YYYY.MM.dd}"

      }

    }

  }

}

output{

  elasticsearch {

    hosts => ["172.16.1.120:9200","172.16.1.121:9200","172.16.1.122:9200"]

    index => "%{[@metadata][target_index]}"

  }

}

 

# systemctl restart logstash.service

注意:

不要打开日志文件然后添加测试日志,这样会导致日志格式发生变化,导致重复消费,在kibana中会看到日志数目成倍增加,这是因为kafka客户端日志偏移量没有正确找到,然后重头开始消费。

8.5 kibana可视化展示日志

1 添加索引模式

wps63 

 

2 nginx日志

wps64 

 

 

 

 

3 tomcat堆栈日志

wps65 

9 知识拾遗

9.1 elasticsearch单实例部署

官方文档: https://www.elastic.co/guide/en/elasticsearch/reference/current/security-minimal-setup.html

172.16.1.120节点上操作

1 elasticsearch.yml配置文件

# grep "^[a-Z]" /usr/local/elasticsearch/config/elasticsearch.yml

cluster.name: es-standalone

node.name: es01

path.data: /usr/local/elasticsearch/data

path.logs: /usr/local/elasticsearch/logs

bootstrap.memory_lock: true

network.host: 172.16.1.120

http.port: 9200

transport.tcp.port: 9300

http.cors.enabled: true

http.cors.allow-origin: "*"

xpack.security.enabled: true

discovery.type: single-node

 

2 创建密码

# 为了方便,所有的用户密码都设置为"elastic",生产环境密码要设置的复杂些。

# /usr/local/elasticsearch/bin/elasticsearch-setup-passwords interactive

……

Please confirm that you would like to continue [y/N]y

Enter password for [elastic]:

Reenter password for [elastic]:

Enter password for [apm_system]:

Reenter password for [apm_system]:

Enter password for [kibana_system]:

Reenter password for [kibana_system]:

Enter password for [logstash_system]:

Reenter password for [logstash_system]:

Enter password for [beats_system]:

Reenter password for [beats_system]:

Enter password for [remote_monitoring_user]:

Reenter password for [remote_monitoring_user]:

Changed password for user [apm_system]

Changed password for user [kibana_system]

Changed password for user [kibana]

Changed password for user [logstash_system]

Changed password for user [beats_system]

Changed password for user [remote_monitoring_user]

Changed password for user [elastic]

 

# 修改密码命令如下

curl -H "Content-Type:application/json" -XPOST -u elastic 'http://172.16.1.120:9200/_xpack/security/user/elastic/_password' -d '{ "password" : "123456" }'

 

3 访问

http://172.16.1.120:9200/

wps66 

(1) 查看节点信息

# curl -u elastic:elastic http://172.16.1.120:9200/_cat/nodes?v

wps67 

# curl -u elastic:elastic http://172.16.1.120:9200

wps68 

(2) 列出索引信息

# curl -u elastic:elastic http://172.16.1.120:9200/_cat/indices?v

wps69 

9.2 elasticsearch集群设置证书验证

官方文档: https://www.elastic.co/guide/en/elasticsearch/reference/current/security-basic-setup.html

1 创建集群交互证书

172.16.1.120节点上操作

(1) 创建ca证书elastic-stack-ca.p12

# /usr/local/elasticsearch/bin/elasticsearch-certutil ca

wps70 

 

(2) 创建证书elastic-certificates.p12

# /usr/local/elasticsearch/bin/elasticsearch-certutil cert --ca /usr/local/elasticsearch/elastic-stack-ca.p12

wps71 

 

(3) 将所有证书移动到elasticsearchconfig目录下

# cd /usr/local/elasticsearch/

# mv elastic-stack-ca.p12 elastic-certificates.p12 config/

注意: 不能将elastic-certificates.p12证书放到config目录之外的路径,否则会报如下错误。

' org.elasticsearch.bootstrap.StartupException: java.security.AccessControlException: access denied ("java.io.FilePermission" "/usr/local/elasticsearch" "read") '

 

2 拷贝elastic-certificates.p12证书到另外两台es机器上并赋权

172.16.1.120节点上操作

(1) 拷贝证书

# cd /usr/local/elasticsearch/config/

# scp -P 22 -p elastic-certificates.p12 root@172.16.1.121:/usr/local/elasticsearch/config/

# scp -P 22 -p elastic-certificates.p12 root@172.16.1.122:/usr/local/elasticsearch/config/

 

(2) 赋权证书

# chown elasticsearch.elasticsearch /usr/local/elasticsearch/config/elastic-certificates.p12

# ssh -p 22 root@172.16.1.121 "chown elasticsearch:elasticsearch /usr/local/elasticsearch/config/elastic-certificates.p12"

# ssh -p 22 root@172.16.1.122 "chown elasticsearch:elasticsearch /usr/local/elasticsearch/config/elastic-certificates.p12"

 

3 配置elasticsearch.yml文件

172.16.1.120-122节点上操作

# grep -Ev "^$|^#" /usr/local/elasticsearch/config/elasticsearch.yml

cluster.name: elk-cluster

# 集群名称

node.name: es01

# 节点名称,每个节点不一样,分别是es01es02es03

path.data: /usr/local/elasticsearch/data

# 数据目录

path.logs: /usr/local/elasticsearch/logs

# 日志目录

bootstrap.memory_lock: true

# 限制elasticsearch的内存

network.host: 172.16.1.120

# 节点监听端口,三个节点分别是172.16.1.120-122

http.port: 9200

# 节点监听端口

transport.tcp.port: 9300

# 集群数据传输端口

discovery.seed_hosts: ["172.16.1.120", "172.16.1.121", "172.16.1.122"]

# 集群列表

cluster.initial_master_nodes: ["172.16.1.120", "172.16.1.121", "172.16.1.122"]

# 集群启动初始引导节点,在列表中自动选举一个

http.cors.enabled: true

http.cors.allow-origin: "*"

# 允许跨域访问elasticsearch

xpack.security.enabled: true

xpack.security.transport.ssl.enabled: true

xpack.security.transport.ssl.verification_mode: certificate

xpack.security.transport.ssl.client_authentication: required

xpack.security.transport.ssl.keystore.path: /usr/local/elasticsearch/config/elastic-certificates.p12

xpack.security.transport.ssl.truststore.path: /usr/local/elasticsearch/config/elastic-certificates.p12

# 开启证书配置,每个节点都要配

 

4 保存elastic-certificates.p12证书密码到各个节点的elasticsearch.keystore文件上并赋权

(1) 保存密码

172.16.1.120-122节点上操作

# cd /usr/local/elasticsearch/

# ./bin/elasticsearch-keystore add xpack.security.transport.ssl.keystore.secure_password

wps72 

# ./bin/elasticsearch-keystore add xpack.security.transport.ssl.truststore.secure_password

wps73 

 

(2) elasticsearch.keystore文件授权

172.16.1.120节点上操作

# chown elasticsearch.elasticsearch /usr/local/elasticsearch/config/elasticsearch.keystore

# ssh -p 22 root@172.16.1.121 "chown elasticsearch:elasticsearch /usr/local/elasticsearch/config/elasticsearch.keystore"

# ssh -p 22 root@172.16.1.122 "chown elasticsearch:elasticsearch /usr/local/elasticsearch/config/elasticsearch.keystore"

 

5 重启elasticsearch服务

(1) 重启elasticsearch服务

172.16.1.120-122节点上操作

# systemctl restart elasticsearch.service

 

(2) 查看elasticsearch日志

1) 172.16.1.120节点

Security is enabled

wps74 

2) 172.16.1.121节点

wps75 

3) 172.16.1.122节点

wps76 

 

6 创建密码

172.16.1.120节点上操作

注意: ES集群开启xpack的时候只要有一个节点设置密码即可,否则不能访问

# 我这里所有用户密码都设置为"elastic"

# /usr/share/elasticsearch/bin/elasticsearch-setup-passwords interactive

Please confirm that you would like to continue [y/N]y

Enter password for [elastic]:

Reenter password for [elastic]:

Enter password for [apm_system]:

Reenter password for [apm_system]:

Enter password for [kibana_system]:

Reenter password for [kibana_system]:

Enter password for [logstash_system]:

Reenter password for [logstash_system]:

Enter password for [beats_system]:

Reenter password for [beats_system]:

Enter password for [remote_monitoring_user]:

Reenter password for [remote_monitoring_user]:

Changed password for user [apm_system]

Changed password for user [kibana_system]

Changed password for user [kibana]

Changed password for user [logstash_system]

Changed password for user [beats_system]

Changed password for user [remote_monitoring_user]

Changed password for user [elastic]

 

7 elasticsearch集群状态查询

172.16.1.120节点上操作

(1) 节点状态

# curl -u elastic:elastic -XGET 'http://172.16.1.121:9200/_cat/nodes?pretty'

wps77 

 

(2) 集群健康状态

# curl -u elastic:elastic -i -XGET 'http://172.16.1.122:9200/_cluster/health?pretty'

wps78 

9.3 kibanalogstash带密码方式访问elasticsearch

1 kibana

(1) 修改kibana配置文件

# egrep -v "^#|^$" /usr/local/kibana/config/kibana.yml

server.port: 5601

server.host: "172.16.1.120"

elasticsearch.hosts: ["http://172.16.1.120:9200","http://172.16.1.121:9200","http://172.16.1.122:9200"]

elasticsearch.username: "kibana_system"

elasticsearch.password: "elastic"

logging.dest: /usr/local/kibana/logs/logging.log

i18n.locale: "zh-CN"

logging:

  appenders:

    file:

      type: file

      fileName: /usr/local/kibana/logs/kibana.log

      layout:

        type: pattern

  root:

    appenders: [default, file]

 

(2) 访问http://172.16.1.120:5601/

wps79 

 

2 logstash

(1) 修改配置文件

# cat input_beats-output_es.conf

input {

  beats {

    host => "0.0.0.0"

    port => 5044

  }

}

 

filter {

}

 

output {

  elasticsearch {

    hosts => ["172.16.1.120"]

    index => "input_beats-ouput_es-%{+YYYY.MM.dd}"

    user => "elastic"

    password => "elastic"

  }

}

 

(2) kibana中查看推送的日志

wps80 

wps81 

 

wps82 

9.4 filebeat优化

参考文档: https://support.huaweicloud.com/trouble-css/css_02_0018.html

 

1 针对filebeat.yml配置文件做参数优化,调整input端配置

# 根据实际情况调大harvester_buffer_size参数(该参数是指每个harvester监控文件时,使用的buffer大小)

# 以字节为单位,默认值为 16384 字节。

harvester_buffer_size: 40960000

# 根据实际情况调大filebeat.spool_size参数(该参数是指spooler的大小,一次Publish,上传多少行的日志量)

filebeat.spool_size: 250000

# 根据实际情况调整filebeat.idle_timeout参数(该参数是指spooler的超时时间,如果到了超时时间,不论是

# 否到达容量阈值,spooler会清空发送出去)

filebeat.idle_timeout: 1s

# 下面两个参数结合起来,根据应用需求,一个文件30分钟内不更新,则需要关闭句柄,文件改名或删除,需要关闭句柄。

close_older: 30m

force_close_files: true

 

 

2 针对filebeat.yml配置文件做参数优化,调整output.elasticsearch端配置

# 根据实际情况将worker参数调整为跟ES个数一致(该参数是指对应ES的个数,默认1)

worker: 1

# 根据实际情况调大bulk_max_size参数(该参数是指单个elasticsearch批量API索引请求的最大事件数,默认是50)

bulk_max_size: 15000

# 根据实际情况调整flush_interval参数(该参数是指新事件两个批量API索引请求之间需要等待的秒数,如果bulk_max_size在该值之前到达,额外的批量索引请求生效)

flush_interval: 1s

9.5 logstash优化

1 查询一下ES当前的线程情况(thread_pool)

(1) kibana开发工具中查询

GET _nodes/stats/thread_pool?pretty

(2) 使用命令行查询

# curl -u elastic:elastic -i -XGET "http://172.16.1.122:9200/_nodes/stats/thread_pool?pretty"

-u # 表示指定服务器用户和密码

-i # 表示在输出中包含协议头

-X # 表示请求命令指定要使用的请求命令

 

2 优化方案

(1) 修改logstash.yml配置文件

官方的建议是提高每次批处理的数量,调节传输间歇时间。当batch.size增大,es处理的事件数就会变少,写入也就越快了。具体的pipeline.workers数量建议等于CPU数,batch.size/batch.delay根据实际的数据量逐渐增大来测试最优值。

 

# vim /usr/local/logstash/config/logstash.yml

# 输入、输出及过滤器的总工作数量,也就是logstash的工作进程,此工作进程默认为主机的cpu核心数量

pipeline.workers: 24

# 在输入阶段,单个工作线程将从输入中收集的最大事件数,此事件数越大,堆内存开销越大,内存开销可在jvm.options文件

# 中设置堆内存大小来优化此选项。默认125

pipeline.batch.size: 10000

# 在将一个较小的批次发送到filters+output之前,轮询下一个事件时等待的时间(以毫秒为单位),默认5

pipeline.batch.delay: 10

 

(2) 修改堆内存大小

# vim /usr/local/logstash/config/jvm.options

-Xms6g

-Xmx6g

# 默认1g

9.6 kibana优化

1 kibana说明

(1) Kibana是一个单页的web应用,所有的页面的读取都是在浏览器上完成,而与后台服务器无关。与后台服务器的通信只关乎数据,而非页面。所以,应用上所有的UI都被打包在一起,一次性的发送到了浏览器端,而不是通过URL到后台进行获取。

(2) 当我们在kibana的配置文件中打开或者关闭功能,或者安装、卸载额外的插件后,重启kibana会触发一个优化的过程(optimize)kibana功能越多,代码量越大,每次optimize的过程都会耗费更多的时间。

(3) Kibana是用Nodejs编写的程序,在一般的后端语言中,内存使用上基本没有什么限制,但是在nodeJs中却只能使用部分内存。在64位系统下位约为1.4G,在32位系统下约为0.7G,因为Kibana的代码体量越来越大,将所有的代码加载到内存之后,再解析语法树,进行bundle的转换所耗费的内存已经接近1.4G的限制了,当你安装更多插件的时候,系统往往已经无法为继,导致Kibana无法启动。这种情况下,我们需要在Kibana启动的时候,指定NodeJs使用更多的内存。

 

2 优化方法

修改kibana启动脚本,添加内存。

$NODE_OPTIONS --max_old_space_size=3072 --no-warnings

 

# vim /usr/local/kibana/bin/kibana

wps83 

9.7 kibana监控的使用

X-Pack是一个Elastic Stack扩展,提供安全、警报、监控、机器学习、管道管理和许多其他功能,在安装beatslogstashelasticsearch时就已经安装了。

 

1 监控集群架构图

一般来说,监控集群和被监控的集群应该运行相同版本的堆栈。监控集群无法监控运行较新版本堆栈的生产集群。如有必要,监控集群可以监控运行旧版本的生产集群,但版本差异不能超过一个主版本。

wps84 

2 监控配置(内部收集)

(1) beats

官方文档: https://www.elastic.co/guide/en/beats/filebeat/7.14/monitoring-internal-collection.html

172.16.1.120节点上操作

1) 获取elk集群的uuid

# curl -u elastic:elastic -i -XGET "http://172.16.1.120:9200"

"cluster_uuid" : "qKs4CVLeTfWAtIaTFFmJvA",

2) 修改filebeat.yml配置文件

# vim /usr/local/filebeat/filebeat.yml

monitoring:

  enabled: true

  cluster_uuid: qKs4CVLeTfWAtIaTFFmJvA

  elasticsearch:

    hosts: ["http://172.16.1.120:9200", "http://172.16.1.121:9200", "http://172.16.1.122:9200"]

    # api_key:  id:api_key

    username: beats_system

    password: elastic

 

(2) logstash

官方文档: https://www.elastic.co/guide/en/logstash/current/monitoring-internal-collection-legacy.html

172.16.1.121节点上操作

# vim /usr/local/logstash/config/logstash.yml

xpack.monitoring.enabled: true

xpack.monitoring.elasticsearch.username: logstash_system

xpack.monitoring.elasticsearch.password: elastic

xpack.monitoring.elasticsearch.hosts: ["http://172.16.1.120:9200", "http://172.16.1.121:9200", "http://172.16.1.122:9200"]

 

(3) elasticsearch

官方文档: https://www.elastic.co/guide/en/elasticsearch/reference/current/monitoring-settings.html

172.16.1.120-122节点上操作

# vim /usr/local/elasticsearch/config/elasticsearch.yml

xpack.monitoring.enabled: true

# 启用Elasticsearch监控功能,默认为true

xpack.monitoring.collection.enabled: true

# 启用Elasticsearch数据收集功能,默认为false,不会收集Elasticsearch监控数据,并忽略来自

# 其他来源(例如KibanaBeatsLogstash)的所有监控数据。

 

(4) kibana

官方文档: https://www.elastic.co/guide/en/kibana/current/monitoring-settings-kb.html

172.16.1.120节点上操作

# vim /usr/local/kibana/config/kibana.yml

monitoring.enabled: true

# 默认为true

monitoring.ui.elasticsearch.hosts: ["http://172.16.1.120:9200","http://172.16.1.121:9200","http://172.16.1.122:9200"]

# 如果不指定默认使用"elasticsearch.hosts"

monitoring.ui.elasticsearch.username: "kibana_system"

# 如果不指定默认使用"elasticsearch.username"

monitoring.ui.elasticsearch.password: "elastic"

# 如果不指定默认使用"elasticsearch.password"

 

3 kibana中查看监控

wps85 

 

(1) 概览

wps86 

 

 

(2) 查看具体监控项

1) filebeat

wps87 

 

 

 

2) logstash

wps88 

 

 

 

 

 

 

 

 

 

 

 

 

 

3) elasticsearch

wps89 

 

 

 

 

 

 

4) kibana

wps90 

 

4 Metricbeat collection监控

(1) 说明

以上监测filebeatlogstashelasticsearchkibana堆栈的方式为"Legacy Collection",下一主要版本(8.0.0)

将不再支持这种监测方法,使用Metricbeat监测。

官方文档: https://www.elastic.co/guide/en/beats/metricbeat/7.13/metricbeat-installation-configuration.html

 

 

 

 

 

 

 

(2) Metricbeat监控架构图

wps91 

9.8 elasticsearch索引分片及副本的设置

1 索引操作

(1) 设置索引分片和副本

# 三台ES,设置3个分片,1个副本,主分片+备份分片=2

# 默认创建索引的分片数为1,副本为1

PUT /nginx-log

{

  "settings": {

    "number_of_shards": 3,

    "number_of_replicas": 1

  }

}

wps92 

 

(2) 修改索引副本数量

# 索引创建完成之后分片不可修改,副本数可以修改

PUT /nginx-log/_settings

{

  "number_of_replicas": 2

}

wps93 

 

(3) 获取索引分片信息

GET /_cat/indices?v

# 获取所有索引信息

GET /nginx-log/_search_shards

# 获取nginx-log索引的分片信息

 

(4) 往索引里插入数据

POST /nginx-log/_doc

{

  "server_name": "www.baidu.com",

  "IP": " 180.101.49.11"

}

 

(5) 查询数据分片所在位置(routing也就是数据的ID)

GET /nginx-log/_search_shards?routing=GUmH0XUBiqEQwQWjL5hD

 

(6) 删除索引

DELETE /nginx-log

 

2 索引模板设置

(1) 获取所有索引模板

GET /_template

 

(2) 简单索引模板创建

PUT _template/nginx-template

{

  "index_patterns": ["nginx*"],

  "settings": {

    "number_of_shards": 3,

    "number_of_replicas": 1

  }

}

 

(3) 插入数据

POST /nginx-log/_doc

{

  "server_name": "www.baidu.com",

  "IP": " 180.101.49.12"

}

 

(4) 删除索引模板

DELETE _template/nginx-template

posted @ 2021-08-09 17:36  云起时。  阅读(673)  评论(0编辑  收藏  举报