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.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