简介



  • 之前写过一篇博客 ELK:日志收集分析平台,介绍了在Centos7系统上部署配置使用ELK的方法,随着容器化时代的到来,容器化部署成为一种很方便的部署方式,收集容器日志也成为刚需。本篇文档从 容器化部署ELK系统,收集容器日志,自动建立项目索引,ElastAlert日志监控报警,定时删除过期日志索引文件 这几个方面来介绍ELK。
  • 大部分配置方法多是看官方文档,理解很辛苦,查了很多文章,走了很多弯路,分享出来,希望让有此需求的朋友少走弯路,如有错误或理解不当的地方,请批评指正。
  • 逻辑结构如下图

 

 

ELK之容器日志收集及索引建立



docker pull docker.elastic.co/elasticsearch/elasticsearch:6.6.2
docker pull docker.elastic.co/kibana/kibana:6.6.2
docker pull docker.elastic.co/beats/filebeat:6.6.2
docker pull docker.elastic.co/logstash/logstash:6.6.2

Elasticsearch 容器部署

Elasticsearch 启动命令说明

  • 启动两个端口,9200为数据查询和写入端口,也即是业务端口,9300为集群端口,同步集群数据,此处我单节点部署
  • 指定日志输出格式为json格式,默认情况下也为json格式,默认输出路径 /var/lib/docker/containers/*/*.log
  • 日志文件最多保留三个,每个最多10M
  • 容器开机自启
  • 传递参数为单节点部署
  • 数据存储映射至宿主机
  • 需要给 /data/elasticsearch 赋予权限,否则报权限不足的错误
docker run -d \
--user root \
-p 127.0.0.1:9200:9200 \
-p 9300:9300 \
--log-driver json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
--name elasticsearch \
--restart=always \
-e "discovery.type=single-node" \
-v /data/elasticsearch:/usr/share/elasticsearch/data \
docker.elastic.co/elasticsearch/elasticsearch:6.6.2 chmod 777 -R /data/elasticsearch

Logstash 容器部署

Logstash 配置文件说明

  • 配置文件映射至至宿主机
  • match => { "message" => "%{TIMESTAMP_ISO8601:log-timestamp} %{LOGLEVEL:log-level} %{JAVALOGMESSAGE:log-msg}" } 将日志做简单拆分, 时间戳重命名为 log-timestamp,日志级别重命名为 log-msg,如果拆分成功输出日志中就会产生这两个字段
  • 通过 remove_field => ["beat"] 移除无用字段
  • 输出到elasticsearch
  • 索引通过 容器名称-时间 建立
mkdir -pv /data/conf
cat > /data/conf/logstash.conf << "EOF"
input {
beats {
host => "0.0.0.0"
port => "5043"
}
}
filter {
grok {
match => { "message" => "%{TIMESTAMP_ISO8601:log-timestamp} %{LOGLEVEL:log-level} %{JAVALOGMESSAGE:log-msg}" }
}
mutate {
# remove_field => ["message"]
remove_field => ["beat"]
}
}
output {
stdout { codec => rubydebug }
elasticsearch {
hosts => [ "elasticsearch:9200" ]
index => "%{containername}-%{+YYYY.MM.dd}"
}
}
EOF

Logstash 启动命令说明

  • 通过 --link elasticsearch 连接 elasticsearch 容器,并生成环境变量在容器中使用
  • 配置文件映射如容器
docker run -p 5043:5043 -d \
--user root \
--log-driver json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
--name logstash \
--link elasticsearch \
--restart=always \
-v /data/conf/logstash.conf:/usr/share/logstash/pipeline/logstash.conf \
docker.elastic.co/logstash/logstash:6.6.2

Kibana容器部署

  • 启动参数参考上述组件
docker run -p 5601:5601 -d \
--user root \
--log-driver json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
--name kibana \
--link elasticsearch \
--restart=always \
-e ELASTICSEARCH_URL=http://elasticsearch:9200 \
-v /data/conf/kibana.yml:/usr/share/kibana/config/kibana.yml \
-v /data/elastalert-kibana-plugin:/usr/share/kibana/plugins/elastalert-kibana-plugin \
docker.elastic.co/kibana/kibana:6.6.2
  • 通过服务器IP地址即可访问Kibana web http://IP:5601

Filebeat 容器部署

Filebeat 配置文件说明

  • Filebeat是一个轻量级的日志收集工具,是Elastic的Beat组成员,默认情况下,docker输出的日志格式为json格式,需要解码才方便查看日志的路径为 /var/lib/docker/containers/*/*.log
  • - type: log 选择filebeat输入类型选择log,之后通过解码json的配置将docker输出的日志解码,输入类型也可选择docker,但是我试过目前版本该数据类型有些功能受限,比如后面rename时,只能rename一个
  • json解码: 必须至少指定设置其中之一来启用JSON解析模式,建议三行都加上,不然,有些功能会有问题
  • json.overwrite_keys #如果启用了keys_under_root和此设置,那么来自解码的JSON对象的值将覆盖Filebeat通常添加的字段(type, source, offset,等)以防冲突。
  • json.add_error_key #如果启用此设置,则在出现JSON解组错误或配置中定义了message_key但无法使用的情况下,Filebeat将添加“error.message”和“error.type:json”键。
  • json.message_key #一个可选的配置设置,用于指定应用行筛选和多行设置的JSON密钥。 如果指定,键必须位于JSON对象的顶层,且与键关联的值必须是字符串,否则不会发生过滤或多行聚合。
  • 多行合并: 将多行日志合并成一条,比如java的报错日志,规则为,如果不是以四个数字,即年份开头的日志合并到上一条日志当中
  • 排除或删除通配符行: 即排除含有相关关键字的行,或只收集含有相关关键字的行
  • 排除通配文件: 即不读取该含该字符的文件的日志
  • 添加docker元数据: 将docker容器的相关数据收集起来,方便作为索引的字段, match_source_index: 4 为获取docker数据的索引,其数据为json格式,索引太低可能无法获取关键docker数据
  • 处理器重命名和删除无用字段: - rename: 将上面收集的元数据重命名来提升其索引等级,以便交给logstash来处理,其中 docker.container.name 为docker容器的名字,重命名为 containername字段, - drop_fields: 清除掉无用索引数据,不输出到 output
  • 日志输出:日志输出的几种方式 output.file 输出到文件,output.console 输出到标准输出,通过 docker logs containName 查看,该两种输出方便调试
cat > /data/conf/filebeat.yml << "EOF"
filebeat.inputs:
- type: log
paths:
- '/var/lib/docker/containers/*/*.log'
# json解码
json.add_error_key: true
json.overwrite_keys: true
json.message_key: log
# 多行合并
# multiline:
# pattern: ^\d{4}
# negate: true
# match: after
#
# 排除或删除通配符行
# exclude_lines: ['^DBG']
# include_lines: ['ERROR', 'WARN', 'INFO']
# 排除通配文件
# exclude_files: ['\.gz$']
#
# 添加docker元数据
processors:
- add_docker_metadata:
match_source: true
# 选取添加docker元数据的层级
match_source_index: 4
# 处理器重命名和删除无用字段
processors:
- rename:
fields:
- from: "json.log"
to: "message"
- from: "docker.container.name"
to: "containername"
- from: "log.file.path"
to: "filepath"
- drop_fields:
fields: ["docker","metadata","beat","input","prospector","host","source","offset"]
# 日志输出
output.logstash: # 输出地址
hosts: ["192.168.30.42:5043"]
#output.elasticsearch:
# hosts: ["192.168.30.42:9200"]
# protocol: "http"
#output.file:
# path: "/tmp"
# filename: filebeat.out
#output.console:
# pretty: true
EOF

Filebeat 启动命令

  • -v /var/lib/docker/containers/:/var/lib/docker/containers/ 映射日志目录
  • -v /var/run/docker.sock:/var/run/docker.sock:ro 映射docker套接字文件,来收集docker信息,添加docker元数据
docker run -d \
--name filebeat \
--user root \
--log-driver json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
--restart=always \
-v /data/conf/filebeat.yml:/usr/share/filebeat/filebeat.yml:ro \
-v /var/lib/docker/containers/:/var/lib/docker/containers/ \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
docker.elastic.co/beats/filebeat:6.6.2
  • Filebeat是日志收集客户端,正常情况下其部署在需要收集日志的主机上

添加kibana索引

  • 通过服务器IP地址访问Kibana web http://IP:5601 同时添加索引

  • 如此便可查看相关日志

 

 

ELK之ElastAlert日志告警



  1. any:只要有匹配就报警;
  2. blacklist:compare_key字段的内容匹配上 blacklist数组里任意内容;
  3. whitelist:compare_key字段的内容一个都没能匹配上whitelist数组里内容;
  4. change:在相同query_key条件下,compare_key字段的内容,在 timeframe范围内发送变化;
  5. frequency:在相同 query_key条件下,timeframe 范围内有num_events个被过滤出来的异常;
  6. spike:在相同query_key条件下,前后两个timeframe范围内数据量相差比例超过spike_height。其中可以通过spike_type设置具体涨跌方向是up,down,both 。还可以通过threshold_ref设置要求上一个周期数据量的下限,threshold_cur设置要求当前周期数据量的下限,如果数据量不到下限,也不触发;
  7. flatline:timeframe 范围内,数据量小于threshold阈值;
  8. new_term:fields字段新出现之前terms_window_size(默认30天)范围内最多的terms_size (默认50)个结果以外的数据;
  9. cardinality:在相同 query_key条件下,timeframe范围内cardinality_field的值超过 max_cardinality 或者低于min_cardinality
  10. Percentage Match: 在buffer_time 中匹配所设置的字段的百分比高于或低于阈值时,此规则将匹配。默认情况下为全局的buffer_time

ElastAlert容器启动

  • -p 3030:3030 指定映射端口,该端口需要kibana调用
  • -v config/elastalert.yaml:/opt/elastalert/config.yaml 映射ElastAlert的配置文件
  • -v rules:/opt/elastalert/rules 映射报警规则文件目录
  • --link elasticsearch ElastAlert需要连接ElasticSearch 进行数据的查询
  • rule_templates:/opt/elastalert/rule_templates 该目录下为报警规则的模版,可使用其配置并放入 rules 使其生效,具体配置规则参考 https://elastalert.readthedocs.io/en/latest/ruletypes.html
git clone https://github.com/bitsensor/elastalert.git; cd elastalert
sed -i -e 's/localhost/elasticsearch/g' `pwd`/config/elastalert.yaml
docker run -d \
-p 3030:3030 \
-v `pwd`/config/elastalert.yaml:/opt/elastalert/config.yaml \
-v `pwd`/config/config.json:/opt/elastalert-server/config/config.json \
-v `pwd`/rules:/opt/elastalert/rules \
-v `pwd`/rule_templates:/opt/elastalert/rule_templates \
--link elasticsearch \
--name elastalert \
bitsensor/elastalert:latest
  • 可通过 elastalert-test-rule rules/rule1.yamlelastalert 容器内测试报警规则

Kibana 需要更改配置

  • 添加 elastalert 相关的配置,包括主机名和端口
cat > /data/conf/kibana.yml << "EOF"
# Default Kibana configuration from kibana-docker. server.name: kibana
server.host: "0"
elasticsearch.hosts: http://elasticsearch:9200
xpack.monitoring.ui.container.elasticsearch.enabled: true
elastalert-kibana-plugin.serverHost: elastalert
elastalert-kibana-plugin.serverPort: 3030

Kibana 启动参数更改

  • 配置 Kibana的插件 elastalert-kibana-plugin 需要注意的是,插件的下载地址 https://github.com/bitsensor/elastalert-kibana-plugin/releases 需要找到对应自己 kibana 版本,否则插件无法安装成功
  • 从目前版本来看,插件的使用不是很方便,其相当于在 ElasticAlert 启动时 -v rules:/opt/elastalert/rules 目录下写文件
  • -v /data/kibana/elastalert-kibana-plugin:/usr/share/kibana/plugins/elastalert-kibana-plugin 映射插件目录
cd /data
wget https://github.com/bitsensor/elastalert-kibana-plugin/releases/download/1.0.2/elastalert-kibana-plugin-1.0.2-6.6.2.zip
unzip elastalert-kibana-plugin-1.0.2-6.6.2.zip
docker run -p 5601:5601 -d \
--user root \
--log-driver json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
--name kibana \
--link elasticsearch \
--link elastalert \
--restart=always \
-e ELASTICSEARCH_URL=http://elasticsearch:9200 \
-v /data/conf/kibana.yml:/usr/share/kibana/config/kibana.yml \
-v /data/kibana/elastalert-kibana-plugin:/usr/share/kibana/plugins/elastalert-kibana-plugin \
docker.elastic.co/kibana/kibana:6.6.2
  • 启动后,可查看 http://IP:5601,可通过此来创建报警规则

报警规则配置

  • 这里给出一个报警规则的示例,更多请查看文档 https://elastalert.readthedocs.io/en/latest/ruletypes.html
  • es_host: elasticsearch 该配置会使用docker容器中的变量
  • name: filebeat info frequency rule 报警规则的名称,需要唯一
  • timeframe: 设定查询的时间尺度,这里指定为5分钟
  • filter 指定报警条件,示例为日志中message字段还有INFO信息就示作匹配
  • alert 指定报警方式,报警方式有很多,这里使用slack,可查看文档配置
# Alert when the rate of events exceeds a threshold

# (Optional)
# Elasticsearch host
# es_host: elasticsearch.example.com
es_host: elasticsearch # (Optional)
# Elasticsearch port
# es_port: 14900
es_port: 9200 # (OptionaL) Connect with SSL to Elasticsearch
#use_ssl: True # (Optional) basic-auth username and password for Elasticsearch
#es_username: someusername
#es_password: somepassword # (Required)
# Rule name, must be unique
name: filebeat info frequency rule # (Required)
# Type of alert.
# the frequency rule type alerts when num_events events occur with timeframe time
type: frequency # (Required)
# Index to search, wildcard supported
index: filebeat-* # (Required, frequency specific)
# Alert when this many documents matching the query occur within a timeframe
num_events: 1 # (Required, frequency specific)
# num_events must occur within this amount of time to trigger an alert
timeframe:
# hours: 1
minutes: 5
# (Required)
# A list of Elasticsearch filters used for find events
# These filters are joined with AND and nested in a filtered query
# For more info: http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl.html filter:
- query:
query_string:
query: "message:INFO"
# (Required)
# The alert is use when a match is found alert:
- "slack" alert_subject: "{} @{}"
alert_subject_args:
- containername
- log-timestamp
alert_text_type: alert_text_only
alert_text: |
> 【Name】: {}
> 【Log-Msg】: {}
alert_text_args:
- containername
- message slack_webhook_url: "https://hooks.slack.com/services/xxxx/xxxx/xxxxxx"
slack_title_link: "https://elk.glinux.top"
slack_title: "ELK URL"
slack_username_override: "ELK Alert"
slack_channel_override: "#filebeat-test"
  • 报警的效果如图

 

 

定时删除过期日志索引文件



  • 该脚本用于删除7天以前的索引文件(过月日志清除),脚本为参考他人作品,做了少许更改,可查看参考文档
  • curl -s "http://127.0.0.1:9200/_cat/indices?v" 该命令可以查看es中的索引
  • curl -XDELETE -s "http://127.0.0.1:9200/filebeat-2019.04.27" 该命令用于删除es中的 filebeat-2019.04.27 索引
cat > /data/delete_index.sh << "EOF"
#!/bin/bash elastic_url=127.0.0.1
elastic_port=9200
user="username"
pass="password"
log="/data/log/delete_index.log" # 当前日期时间戳减去索引名时间转化时间戳是否大于1
dateDiff (){
dte1=$1
dte2=$2
diffSec=$((dte1-dte2))
if ((diffSec > 6)); then
echo "1"
else
echo "0"
fi
} # 循环获取索引文件,通过正则匹配过滤
for index in $(curl -s "${elastic_url}:${elastic_port}/_cat/indices?v" | awk -F' ' '{print $3}' | grep -E "[0-9]{4}.[0-9]{2}.[0-9]{2}$"); do
# 获取索引文件日期,并转化格式
date=$(echo $index | awk -F'-' '{print $NF}' | sed -n 's/\.//p' | sed -n 's/\.//p')
# 获取当前日期
cond=$(date '+%Y%m%d')
# 根据不同服务器,计算不同数值
diff=$(dateDiff "${cond}" "${date}")
# 打印索引名和结果数值
#echo -n "${index} (${diff})" # 判断结果值是否大于等于1
if [ $diff -eq 1 ]; then
curl -XDELETE -s "${elastic_url}:${elastic_port}/${index}" && echo "${index} 删除成功" >> $log || echo "${index} 删除失败" >> $log
fi
done
EOF
  • 该脚本可以做成定时任务,每天都执行一次,来删除过期数据

 

 

参考文档



ELK

  1. 使用Docker搭建ELK日志系统 https://zhuanlan.zhihu.com/p/32559371
  2. Beats详解(四) http://www.51niux.com/?id=204
  3. Offical document: https://www.elastic.co/guide/index.html
  4. 将日志输出到Docker容器外: https://www.jianshu.com/p/bf2eb121ac62
  5. elk日志大盘显示和日志监控报警配置实践: https://blog.csdn.net/yujiak/article/details/79897408

Elastalert

  1. elastalert github地址: https://github.com/bitsensor/elastalert
  2. elastalert-kibana-plugin github地址: https://github.com/bitsensor/elastalert-kibana-plugin/tree/1.0.2
  3. ElastAlert 官方操作文档:https://elastalert.readthedocs.io/en/latest/ruletypes.html

索引定期清除

  1. 历史索引删除 http://www.cenhq.com/2017/11/07/elasticsearch-deletes-index-by-date/

其他

  1. Centos 7 Docker命令自动补全 https://medium.com/@ismailyenigul/enable-docker-command-line-auto-completion-in-bash-on-centos-ubuntu-5f1ac999a8a6
  2. Searchguard 插件支持OpenLdap:https://github.com/floragunncom/search-guard-kibana-plugin
  3. 设置登录认证: https://birdben.github.io/2017/02/08/Kibana/Kibana学习(六)Kibana设置登录认证
  4. SSL免费证书 https://certbot.eff.org/lets-encrypt/ubuntuxenial-nginx

ELK:收集Docker容器日志的更多相关文章

  1. elk-filebeat收集docker容器日志

    目录 使用docker搭建elk filebeat安装与配置 docker容器设置 参考文章 首发地址 使用docker搭建elk 1.使用docker-compose文件构建elk.文件如下: ve ...

  2. EFK的安装和收集docker容器日志展示

    在用户根目录创建个filebeat.docker.yml文件,文件内容如下 filebeat.config: modules: path: ${path.config}/modules.d/*.yml ...

  3. ELK:收集k8s容器日志最佳实践

    简介 关于日志收集这个主题,这已经是第三篇了,为什么一再研究这个课题,因为这个课题实在太重要,而当今优秀的开源解决方案还不是很明朗: 就docker微服务化而言,研发有需求标准输出,也有需求文件输出, ...

  4. docker 容器日志集中 ELK + filebeat

    docker 容器日志集中 ELK ELK 基于 ovr 网络下 docker-compose.yaml version: '2' networks: network-test: external: ...

  5. 利用 ELK 搭建 Docker 容器化应用日志中心

    利用 ELK 搭建 Docker 容器化应用日志中心 概述 应用一旦容器化以后,需要考虑的就是如何采集位于 Docker 容器中的应用程序的打印日志供运维分析.典型的比如SpringBoot应用的日志 ...

  6. docker容器日志收集方案汇总评价总结

    docker日志收集方案有太多,下面截图罗列docker官方给的日志收集方案(详细请转docker官方文档).很多方案都不适合我们下面的系列文章没有说. 经过以下5篇博客的叙述简单说下docker容器 ...

  7. docker容器日志收集方案(方案一 filebeat+本地日志收集)

    filebeat不用多说就是扫描本地磁盘日志文件,读取文件内容然后远程传输. docker容器日志默认记录方式为 json-file 就是将日志以json格式记录在磁盘上 格式如下: { " ...

  8. docker容器日志收集方案(方案二 filebeat+syslog本地日志收集)

    与方案一一样都是把日志输出到本地文件系统使用filebeat进行扫描采集 不同的是输出的位置是不一样的 我们对docker进行如下设置 sudo docker service update  --lo ...

  9. docker容器日志查看

    日志分两类,一类是 Docker 引擎日志:另一类是 容器日志. Docker 引擎日志 Docker 引擎日志 一般是交给了 Upstart(Ubuntu 14.04) 或者 systemd (Ce ...

随机推荐

  1. css控制div等比高度

    在移动端开发中,在banner轮播图未加载出来之前,banner层是不占文档流高度的,当从服务器获取完banner数据,展示的时候,banner层因为有了内容 所以会撑开,导致banner层下面的内容 ...

  2. GeneXus DevOps 自动化构建和部署流程

    以下视频详细介绍了GeneXus DevOps自动化构建和部署流程,包括通过MS Bulid来管理自动化流程,自动化的架构,以及在GeneXus Server上使用Jenkins做为自动化引擎. 视频 ...

  3. 对Java中可变参数的理解

    说明 可变参数:是DK1.5之后出现的新特性,其实可变参数是0.1.2.3.....个参数的数组 使用前提 当方法的参数列表数据类型已经确定,但是参数的个数不确定,就可以使用可变参数 使用格式 修饰符 ...

  4. Java BIO NIO 与 AIO

    回顾 上一章我们介绍了操作系统层面的 IO 模型. 阻塞 IO 模型. 非阻塞 IO 模型. IO 复用模型. 信号驱动 IO 模型(用的不多,知道个概念就行). 异步 IO 模型. 并且介绍了 IO ...

  5. 从源码角度了解SpringMVC的执行流程

    目录 从源码角度了解SpringMVC的执行流程 SpringMVC介绍 源码分析思路 源码解读 几个关键接口和类 前端控制器 DispatcherServlet 结语 从源码角度了解SpringMV ...

  6. 【Linux】---Linux系统下各种常用命令总结

    在Linux系统下,“万物皆文件”,之所以强调在强调这个概念,是因为很多人已经习惯了win系统下找找点点得那种方式和思维,因此总是会觉得linux系统下很多指令既复杂又难记.其实都是一样得东西,只是w ...

  7. 保存数据到txt

    join用的不错 a = "Hello, world" b = "你好,世界" c = "How are you?" with open(f ...

  8. SpringSecurity 默认表单登录页展示流程源码

    SpringSecurity 默认表单登录页展示流程源码 本篇主要讲解 SpringSecurity提供的默认表单登录页 它是如何展示的的流程, 涉及 1.FilterSecurityIntercep ...

  9. 代码审计之CVE-2018-7600-Drupal远程代码执行漏洞-Render API

    今天学习一下Drupal的另一个漏洞,由于渲染数组不当造成的漏洞 poc: url:http://localhost/drupal-8.5.0/user/register?element_parent ...

  10. 高通量计算框架HTCondor(三)——使用命令

    目录 1. 目录 2. 进程 3. 命令 3.1. condor_q 3.2. condor_status 3.3. conodr_submit 3.4. conodr_rm 4. 相关 1. 目录 ...