05月03, 2018

探索 - Elastic Stack(ELK)实时日志分析平台

简介

  • Elasticsearch(更多详情
    搜索、分析和存储您的数据。
  • Kibana(更多详情
    实现数据可视化。
  • Logstash(更多详情
    Logstash 是动态数据收集管道,拥有可扩展的插件生态系统,能够与 Elasticsearch 产生强大的协同作用。
  • Beats(更多详情
    Beats 是轻量型采集器的平台,从边缘机器向 Logstash 和 Elasticsearch 发送数据。
  • X-Pack(更多详情
    X-Pack 是集成了多种便捷功能的单个插件 — security、alerting、monitoring、reporting、graph 探索和 machine learning 。
  • ES-Hadoop(更多详情
    Elasticsearch-Hadoop (ES-Hadoop) 连接器将 Hadoop 海量的数据存储和深度加工能力与 Elasticsearch 实时搜索和分析功能进行连接。它能够让您快速深入了解大数据,并让您在 Hadoop 生态系统中更好地开展工作。

安装顺序

按照以下顺序安装 你要使用的Elastic Stack产品:

  1. Elasticsearch
  2. X-Pack for Elasticsearch
  3. Kibana
  4. X-Pack for Kibana
  5. Logstash
  6. X-Pack for Logstash
  7. Beats
  8. Elasticsearch Hadoop

下图为X-PackElasticsearchKibanaLogstash中所提供的功能。

X-pack

注: X-Pack 将于 6.3 版本起开源。(官方说明

准备工作

1、下载所需的软件包:官方地址

  • 我这里所用的版本是:6.2.4(发布时间:2018-4-17)

  • 所涉及到的Elastic Stack软件产品有:Elasticsearch、Kibana、Logstash、FileBeat、X-Pack

  • 下载的均是 tar.gz 的包,这样可以更加灵活的控制在服务器中的部署位置。

# mkdir /opt/download/elastic
# cd /opt/download/elastic
# wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.2.4.tar.gz
# wget https://artifacts.elastic.co/downloads/kibana/kibana-6.2.4-linux-x86_64.tar.gz
# wget https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-6.2.4-linux-x86_64.tar.gz
# wget https://artifacts.elastic.co/downloads/logstash/logstash-6.2.4.tar.gz
# wget https://artifacts.elastic.co/downloads/packs/x-pack/x-pack-6.2.4.zip

2、服务器资源

  • ES最小的集群为3个节点。
  • 这里我以单点的形式部署介绍Elastic Stack,同时也会有对集群模式的说明。

3、创建普通用户
不要以root用户运行应用程序,这里我创建一个elastic普通用户。

# useradd elastic

4、创建目录结构
分别创建 程序目录、日志目录、数据目录,并对elastic普通用户授权目录权限。

# mkdir -p /opt/soft/elastic    
# mkdir -p /opt/log/elastic/{elasticsearch,logstash,kibana}
# mkdir -p /opt/data/elastic/{elasticsearch,logstash,kibana}

# chwon -R elastic:elastic /opt/soft/elastic
# chwon -R elastic:elastic  /opt/log/elastic
# chwon -R elastic:elastic /opt/data/elastic

5、配置java环境
访问Oracle官网 下载JAVA
这里我下载的版本是jdk-8u171-linux-x64.tar.gz

## 解压安装
# tar xzf jdk-8u171-linux-x64.tar.gz -C /opt/soft/

## 配置JAVA的全局环境变量
# tail -1 /etc/profile
export PATH=/opt/soft/jdk1.8.0_171/bin:$PATH

## 重新登录当前终端或重载环境,可直接执行java命令为完成配置。
# . /etc/profile
# java -version
java version "1.8.0_171"
Java(TM) SE Runtime Environment (build 1.8.0_171-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.171-b11, mixed mode)

6、补充说明
本文只根据官方资料,对nginx日志采集处理组织一个比较系统的简要介绍,没有针对单个产品的深入剖析。

全文中,代码字段说明:

  • ##符号开头,注释行
  • # 符号开头,以超级用户执行的命令
  • $符号开头,以普通用户执行的命令

安装过程

Elastic Stack

全文会围绕着此图进行Elastic Stack介绍。

  • Beats服务部署在应用服务器(或称之边缘服务器)进行数据采集。
  • Logstash服务接收数据进行解析,处理数据结构后写入ES。
  • ElasticSearch服务搜索、分析和存储数据。在规模较大时,ES集群需要进行角色拆分。
  • Kibana操作 Elastic Stack 可视化 Elasticsearch 中的数据。

说明:在生产环境中每层都建议是独立的主机,避免额外的干扰,提高每层的数据处理能力。另外,在一些网上的资料中,有的会在采集层和解析层中间加一层队列层(队列服务 - REDIS/MQ/Kafka),用来提高突发尖峰等异常情况的容错能力。其实是非必要的,下面会在介绍Logstash时对此说明。


安装 Elasticsearch

## 配置用户的文件打开数及线程数
# grep "elastic" /etc/security/limits.conf
elastic - nofile  65536
elastic - nproc 4096

## 配置虚拟内存
# grep "max_map_count" /etc/sysctl.conf
vm.max_map_count = 262144
# sysctl -p

## 解压即安装
# su - elastic
$ tar xzf /opt/download/elastic/elasticsearch-6.2.4.tar.gz -C /opt/soft/elastic/

## 配置文件
$ cd /opt/soft/elastic/elasticsearch-6.2.4
$ cat config/elasticsearch.yml
cluster.name: elasticsearch
node.name: ${HOSTNAME}
network.host: 0.0.0.0
path.data: /opt/data/elastic/elasticsearch
path.logs: /opt/log/elastic/elasticsearch

## 安装 X-pack 插件
$ bin/elasticsearch-plugin install file:///opt/download/elastic/x-pack-6.2.4.zip

## 启动服务
$ bin/elasticsearch  -p elasticsearch.pid -d

## 生成 elastic、kibana、logstash_system 用户密码
$ bin/x-pack/setup-passwords auto

可以直接以${...}的方式,调用系统中的环境变量。

一些重要的ES配置

来源参见: 官方说明

  • Path settings
    配置日志、数据的存放路径,其中数据存放路径可以配置成多个路径,在这种情况下,所有路径都将被用于存储数据。

  • Cluster name
    cluster.name相同的节点可以组建成一个集群,默认的名称是elasticsearch,但是你应该将它更改为一个适当的名称,它描述了集群的目的。 确保不会在不同的环境中重用相同的集群名称,否则可能会遇到连接错误集群的节点。

  • Node name
    在默认情况下,elasticsearch将使用随机生成的UUID的前七个字符作为节点id。注意,节点id是持久化的,也就是说当节点重新启动时不会改变,所以配置一个可读性更高的节点名是有意义的,这里我习惯以主机名命名。

  • Network host
    默认情况下,elasticsearch只绑定本地回环地址127.0.0.1,这适合在单台服务器上部署单个开发节点。生产环境根据情况配置为你要监听的实际地址,以实现集群个节点间的通信。
    注意:单个服务器启动多个elasticsearch进程也能实现集群功能,但仅适用于测试。

  • Discovery settings
    elasticsearch使用Zen Discovery自定义发现实现节点与节点的集群建立和主选举。在生产环境中应该配置两个重要的发现设置。

    • discovery.zen.ping.unicast.hosts
      单播其它节点
    • discovery.zen.minimum_master_nodes
      避免脑裂,防止数据丢失,每个主合格节点都知道必须可见的主合格节点的最小数量,以便形成集群。最小值:(master_eligible_nodes / 2) + 1
  • Heap size
    默认情况下,Elasticsearch告诉JVM使用最小和最大的Heap size为1GB。生产环境中,配置Heap size是很重要的,以确保ES有足够的堆可用。配置法则是:
    • 将最小堆大小(Xms)和最大堆大小(Xmx)设置为相等。其目的是为了能够在java垃圾回收机制清理完堆区后不需要重新分隔计算堆区的大小而浪费资源,可以减轻伸缩堆大小带来的压力。
    • 值大小不超过物理RAM的50%,以确保内核文件系统缓存中有足够的物理RAM。
    • 最大大小不要超过32GB。
  • Heap dump path
    RPM和Debian默认配置JVM,以将内存溢出时的堆转储到/var/lib/elasticsearch,如果此路径不适合存储堆转储,可修改-XX:HeapDumpPath=/var/lib/elasticsearch自定义路径。 如果指定了文件名而不是目录,则JVM将重复使用相同的文件; 这是一种防止堆转储在堆转储路径中积累的机制。或者,你可以通过配置计划任务,定期删除比配置的时间早的堆转储。
    请注意,归档分发默认情况下不配置堆转储路径。

  • GC logging
    默认启用,存放路径与ES日志路径一致。并且每64MB就会旋转日志,最多可以消耗2GB的磁盘空间。

重要的系统配置

这里不做过多的赘述,细节详情参见:官方说明

  • Disable swapping
  • Increase file descriptors
  • Ensure sufficient virtual memory
  • Ensure sufficient threads
  • JVM DNS cache settings

需要了解的 Node 角色

  • Master-eligible node
    有资格被选为控制集群的主节点。主节点负责轻量级集群范围的操作,如创建或删除索引、跟踪哪些节点是集群的一部分,以及决定将哪些切分分配给哪些节点。对于集群健康来说,拥有一个稳定的主节点是很重要的。

  • Data node
    数据节点保存数据并执行与数据相关的操作,如CRUD、搜索和聚合。拥有专用数据节点的主要好处是主服务器和数据角色的分离。

  • Ingest node
    摄取节点能够将摄取管道应用于文档,以便在编制索引之前转换和丰富文档。

  • Tribe node
    通过 tribe.* 配置部落节点。是一种特殊的协调节点,它可以连接到多个集群,并在所有连接的集群中执行搜索和其他操作。

    注意:Tribe node 从5.4.0版本起已被弃用。被 Cross Cluster Search 功能所取代,并将于 Elasticsearch 7.0 时移除。

  • Coordinating node
    如果 node 禁用了node.master、node.data、node.ingest 能力,那么就剩下了一个协调节点,该节点只能路由请求、处理搜索减少阶段,以及分发批量索引。从本质上说,只协调节点就像智能负载平衡器一样。这样的节点需要有足够的内存和CPU来处理收集阶段。

    注意:将太多的协调节点添加到集群中会增加整个集群的负担,因为所选的主节点必须等待来自每个节点的集群状态更新的确认!只协调节点的好处不应该被夸大 —— 数据节点可以很好地服务于相同的目的。

更多细节详情参见:官方说明


安装 Kibana

配置为单机部署的最简配置。配置完启动后可通过:http://your_server_ip:5601 访问kibana的web服务。不要带端口访问的话,建议结合nginx来实现。

## 解压即安装
$ tar xzf /opt/download/elastic/kibana-6.2.4-linux-x86_64.tar.gz -C /opt/soft/elastic
$ cd /opt/soft/elastic/kibana-6.2.4-linux-x86_64

## 安装 X-pack 插件
$ bin/kibana-plugin install file:///opt/download/elastic/x-pack-6.2.4.zip

## 配置文件
$ grep -Ev '^#|^$' config/kibana.yml 
server.host: "0.0.0.0"
elasticsearch.username: "kibana"
elasticsearch.password: "Your****Pass****For****Kibana"
pid.file: /opt/log/elastic/kibana/kibana.pid

## 启动服务
$ nohup bin/kibana &> /dev/null &

安装 Logstash

## 解压即安装
$ tar xzf /opt/download/elastic/logstash-6.2.4.tar.gz -C /opt/soft/elastic/
$ cd /opt/soft/elastic/logstash-6.2.4/

## 安装 X-pack 插件
$ bin/logstash-plugin install file:///opt/download/elastic/x-pack-6.2.4.zip

## 主配置文件
$ grep -Ev "^#|^$" config/logstash.yml 
node.name: ${HOSTNAME}
path.data: /opt/data/elastic/logstash
config.reload.automatic: true
path.logs: /opt/log/elastic/logstash
xpack.monitoring.elasticsearch.url: ["http://your_es_ip:9200"] 
xpack.monitoring.elasticsearch.username: "logstash_system" 
xpack.monitoring.elasticsearch.password: "your***logstash***pass"

接下来配置work文件,用于解析处理数据。

$ mkdir workconfig
$ cat workconfig/test-nginx.conf
input {
  beats {
    port => 5044
    host => "0.0.0.0"
  }
}
filter {
  if [fileset][module] == "nginx" {
    if [fileset][name] == "access" {
      grok {
        match => { "message" => ["%{IPORHOST:[nginx][access][remote_ip]} - %{DATA:[nginx][access][user_name]} \[%{HTTPDATE:[nginx][access][time]}\] \"%{WORD:[nginx][access][method]} %{DATA:[nginx][access][url]} HTTP/%{NUMBER:[nginx][access][http_version]}\" %{NUMBER:[nginx][access][response_code]} %{NUMBER:[nginx][access][body_sent][bytes]} \"%{DATA:[nginx][access][referrer]}\" \"%{DATA:[nginx][access][agent]}\""] }
        remove_field => "message"
      }
      mutate {
        add_field => { "read_timestamp" => "%{@timestamp}" }
      }
      date {
        match => [ "[nginx][access][time]", "dd/MM/YYYY:H:m:s Z" ]
        remove_field => "[nginx][access][time]"
      }
      useragent {
        source => "[nginx][access][agent]"
        target => "[nginx][access][user_agent]"
        remove_field => "[nginx][access][agent]"
      }
      geoip {
        source => "[nginx][access][remote_ip]"
        target => "[nginx][access][geoip]"
      }
    }
    else if [fileset][name] == "error" {
      grok {
        match => { "message" => ["%{DATA:[nginx][error][time]} \[%{DATA:[nginx][error][level]}\] %{NUMBER:[nginx][error][pid]}#%{NUMBER:[nginx][error][tid]}: (\*%{NUMBER:[nginx][error][connection_id]} )?%{GREEDYDATA:[nginx][error][message]}"] }
        remove_field => "message"
      }
      mutate {
        rename => { "@timestamp" => "read_timestamp" }
      }
      date {
        match => [ "[nginx][error][time]", "YYYY/MM/dd H:m:s" ]
        remove_field => "[nginx][error][time]"
      }
    }
  }
}
output {
  elasticsearch {
    hosts => your_es_ip
    manage_template => false
    index => "%{[@metadata][beat]}-%{[@metadata][version]}-%{+YYYY.MM.dd}"
  }
}

指定work配置文件,启动服务。

$ bin/logstash -f workconfig/test-nginx.conf

Logstash工作有三个阶段:inputs → filters → outputs
上面示例中的work配置,用于接收beats发来的nginx日志事件,然后进行字段处理实现关键字匹配,最后输出到ES并建立事件索引。每一个Logstash插件都足够的强大,更多细节性的插件说明请参阅官网:Input Plugins , Filter Plugins , Output Plugins , Codec Plugins.

前面我有提到说Beats数据采集层与Logstash解析层之间不需要额外的增加队列层(缓冲层),原因是因为:
假如 Logstash 节点发生故障,Logstash 会通过持久化队列来保证运行中的事件至少一次被送达(at-least-once delivery)。那些未被正常处理的消息会被送往死信队列(dead letter queue)以便做进一步处理。由于具备了这种吸收吞吐量的能力,所以现在无需采用额外的队列层,Logstash 就能平稳度过高峰期。


安装 Filebeat

## 解压即安装
$ tar xzf /opt/download/elastic/filebeat-6.2.4-linux-x86_64.tar.gz -C /opt/soft/elastic/
$ cd /opt/soft/elastic/filebeat-6.2.4-linux-x86_64/

## 配置文件
$ grep -Pv "^[ ]*#|^$" filebeat.yml 
filebeat.prospectors:
- type: log
  enabled: false
  paths:
    - /var/log/*.log
filebeat.config.modules:
  path: ${path.config}/modules.d/*.yml
  reload.enabled: true
setup.template.settings:
  index.number_of_shards: 3
output.logstash:
  hosts: ["your_logstash_ip:5044"]

使用filebeats模块功能

## 启用nginx模块
./filebeat modules enable nginx

## 模块配置
$ grep -Pv "^[ ]*#|^$" modules.d/nginx.yml 
- module: nginx
  access:
    enabled: true
    var.paths: 
      - /path/to/log/nginx/access.log*
  error:
    enabled: true
    var.paths: 
      - /path/to/log/nginx/error.log*

启动服务

$ filebeat

尾声

至此,整个配置过程完毕。

参考资料

本文链接:https://fandenggui.com/post/explor-elk.html

-- EOF --

Comments