根据官方文档以及其他资料翻译和总结而来:Getting started with the Elastic Stack

嘿,你在寻找如何快速安装和配置ELK的教程吗?来对地方了!你可以在单台虚拟机上安装ELK,甚至可以在你的笔记本上快速搭建一个学习坏境!

  • Elasticsearch
  • Kibana
  • Beats
Logstash可以提供强大的数据解析和传输功能,但不是必须安装的,如果你需要Logstash,参考:Getting Started with Logstash.

ELK介绍

你为什么需要ELK?

我们在引入一个技术栈之前,务必考虑清楚,你为什么需要这个东西,否则会给日后的维护工作埋下隐患。

日常工作中,经常有分析线上日志的需求,对于Linux老手使用grep awk这些工具就可以轻松获得想要的信息。但是这种方法仅限于规模较小的应用,一旦应用规模较大,日志往往分散在多个系统之中,排查起来就非常的困难了。

如果有这样一个系统,可以将我们所有应用的日志都集中到一起,并且进行一些加工处理,便于检索,那么问题就迎刃而解了。ELk就是目前业界主流的日志系统,它提供了一整套的技术栈,且都是同一家公司的产品,彼此间可以完美衔接。

为什么叫ELK?

ELK日志系统需要用到组件有下面这些:

  • Elasticsearch:基于Lucence的开源分布式搜索引擎,提供搜集、分析、存储数据的功能
  • Logstash:提供日志的搜集、分析、过滤功能
  • Kibana:Kibana可以为Logtash和Elasticsearch提供友好的UI界面,用于数据的可视化展示
  • Beats:

    • Packetbeat:采集网络数据
    • Metricbeat:采集系统指标,如CPU、MEM占用等
    • Filebeat:采集日志文件
    • Winlogbeat:采集Windows时间日志
    • Auditbeat:采集审计日志
    • Heartbeat:运行状态监控
由于Logstash过于笨重,Elastic家族产生了一个叫Beats的工具,用于代替Logstash Forwoarder进行轻量级的日志采集,因此Elastic也将ELK Stack改名为Elastic Stack。

Elastic Stack 单节点部署

安装前准备

需要一台安装CentOS的主机,由于Elastic是运行在JVM上的,对于内存的需求比较大,并且为了快速索引都会用到内存缓存,所以内存越大越好。

我使用的配置为:8核心处理器 16GB内存 1TB数据硬盘。

在使用Elastic Stack时,每个组件的版本必须保持一致,以获得最大的兼容性和稳定性。

本文创作时稳定版本为:7.15.0,因此每个组件的版本为:

  • Elasticsearch-7.15.0
  • Logstash-7.15.0
  • Kibana-7.15.0
  • Filebeat-7.15.0

安装组件

Elastic提供了主流操作系统的预编译包,尽量使用这些包进行快速安装,也便于后续的升级和管理。对于比较冷门的系统,才建议使用通用二进制或者源码编译的方式安装。

对于CentOS使用的RPM包管理工具,Elastic Stack提供了对应YUM源,如果服务器具有网络访问权限,建议通过添加YUM源的方式安装。如果是内网环境,可以预先下载RPM包,然后上传安装。

方式1、使用YUM源安装

导入公钥:

rpm --import https://packages.elastic.co/GPG-KEY-elasticsearch

添加仓库:

cat << EOF > /etc/yum.repos.d/elastic.repo
[elastic-7.x]
name=Elastic repository for 7.x packages
baseurl=https://artifacts.elastic.co/packages/7.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md
EOF

安装本指南中所需组件:

yum install elasticsearch kibana filebeat logstash

方式2、下载RPM包安装

下载链接:

# 证书
https://artifacts.elastic.co/GPG-KEY-elasticsearch

https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.15.0-x86_64.rpm
https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.15.0-x86_64.rpm
https://artifacts.elastic.co/downloads/kibana/kibana-7.15.0-x86_64.rpm
https://artifacts.elastic.co/downloads/logstash/logstash-7.15.0-x86_64.rpm

安装:

# 导入证书
rpm --import GPG-KEY-elasticsearch

rpm -ivh elasticsearch-7.15.0-x86_64.rpm
rpm -ivh filebeat-7.15.0-x86_64.rpm
rpm -ivh kibana-7.15.0-x86_64.rpm
rpm -ivh logstash-7.15.0-x86_64.rpm

配置Elasticsearch

配置文件目录:/etc/elasticsearch

配置完成后的有效配置:

grep -Ev '^$|^#' /etc/elasticsearch/elasticsearch.yml
cluster.name: ELK-Cluster
node.name: node-standalone
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
network.host: 172.16.243.160
http.port: 9200
discovery.type: single-node

network.host,Elasticsearch默认只能使用localhost进行访问,如果需要在其他主机上向Elasticsearch发送数据,需要修改绑定地址,一般配置为所使用网卡的IP,也可以配置成0.0.0.0绑定所有接口。

discovery.type,需要自己添加到配置文件中,设置为single-node可以避免Elasticsearch扫描网络中的其他节点。

path.datapath.logs,这两个参数需要注意,根据Elasticsearch数据量考虑,配置到容量足够的目录。

启动Elasticsearch并且配置自动运行:

systemctl enable --now elasticsearch

测试Elasticsearch:

curl http://localhost:9200

如果看到类似下面的返回结果就说明成功了。

{
  "name" : "node-standalone",
  "cluster_name" : "ELK-Cluster",
  "cluster_uuid" : "Y00Y4qzbQAqqbuVQjsCMGQ",
  "version" : {
    "number" : "7.15.0",
    "build_flavor" : "default",
    "build_type" : "rpm",
    "build_hash" : "79d65f6e357953a5b3cbcc5e2c7c21073d89aa29",
    "build_date" : "2021-09-16T03:05:29.143308416Z",
    "build_snapshot" : false,
    "lucene_version" : "8.9.0",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}

配置Kibana

配置文件目录:/etc/kibana

配置完成后的有效配置:

grep -Ev '^$|^#' /etc/kibana/kibana.yml
server.port: 5601
server.host: "172.16.243.160"
server.basePath: "/"
server.publicBaseUrl: "http://172.16.243.160:5601/"
server.name: "ELK Stack"
elasticsearch.hosts: ["http://172.16.243.160:9200"]
i18n.locale: "zh-CN"

server.host,Kibana默认也是只能通过localhost访问,需要配置成具体接口IP或者是0.0.0.0绑定所有接口。

server.basePathserver.publicBaseUrl,用于配置对外访问地址,如果不配置页面会有警告信息,最好配置一下。publicBaseUrlbasePath保持一致,也可以添加前缀用于反向代理,例如:

server.basePath: "/elk/"
server.publicBaseUrl: "http://172.16.243.160:5601/elk/"

启动Kibana并且配置自动运行:

systemctl enable --now kibana

使用浏览器访问,例如:http://172.16.243.160:5601

配置FileBeat

配置文件目录:/etc/filebeat

配置完成后的有效配置:

grep -Ev '^$|#|^#' /etc/filebeat/filebeat.yml
filebeat.inputs:
- type: log
  enabled: false
  paths:
    - /var/log/*.log
- type: filestream
  enabled: false
  paths:
    - /var/log/*.log
filebeat.config.modules:
  path: ${path.config}/modules.d/*.yml
  reload.enabled: false
setup.template.settings:
  index.number_of_shards: 1
setup.kibana:
  host: "172.16.243.160:5601"
output.elasticsearch:
  hosts: ["172.16.243.160:9200"]
processors:
  - add_host_metadata:
      when.not.contains.tags: forwarded
  - add_cloud_metadata: ~
  - add_docker_metadata: ~
  - add_kubernetes_metadata: ~

setup.kibana.host,用于载入仪表盘,可以不配置。

filebeat.inputs中启用了log类型的采集器,采集/var/log/*.log目录下的所有日志文件,这里主要用于测试目的,可以根据实际需要配置你想要采集的日志目录。

filebeat还附带了一些集成的模块,这些模块会根据当前操作系统,寻找默认的日志目录进行采集,下面看一个简单的示例:

查看可用的模块:

filebeat modules list

启用nginx模块:

filebeat modules enable nginx

模块的配置信息在/etc/filebeat/modules.d目录下,启用模块实质是就是将文件后缀.disabled移除,可以根据需要修改这些模块,或者添加自己的模块。我们查看nginx模块默认的采集目录。

- module: nginx
  access:
    var.paths: ["/var/log/nginx/access.log*"] 
查看所有的模块使用方法:Modules

启动Filebeat并且配置为自动运行:

systemctl enable --now filebeat

打开Kibana页面,点击Discover,选择filebeat-*索引,查看是否有数据,如果看不到数据,将时间范围设置大一点。

配置Metricbeat

curl -L -O https://artifacts.elastic.co/downloads/beats/metricbeat/metricbeat-7.15.0-x86_64.rpm
rpm -ivh metricbeat-7.15.0-x86_64.rpm

Metricbeat提供了一些预装的模块,快速实现系统的监控。

启用system模块:

metricbeat modules enable system

设置初始化环境:

metricbeat setup -e

setup命令加载Kibana的仪表盘,如果已经加载过了,忽略这条命令。-e参数是可选的,作用是将日志输出到标准输出而不是系统日志。

如果修改了kibana的绑定地址,需要修改配置文件:

metricbeat.yml

setup.kibana.host: "http://localhost:5601"

启动Metricbeat

systemctl enable --now metricbeat

kibana可视化展示系统指标

打开浏览器,访问:http://localhost:5601/app/kibana#/dashboard/Metricbeat-system-overview-ecs

如果在Kibana中看不到数据,可以尝试将日期范围设置大一点,Kibana默认展示过去15分钟的数据。如果出现错误信息,请确保Metricbeat服务正常运行,然后刷新页面。

配置Logstash

Filebeat收集的日志非常原始和杂乱。必要时可以添加Logstash进行处理然后发送给Elasticsearch存储。

配置文件目录:/etc/logstash

复制一份logstash-smaple.conf到conf.d`目录,根据需要重新命名,配置完成后如下:

input {
  beats {
    port => 5044
  }
}

output {
  stdout { codec => rubydebug }
}

这是一个简单的Beats -> Logstash -> Elasticsearch流水线,监听在5044端口,我们将原本输出到Elasticsearch改为输出到标准输出,便于调试。

修改Filebeat配置文件,将原来的直接输出到Elasticsearch改为将数据输出到Logstash。

output.logstash:
  hosts: ["172.16.243.160:5044"]

测试Logstash

/usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/test.conf --config.test_and_exit

重启Filebeat,启动Logstash:

systemctl restart filebeat
/usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/test.conf

如果一切正常将会在标准输出上看到JSON格式的日志信息。

一切都正常将Logstash的输出改回Elasticsearch:

input {
  beats {
    port => 5044
  }
}

output {
  elasticsearch {
    hosts => ["http://localhost:9200"]
    index => "%{[@metadata][beat]}-%{[@metadata][version]}-%{+YYYY.MM.dd}"
  }
}

不要忘了重启一下。

使用Grok插件过滤Web日志

Grok是Logstash自带的几个插件之一,可以用来对非结构化的数据进行处理,比如将日志解析成Json格式。

Grok是通过正则表达式来匹配日志内容的,为了便于使用,Grok提供了一些内置的模式,例如INT模式对应的正则表达式为(?:[+-]?(?:[0-9]+)),使用这些模式可以帮助我们快速解析日志,并且增强可读性。

Grok的语法:

%{SYNTAX:SEMANTIC}

SYNTAX表示要匹配的内容,SEMANTIC表示匹配成功后存储的字段名称。

除了使用内置的模式,还可以自定义模式:

(?<field_name>the pattern here)
(?<userName>[a-zA-Z]{3,5}) 3-5位字母的用户名

在线调试表达式:https://grokdebug.herokuapp.com/

通过一个例子来看一下如何使用Grok进行数据过滤,首先准备测试数据。

2021-10-10 11:57:16.825 [http-nio-10002-exec-10] DEBUG c.c.f.s.f.UsernamePasswordFilter - request failed: com.demo.authentication.BadCredentialsException: 用户名或密码错误
  at com.demo.authenticate(AuthenticationProvider.java:151)

对应的匹配模式:

(?m)%{TIMESTAMP_ISO8601:createTime} \[%{DATA:threadName}\] %{LOGLEVEL:LEVEL} %{JAVACLASS:javaClass} - %{GREEDYDATA:msg}

解析成功的数据格式:

{
  "createTime": [
    [
      "2021-10-10 11:57:16.825"
    ]
  ],
  "YEAR": [
    [
      "2021"
    ]
  ],
  "MONTHNUM": [
    [
      "10"
    ]
  ],
  "MONTHDAY": [
    [
      "10"
    ]
  ],
  "HOUR": [
    [
      "11",
      null
    ]
  ],
  "MINUTE": [
    [
      "57",
      null
    ]
  ],
  "SECOND": [
    [
      "16.825"
    ]
  ],
  "ISO8601_TIMEZONE": [
    [
      null
    ]
  ],
  "threadName": [
    [
      "http-nio-10002-exec-10"
    ]
  ],
  "LEVEL": [
    [
      "DEBUG"
    ]
  ],
  "javaClass": [
    [
      "c.c.f.s.f.UsernamePasswordFilter"
    ]
  ],
  "msg": [
    [
      "request failed: com.demo.authentication.BadCredentialsException: 用户名或密码错误\n  at com.demo.authenticate(AuthenticationProvider.java:151)"
    ]
  ]
}
在这里栽了跟头,打印日志的时候,有些地方多了一个少了一个空格,导致解析不出来,建议空格用%{SPACE}代替。

配置过滤器

input {
  beats {
    port => 5044
    type => "kube-log"
  }
}

filter {
  match => { "message" => "(?m)%{TIMESTAMP_ISO8601:createTime} \[%{DATA:threadName}\] %{LOGLEVEL:LEVEL} %{JAVACLASS:javaClass} - %{GREEDYDATA:msg}" }
  remove_field => ["message"]
}

output {
  elasticsearch {
    hosts => ["http://localhost:9200"]
    index => "%{[@metadata][beat]}-%{[@metadata][version]}-%{+YYYY.MM.dd}"
  }
}

message解析完成后,就没有必要了,所以移除,节省空间。

Elastic安全性配置

在浏览服务器指标仪表盘时,会弹出安全警告,因为我们没有配置Elastic安全访问。

Elastic提供了三种级别的安全配置:

  • 最低安全性(开发)
  • 普通安全性(生产)
  • 增强安全性(在普通安全性基础上增加TLS加密)

最低安全性配置

开启安全功能

首先启用Elastic安全功能,然后为内置用户设置密码,在这之后你也可以添加更多的用户。

要求:

  • 安装配置好Elasticsearch和Kibana
  • 使用的许可证包含所需的安全功能

/etc/elasticsearch/elasticsearch.yml配置文件添加:

xpack.security.enabled: true
为系统内建用户创建密码

为了与集群通信,你必须给内建的用户配置密码,除非你启用匿名访问,否则任何不包含用户名和密码的请求都会被拒绝。

使用最低安全性或者普通安全性时,你只需要设置elastic和kibana_system用户的密码。

在每个节点上,启动Elasticsearch,在安装目录找到elasticsearch-setup-passwords,使用PRM包安装的话,在/usr/share/elasticsearch/bin/elasticsearch-setup-passwords

使用auto参数随机生成密码,如果有必要可以稍后再修改。

/usr/share/elasticsearch/bin/elasticsearch-setup-passwords auto

如果你想自己设置密码,使用interactive参数替代auto参数,这个模式会逐步为每个内建用户设置密码。

/usr/share/elasticsearch/bin/elasticsearch-setup-passwords interactive
配置Kibina使用密码连接Elasticsearch

编辑配置文件${KIB_PATH_CONF}/kibana.yml

elasticsearch.username: "kibana_system"

也许你注意到了,配置文件中也可以设置密码,但是明文的密码不具备安全性,可以通过密钥库的方式存储密码。

在Kibana安装目录找到kibana-keystore,对于RPM安装,在/usr/share/kibana/bin/kibana-keystore

创建密钥库:

/usr/share/kibana/bin/kibana-keystore create

向密钥库中添加kibana_system用户的密码:

/usr/share/kibana/bin/kibana-keystore add elasticsearch.password

当提示出现时,输入kibana_system用户的密码。

Filebeat也需要添加,和Kibbana类似,不载赘述。

最后重启Kibina,然后通过浏览器访问,使用elastic用户登录,创建其他用户和角色,对于单节点模式的话,到这里就可以结束了。

其他安全性配置

对于单节点,不需要配置,以后有需要再来补充。

最后修改:2023 年 08 月 02 日
如果觉得我的文章对你有用,请随意赞赏