第16章: ELK+K8S
ELK+K8S
作者 |
刘畅 |
时间 |
2021-07-26 |
环境: CentOS7.5
主机名称 |
IP |
软件 |
controlnode |
172.16.1.120 [4核8G] |
kafka环境[zookeeper-3.7.0、kafka_2.13-2.8.0、jdk1.8.0_45] ELK环境[nginx、tomcat、ES-7.13.4、ElasticHD、logstash-7.13.4、filebeat-7.13.4、kibana-7.13.4] |
slavenode1 |
172.16.1.121 [2核4G] |
kafka环境[zookeeper-3.7.0、kafka_2.13-2.8.0、jdk1.8.0_45] ELK环境[ES-7.13.4、logstash-7.13.4] |
slavenode2 |
172.16.1.122 [2核4G] |
kafka环境[zookeeper-3.7.0、kafka_2.13-2.8.0、jdk1.8.0_45] ELK环境[ES-7.13.4] |
k8s-admin |
172.16.1.70 [2核4G] |
K8S控制端 |
k8s-node1 |
172.16.1.71 [4核8G] |
k8s slave端01 |
k8s-node2 |
172.16.1.72 [4核8G] |
k8s slave端02 |
(1) 注: 本文档不记录zookeeper+kafka、k8s的搭建过程。
(2) ELK官方文档: https://www.elastic.co/guide/index.html
(3) ELK下载地址: https://www.elastic.co/downloads/
(4) elasticsearch、logstash自带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
目录
2.3 将Elasticsearch服务加入systemd 3
3.5 输入插件input(输入阶段,从哪里获取日志) 12
3.6 过滤插件filter(过滤阶段,将日志格式化处理) 15
3.7 输出插件output(将处理完成的日志推送到远程数据库存储) 24
8 Filebeat->Logstash->Kafka->Logstash->ES->Kibana 53
9.3 kibana、logstash带密码方式访问elasticsearch 68
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
# 集合了多种单一用途数据采集器,用于实现从边缘机器向Logstash和Elasticsearch发送数据。是应用最多的,是一个轻量级日志采集器。
1.3 ELK架构
2 Elasticsearch集群部署
在172.16.1.120、121、122节点上操作
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节点为es01,172.16.1.121节点为es02,172.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.120,172.16.1.121,172.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
3) 查看指定es节点基本信息
[root@controlnode ~]# curl -XGET '172.16.1.120:9200/?pretty'
2.4 图形页面管理ES
在172.16.1.120节点上操作
1 下载
推荐插件: ElasticHD、cerebro、elasticsearch-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/
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
概要信息:
3 Logstash部署
在172.16.1.120节点上操作
3.1 Logstash介绍
Logstash能够将采集日志、格式化、过滤,最后将数据推送到Elasticsearch存储。
Logstash不只是一个input|filter|output的数据流,而是一个input|decode|filter|encode|output的数据流。codec就是用来decode,encode 事件的。所以codec常用在input和output中,常用的codec插件有plain,json,multiline等。
服务名 |
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) 解码和编码都是json,json数据不添加任何内容。
(2) plain
1) "plain"编解码器用于纯文本,事件之间没有分隔。这主要用于在其传输协议中已经定义了框架的输入和输出(例如zeromq、rabbitmq、redis等)。
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 事件数据。
(1) Input: 输入,输入数据可以是Stdin、File、TCP、Redis、Syslog等。
(2) Filter: 过滤,将日志格式化。有丰富的过滤插件:Grok正则捕获、Date时间处理、Json编解码
、Mutate数据修改等。
(3) Output:输出,输出目标可以是Stdout、File、TCP、Redis、ES等。
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
# 自定义input,output流处理文件路径
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服务会自动停止运行,所以看不到logstash的9600端口号。
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
3 从配置文件启动logstash
# /usr/local/logstash/bin/logstash -f /usr/local/logstash/conf.d/input_stdin-output_stdout.conf
说明:
message # 输入的信息
默认给日志加了如下三个字段:
(1) "@timestamp" # 标记事件发生的时间点,写入es时索引用到的" %{+YYYY.MM.dd} "变量就来自这里。
(2) "host" # 标记事件发生的主机
(3) "@version"
4 查看logstash节点基本信息
# curl -XGET '172.16.1.120:9600/?pretty'
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 # 添加任意数量的标签,用于标记日志的其它属性。例如表名是访问日志还是错误日志。
值类型是array,tags => ["web","nginx"]
3 type # 为所有输入添加一个字段,例如表明日志的类型。
值类型是string,type => "access"
3.5.3 输入插件file
file插件用于读取指定日志的文件。
1 常用字段
(1) path # 日志文件路径,可以使用通配符。
值类型是array,path => ["/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 {
exclude => "error.log"
start_position => "beginning"
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
# 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/
(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 常用插件
json、kv、grok、geoip、date
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,如果此过滤器成功,则从此事件中删除任意字段。
(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
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
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) 正则符号说明
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}
(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
echo '223.5.5.5 GET /index.html 55632 0.013 123456 abcdef' >>/tmp/test.log
3.6.6 过滤插件geoip
(1) GeoIP插件根据Maxmind GeoLite2数据库中的数据添加有关IP地址位置信息。使用多模式匹配,写多个正则表达式,只要满足其中一条就能匹配成功。
(2) 下载地址[需要注册登录才能下载]
https://www.maxmind.com/en/accounts/current/geoip/downloads
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
# 未指定保留geoip字段内特定内容的geoip字段输出结果。
3.7 输出插件output(将处理完成的日志推送到远程数据库存储)
3.7.1 常用插件
file、Elasticsearch
3.7.2 输出插件elasticsearch
1 说明
Elasticsearch插件将数据推送到ES存储。
2 常用字段
(1) hosts # 指定ES主机地址。
值类型是array,hosts => ["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
3.8 条件判断
注意:
(1) /usr/local/logstash/conf.d/目录下自定义的所有日志收集配置文件,实际上所有的配置都在一个文件内,如果logstash在收集日志时不根据日志类型做条件判断,会导致一个input输入同时写入多个output中的情况(如果有的output做了判断,有的output没有做判断,那么没有做判断的output是所有日志的总和)。logstash可以同时有多个input和多个output。
(2) 如何在一台服务器上起多台logstash实例
1) 方法一
另安装一个logstash实例,修改配置文件,启动logstash即可。多个logstash实例的端口号依次排序为9600、9601、……、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配置中使用metadata。metadata不会在output中被序列化输出,这样我们便可以在metadata中添加一些临时的中间数据,而不需要去删除它。
3 查看输出
# echo "test" >>/tmp/test.log
# echo "prod" >>/tmp/prod.log
# echo "unknown" >>/tmp/unknown.log
4 Filebeat部署
在172.16.1.120节点上操作
4.1 Filebeat介绍
Filebeat是一个轻量级的日志采集器,将采集的数据推送到Logstash、ES存储。
服务名 |
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
# 采集的日志文件路径,可以通配
- /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
hosts: ["172.16.1.120:5044"]
# logstash服务器地址,可以有多个
enabled: true
# 是否开启输出至logstash,默认即为true
# 工作线程数
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如何积极地抓取新文件进行更新。默认1s,backoff选项定义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管理界面中查看收集的日志索引
(2) filebeat输出的日志内容为
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
5 收集k8s日志
在172.16.1.70、71、72节点上操作
5.1 应用程序日志记录方式
1 标准输出
容器日志输出到控制台,使用kubectl logs可以看到,以DaemonSet方式在每个Node上部署一个日志收集程序,将每个Node的/var/lib/docker/containers/目录以hostPath Volume方式挂载到日志收集容器中。
补充: hostPath Volume
hostPath Volume为pod挂载宿主机上的目录或文件,使得容器可以使用宿主机的高速文件系统进行存储。缺点是,在k8s中,pod都是动态在各node节点上调度。当一个pod在当前node节点上启动并通过hostPath存储了文件到本地以后,下次调度到另一个节点上启动时,就无法使用在之前节点上存储的文件。当删除pod后,hostPath Volume不会被删除。
但是比较适用于DaemonSet方式部署的Pod。
2 日志文件
容器日志写到容器文件系统的文件中,将容器日志目录映射到pod调度到Node上的emptyDir Volume上,在Pod中增加一个容器运行日志采集器并共享该emptyDir Volume。
emptyDir Volume类型的volume在pod分配到node上时被创建,kubernetes会在node上自动分配一个目录,因此无需指定宿主机node上对应的目录文件。这个目录的初始内容为空,当Pod从node上移除时,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
[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"
# cat /var/lib/docker/containers/6046a3470cc675cb0769456b391c4e07755ac67dd09def48467eca20d1e32e66/6046a3470cc675cb0769456b391c4e07755ac67dd09def48467eca20d1e32e66-json.log
3 修改filebeat-kubernetes.yaml文件
# filebeat官方配置
curl -L -O https://raw.githubusercontent.com/elastic/beats/7.13/deploy/kubernetes/filebeat-kubernetes.yaml
(1) 参数修改
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
[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
4 查看es中接收到的kubernetes数据
5.4 日志文件方式采集日志
1 nginx-deployment.yaml测试文件内容概述
使用deployment方式部署3个pod,每个pod中包含一个filebeat容器和一个nginx容器,filebeat容器用于收集nginx容器的日志。将nginx容器日志目录/usr/local/nginx/logs/映射到pod分配到Node的emptyDir Volume上,日志采集容器filebeat共享该emtyDir Volume,达到让日志采集器读取到nginx日志文件的目的。
# 日志标签
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
# 访问日志
3 查看收集到的日志
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
(2) 在discover菜单查看
2 数据搜索
(1) 语法
以Key:Value的形式构建查询条件,Value使用双引号为精确查询,相反为非精确查询。
(2) 基本查询
# 查询agent.name为k8s-node1的日志
agent.name: "k8s-node1"
(3) 逻辑组合查询(or、and)
# 查询message字段中包含200或304的日志
message: "200" or message: "304"
message: ("200" or "304")
(4) 复合查询
# 查询message字段中包含200且agent.name为k8s-node1
# 或kubernetes.namespace为kubernetes-dashboard的日志
message:"200" and (agent.name: "k8s-node1" or kubernetes.namespace: "kubernetes-dashboard")
(5) 结果取反查询
# 查询agent.name不是k8s-node1的日志
not agent.name: "k8s-node1"
(6) 范围查询
支持 >,>=,<,<=
# 查询持续时间大于1的日志
duration: >1
(7) 通配符查询
# 查询kubernetes.pod.ip字段以172.16开头的日志
3 Kibana可视化和仪表盘
(1) Kibana可视化(Visualize): 基于ES查询,通过一系列聚合来提取和处理数据,将结果进行图表展示。另外,在创建图表需选择一个索引模式。比较常用图表有指标、折线图、饼图、数据表。
(2) Kibana仪表盘: 显示可视化和搜索的集合,统一展示。可以随意排列,调整大小和编辑仪表盘内容等,非常灵活。
7 架构优化
7.1 增加数据缓冲队列
1 架构
使用Redis作为消息队列,起到数据缓冲作用,也就是峰值处理能力。
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以上,还需要增加更多的服务器支撑。需要扩容Logstash、Elasticsearch
7.3 其它优化点
1 在预算充足情况下,服务器硬件配置尽量高。
2 根据业务,规划好索引,不用的索引可以删除或者关闭。
(1) 关闭索引
# curl -XPOST "http://172.16.1.120:9200/kubernetes-docker-containers-log-*/_close?pretty"
# 查看索引状态
# curl -XGET http://172.16.1.120:9200/_cat/indices?v |egrep "kubernetes-docker-containers-log-*"
(2) 开启索引
# curl -XPOST "http://172.16.1.120:9200/kubernetes-docker-containers-log-*/_open?pretty"
# 查看索引状态
# curl -XGET http://172.16.1.120:9200/_cat/indices?v |egrep "kubernetes-docker-containers-log-*"
(3) 删除索引
# curl -XDELETE "http://172.16.1.120:9200/kubernetes-docker-containers-log-*"
{"acknowledged":true}
8 Filebeat->Logstash->Kafka->Logstash->ES->Kibana
8.1 架构图
在172.16.1.120节点上安装nginx、tomcat(8080端口和我本地的服务有冲突,我这里改成8081),这里不赘述了。
8.2 配置Filebeat->logstash
# 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
# 注意: 重启tomcat、nginx会让其日志权限变为640,导致收集不到日志。
# filebeat多行日志匹配规则
multiline:
pattern: '^\s'
negate: false
match: after
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
[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只有1个partition和1个replication,如果有需求可以自定义创建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值类型是array,logstash集群需要相同。
# topics_pattern => "nginx-access-.*"
# 使用正则表达式匹配topic主题,使用此配置时将忽略topics配置。
group_id => "nginx-access-log-group"
# consumer的ConsumerGroup,logstash集群时需要相同。
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标记(topic、offset、group、partition)等信息到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 添加索引模式
2 nginx日志
3 tomcat堆栈日志
9 知识拾遗
9.1 elasticsearch单实例部署
官方文档: https://www.elastic.co/guide/en/elasticsearch/reference/current/security-minimal-setup.html
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/
(1) 查看节点信息
# curl -u elastic:elastic http://172.16.1.120:9200/_cat/nodes?v
# curl -u elastic:elastic http://172.16.1.120:9200
(2) 列出索引信息
# curl -u elastic:elastic http://172.16.1.120:9200/_cat/indices?v
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
(2) 创建证书elastic-certificates.p12
# /usr/local/elasticsearch/bin/elasticsearch-certutil cert --ca /usr/local/elasticsearch/elastic-stack-ca.p12
(3) 将所有证书移动到elasticsearch的config目录下
# 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文件
# grep -Ev "^$|^#" /usr/local/elasticsearch/config/elasticsearch.yml
cluster.name: elk-cluster
# 集群名称
node.name: es01
# 节点名称,每个节点不一样,分别是es01,es02,es03
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
# ./bin/elasticsearch-keystore add xpack.security.transport.ssl.truststore.secure_password
(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
2) 172.16.1.121节点
3) 172.16.1.122节点
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'
(2) 集群健康状态
# curl -u elastic:elastic -i -XGET 'http://172.16.1.122:9200/_cluster/health?pretty'
9.3 kibana、logstash带密码方式访问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/
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中查看推送的日志
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
9.7 kibana监控的使用
X-Pack是一个Elastic Stack扩展,提供安全、警报、监控、机器学习、管道管理和许多其他功能,在安装beats、logstash、elasticsearch时就已经安装了。
1 监控集群架构图
一般来说,监控集群和被监控的集群应该运行相同版本的堆栈。监控集群无法监控运行较新版本堆栈的生产集群。如有必要,监控集群可以监控运行旧版本的生产集群,但版本差异不能超过一个主版本。
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监控数据,并忽略来自
# 其他来源(例如Kibana、Beats、Logstash)的所有监控数据。
(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中查看监控
(1) 概览
(2) 查看具体监控项
1) filebeat
2) logstash
3) elasticsearch
4) kibana
4 Metricbeat collection监控
(1) 说明
以上监测filebeat、logstash、elasticsearch、kibana堆栈的方式为"Legacy Collection",下一主要版本(8.0.0)
将不再支持这种监测方法,使用Metricbeat监测。
官方文档: https://www.elastic.co/guide/en/beats/metricbeat/7.13/metricbeat-installation-configuration.html
(2) Metricbeat监控架构图
9.8 elasticsearch索引分片及副本的设置
1 索引操作
(1) 设置索引分片和副本
# 三台ES,设置3个分片,1个副本,主分片+备份分片=2
# 默认创建索引的分片数为1,副本为1
PUT /nginx-log
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 1
}
}
(2) 修改索引副本数量
# 索引创建完成之后分片不可修改,副本数可以修改
PUT /nginx-log/_settings
{
"number_of_replicas": 2
}
(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