ELK专题:Day1——最小化搭建ELK集群,采集Nginx日志

1,212 阅读10分钟

1. 前言

ELK作为一套广泛使用的日志检索平台已经发展了好些年,并且是业界的主流解决方案之一。但是因为ELK集群里面涉及到多个不同的服务,对新手来说上手比较困难,所以我写了这个教程,希望能通过这个教程给新手完成一个从0到1的突破,用最简的配置和最小化的部署方案先搭建出一套能用的环境。同时在这个过程中也可以让新手逐渐对ELK技术栈建立起一个初步的认识,在迷雾中找到一个方向。

2. 实验环境简介

2.1 架构图

diragram.png

2.2 集群版本信息

  • 操作系统版本:Ubuntu 20.04.2 LTS (GNU/Linux 5.4.0-80-generic x86_64)
  • Elasticsearch版本:7.13.4
  • Logstash版本:7.14
  • Kibana版本:7.14
  • Filebeat版本:7.14

2.3 方案概述

  1. Nginx服务器产生的访问日志会通过Filebeat传送到Logstash。
  2. 在Logstash的配置文件中定义对采集到的日志的操作,最后归档到ES。
  3. 用户通过浏览器进入Kibana,读取ES里面的数据。
  4. 所有服务器网络互通,位于同一个子网。

2.4 实验目标

  1. Nginx、Filebeat、Logstash、ES、Kibana各个服务都正常运行。
  2. 各个服务都能按照最基本的需求完成既定任务。
  3. 在Kibana可以正常访问和检索日志。

3. 环境搭建步骤

3.1 Nginx 部署

本测试环境使用本Hexo网站的测试环境,Nginx服务的搭建比较简单,暂不作详细描述。

3.2 ElasticSearch 服务搭建

根据各个服务之间的依赖关系,我们首先安装不需要依赖其他服务的ES。这也是很多时候在搭建集群时候的习惯做法,先从数据库开始。

在本文中,我们使用Ubuntu自带的apt包管理工具安装ES。

3.2.1 安装Elasticsearch

官方文档:www.elastic.co/guide/en/el…

# 方法1,使用APT在线安装

# 下载安装Elasticsearch仓库的PGP Key
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -

sudo apt-get install apt-transport-https

# 把elasticsearch的仓库地址信息加入到apt工具的配置文件中
echo "deb https://artifacts.elastic.co/packages/7.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-7.x.list

# 安装elasticsearch,在本文中,安装的是7.13.4版本
sudo apt-get update && sudo apt-get install elasticsearch


# 方法2,使用deb包安装

wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.13.4-amd64.deb
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.13.4-amd64.deb.sha512

# 校验文件完整性
shasum -a 512 -c elasticsearch-7.13.4-amd64.deb.sha512 

#安装
sudo dpkg -i elasticsearch-7.13.4-amd64.deb
2.2.2 配置Elasticsearch

使用安装包安装完成后,默认的配置文件存放在/etc/elasticsearch,在本例中,按照最简化部署,我们只调整/etc/elasticsearch/elasticsearch.yml,配置范例如下:

cluster.name: rc-application
node.name: node-rc-1
path.data: /data/elasticsearch
path.logs: /var/log/elasticsearch
network.host: 192.168.0.212
http.port: 9200
cluster.initial_master_nodes: ["node-rc-1"]
3.2.3 启动Elasticsearch

在本例的Ubuntu发行版中,安装完成之后会自动创建systemd启动项目,相关操作如下:

# 设置开机启动
sudo /bin/systemctl daemon-reload
sudo /bin/systemctl enable elasticsearch.service

# start/stop/restart 操作和其他的系统服务一样操作
sudo systemctl start elasticsearch.service
sudo systemctl stop elasticsearch.service
sudo systemctl restart elasticsearch.service
2.2.4 验证Elasticsearch是否正常
  • 查看服务状态

    root@ES:~# systemctl status elasticsearch.service 
    ● elasticsearch.service - Elasticsearch
         Loaded: loaded (/lib/systemd/system/elasticsearch.service; disabled; vendor preset: enabled)
         Active: active (running) since Tue 2021-08-03 08:07:57 UTC; 25min ago
           Docs: https://www.elastic.co
       Main PID: 10100 (java)
          Tasks: 61 (limit: 9448)
         Memory: 4.2G
         CGroup: /system.slice/elasticsearch.service
                 ├─10100 /usr/share/elasticsearch/jdk/bin/java -Xshare:auto -Des.networkaddress.cache.ttl=60 -Des.ne>
                 └─10303 /usr/share/elasticsearch/modules/x-pack-ml/platform/linux-x86_64/bin/controller
    
    Aug 03 08:07:25 ES systemd[1]: Starting Elasticsearch...
    Aug 03 08:07:57 ES systemd[1]: Started Elasticsearch.
    
  • 查看端口占用,ES默认使用9200端口

    root@ES:~# netstat -tunpl | grep 9200
    tcp6       0      0 192.168.0.212:9200      :::*                    LISTEN      10100/java    
    
  • 请求ES服务,直接通过curl命令请求ES服务的根目录,可以查看ES状态

    root@ES:~# curl http://192.168.0.212:9200
    {
      "name" : "node-rc-1",
      "cluster_name" : "rc-application",
      "cluster_uuid" : "y_q0vv9vQ3K7ukSdl0fO7g",
      "version" : {
        "number" : "7.13.4",
        "build_flavor" : "default",
        "build_type" : "deb",
        "build_hash" : "c5f60e894ca0c61cdbae4f5a686d9f08bcefc942",
        "build_date" : "2021-07-14T18:33:36.673943207Z",
        "build_snapshot" : false,
        "lucene_version" : "8.8.2",
        "minimum_wire_compatibility_version" : "6.8.0",
        "minimum_index_compatibility_version" : "6.0.0-beta1"
      },
      "tagline" : "You Know, for Search"
    }
    

3.3 安装Kibana

和Elasticsearch类似,我们继续使用官方提供的软件包进行安装。

3.3.1 安装过程

官方文档:www.elastic.co/guide/en/ki…

wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
sudo apt-get install apt-transport-https
echo "deb https://artifacts.elastic.co/packages/7.x/apt stable main" | sudo tee -a /etc/apt/sources.list.d/elastic-7.x.list
sudo apt-get update && sudo apt-get install kibana
3.3.2 Kibana配置文件/etc/kibana/kibana.yml

配置示例如下:

server.port: 5601
server.host: "192.168.0.213"
server.name: "my-kibana"
elasticsearch.hosts: "http://192.168.0.212:9200"	# 上文中的elasticsearch地址
logging.dest: /var/log/kibana/kibana.log
logging.verbose: false
3.3.3 启动kibana
root@Kibana:/etc/kibana# systemctl start kibana.service 
root@Kibana:/etc/kibana# systemctl status kibana.service 
● kibana.service - Kibana
     Loaded: loaded (/etc/systemd/system/kibana.service; disabled; vendor preset: enabled)
     Active: active (running) since Tue 2021-08-03 08:49:27 UTC; 3s ago
       Docs: https://www.elastic.co
   Main PID: 9978 (node)
      Tasks: 18 (limit: 9448)
     Memory: 147.8M
     CGroup: /system.slice/kibana.service
             ├─9978 /usr/share/kibana/bin/../node/bin/node /usr/share/kibana/bin/../src/cli/dist --logging.dest=>
             └─9996 /usr/share/kibana/node/bin/node --preserve-symlinks-main --preserve-symlinks /usr/share/kiba>

Aug 03 08:49:27 Kibana systemd[1]: Started Kibana.
3.3.4 验证kibana

使用浏览器,进入kibana地址http://192.168.0.213:5601,如果页面可正常打开,则服务正常。

kibana.png

3.4 Logstash服务搭建

在ELK集群的调试中,我认为Logstash是最难的一个了,我们一步一步来。

3.4.1 安装Logstash

根据官方文档指引,使用apt安装

官方文档:www.elastic.co/guide/en/lo…

wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
sudo apt-get install apt-transport-https
echo "deb https://artifacts.elastic.co/packages/7.x/apt stable main" | sudo tee -a /etc/apt/sources.list.d/elastic-7.x.list
sudo apt-get update && sudo apt-get install logstash
3.4.2 配置Logstash

官方文档:www.elastic.co/guide/en/lo…

3.4.2.1 Logstash服务配置 /etc/logstash/logstash.yml

以下是配置范例:

path.data: /data/logstash	# 需要提前确认路径存在,并且检查权限,允许logstash用户读写
pipeline.workers: 2
pipeline.batch.size: 125
path.config: /etc/logstash/conf.d/*.conf	# 这是logstash的默认配置,在这里显式配置
path.settings: /etc/logstash				# 这是logstash的默认配置,在这里显式配置
config.test_and_exit: false
http.host: 192.168.0.211
http.port: 9600-9700
log.level: debug
path.logs: /var/log/logstash
3.4.2.2 Logstash管道配置 /etc/logstash/conf.d/test.conf

我们先使用简单的配置,测试Logstash能否正常把内容推送到ES。

input { stdin { } }

output {
  elasticsearch { hosts => ["192.168.0.212:9200"] }
  stdout { codec => rubydebug }
}
3.4.3 启动并测试Logstash
  1. 用命令行方式启动logstash

    /usr/share/logstash/bin/logstash  -f /etc/logstash/conf.d/test.conf 
    
  2. 通过stdin输入,观察logstash。如输入:“this is a test”,会有如下输出:

    {
        "@timestamp" => 2021-08-03T10:33:10.584Z,
          "@version" => "1",
           "message" => "this is a test",
              "host" => "Logstash"
    }
    
  3. 进入ES查看内容,可以发现ES已把测试信息入库

    # 查看es索引
    curl -s "192.168.0.212:9200/_cat/indices?v"
    health status index                           uuid                   pri rep docs.count docs.deleted store.size pri.store.size
    yellow open   logstash-2021.08.03-000001      YIqdbC81Tq2zIulxfFUI4w   1   1          3            0     13.4kb         13.4kb
    green  open   .apm-custom-link                NnAWZ3THRWiHqJf2_B830Q   1   0          0            0       208b           208b
    green  open   .apm-agent-configuration        YOjjGNX9SaacWHnJshD6Sw   1   0          0            0       208b           208b
    green  open   .kibana-event-log-7.13.4-000001 _UADZI-GSBmRc9inJd1eJg   1   0          1            0      5.6kb          5.6kb
    green  open   .kibana_7.13.4_001              LXjP8PPnRrSDeO8-1APE7A   1   0         18            0      2.1mb          2.1mb
    green  open   .kibana_task_manager_7.13.4_001 yotlqk02SH6P6xISCZZw-g   1   0         10         2062    270.3kb        270.3kb
    
    # 发现有一个新索引logstash-2021.08.03-000001,查看新索引的内容
    curl -XGET '192.168.0.212:9200/logstash-2021.08.03-000001/_doc/_search/?pretty'
    {
      "took" : 5,
      "timed_out" : false,
      "_shards" : {
        "total" : 1,
        "successful" : 1,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : {
          "value" : 3,
          "relation" : "eq"
        },
        "max_score" : 1.0,
        "hits" : [
          {
            "_index" : "logstash-2021.08.03-000001",
            "_type" : "_doc",
            "_id" : "5_yTC3sB-S8uwXpkCUFc",
            "_score" : 1.0,
            "_source" : {
              "@timestamp" : "2021-08-03T10:33:10.584Z",
              "@version" : "1",
              "message" : "this is a test",
              "host" : "Logstash"
            }
          }
         }
        ]
      }
    }
    
  4. 确认Logstash可以正常运行之后,我们可以ctrl+c退出Logstash进程,后面会和Filebeat进行联调。

3.5 为Nginx服务器安装Filebeat

经过上面的步骤,我们已经完成了ELK(Elasticsearch - Logstash - Kibana)的部署,但在常见的技术实践中,因为Logstash需要依赖Java环境才能运行,往往不会直接安装到业务机上。在主流的解决方案中,会在业务机上安装filebeat进行日志传输。

3.5.1 安装Filebeat

官方文档:www.elastic.co/guide/en/be…

curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.13.4-amd64.deb
sudo dpkg -i filebeat-7.13.4-amd64.deb

# 安装完成后,会自动创建systemctl项目
root@hexo:/tmp# systemctl status filebeat
● filebeat.service - Filebeat sends log files to Logstash or directly to Elasticsearch.
     Loaded: loaded (/lib/systemd/system/filebeat.service; disabled; vendor preset: enabled)
     Active: inactive (dead)
       Docs: https://www.elastic.co/beats/filebeat
3.5.2 配置Filebeat

以采集nginx access.log为例, ,我们使用的配置范例如下:

# /etc/filebeat/filebeat.yml

# 配置filebeat自身的运行日志输出
logging.level: info
logging.to_files: true
logging.files:
  path: /var/log/filebeat
  name: filebeat
  keepfiles: 7
  
# filebeat对日志的采集和输出配置
filebeat.inputs:
- type: log
  enabled: true
  paths:
   - /var/log/nginx/hexo_access.log

setup.template.settings:
  index.number_of_shards: 1

output.logstash:
  # 这里输入的是logstash的地址和端口,后面我们会对logstash进行联调
  hosts: ["192.168.0.211:5400"]
3.5.3 Filebeat启动

使用命令systemctl start filebeat.service即可启动filebeat,但目前filebeat与logstash之间的联调还没完成,所以filebeat会有报错,我们会在后面解决这个问题。

2021-08-03T22:12:45.795+0800    ERROR   [publisher_pipeline_output]     pipeline/output.go:154  Failed to connect to backoff(async(tcp://192.168.0.211:5400)): dial tcp 192.168.0.211:5400: connect: connection refused

4. 联调

经过了上面的步骤,我们已经完成了ELK + Filebeat + Nginx 典型业务集群的搭建。下面,我们需要继续进行具体的联调,让ELK发挥作用,实现日志检索和统计的功能。

4.1 filebeat与logstash的联调

从架构图可以看到,Filebeat会把日志传送到Logstash,Logstash再把日志传到ES,我们重点调整一下Logstash。

4.1.1 logstash配置修改
  1. 先把前面用于测试的配置/etc/logstash/conf.d/test.conf删除。

  2. 创建新的测试配置/etc/logstash/conf.d/nginx-es.conf

    input {
            beats {
                    host => "0.0.0.0"
                    port => 5400	# 对应在filebeat的配置中,output到logstash的5400端口
            }
    }
    
    output {
            elasticsearch { 
                    hosts => ["192.168.0.212:9200"] 
                    index => "rc_index_pattern-%{+YYYY.MM.dd}"
            }
    }
    
  3. 使用命令systemctl start logstash.service启动logstash服务。

4.1.2 验证现象
  1. 使用浏览器访问Nginx服务,使access_log产生内容。

  2. filebeat日志/var/log/filebeat/filebeat产生内容如下:

    2021-08-06T16:56:02.801+0800    INFO    [registrar]     registrar/registrar.go:109      States Loaded from registrar: 1
    2021-08-06T16:56:02.801+0800    INFO    [crawler]       beater/crawler.go:71    Loading Inputs: 1
    2021-08-06T16:56:02.802+0800    INFO    log/input.go:157        Configured paths: [/var/log/nginx/hexo_access.log]
    2021-08-06T16:56:02.802+0800    INFO    [crawler]       beater/crawler.go:141   Starting input (ID: 16452737213288841630)
    2021-08-06T16:56:02.802+0800    INFO    [crawler]       beater/crawler.go:108   Loading and starting Inputs completed. Enabled inputs: 1
    2021-08-06T16:56:02.802+0800    INFO    log/harvester.go:302    Harvester started for file: /var/log/nginx/hexo_access.log
    2021-08-06T16:56:03.803+0800    INFO    [publisher_pipeline_output]     pipeline/output.go:143  Connecting to backoff(async(tcp://192.168.0.211:5400))
    2021-08-06T16:56:03.803+0800    INFO    [publisher]     pipeline/retry.go:219   retryer: send unwait signal to consumer
    2021-08-06T16:56:03.803+0800    INFO    [publisher]     pipeline/retry.go:223     done
    2021-08-06T16:56:03.803+0800    INFO    [publisher_pipeline_output]     pipeline/output.go:151  Connection to backoff(async(tcp://192.168.0.211:5400)) established
    

    /var/log/nginx/hexo_access.log的日志已经成功推送到logstash。

  3. 检查ES内容,发现ES已自动创建索引rc_index_pattern-2021.08.06并且已经有Nginx日志内容

    curl -XGET '192.168.0.212:9200/rc_index_pattern-2021.08.06/_doc/_search/?pretty'
    rondo@ES:~$ curl -XGET '192.168.0.212:9200/rc_index_pattern-2021.08.06/_doc/_search/?pretty'
    {
      "took" : 728,
      "timed_out" : false,
      "_shards" : {
        "total" : 1,
        "successful" : 1,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : {
          "value" : 76,
          "relation" : "eq"
        },
        "max_score" : 1.0,
        "hits" : [
          {
            "_index" : "rc_index_pattern-2021.08.06",
            "_type" : "_doc",
            "_id" : "0_ynGnsB-S8uwXpkwkJF",
            "_score" : 1.0,
            "_source" : {
              "host" : {
                "name" : "hexo"
              },
              "@timestamp" : "2021-08-06T08:50:04.192Z",
              "input" : {
                "type" : "log"
              },
              "tags" : [
                "beats_input_codec_plain_applied"
              ],
              "message" : "202.105.107.186 - - [06/Aug/2021:16:49:57 +0800] \"GET /css/main.css HTTP/1.1\" 200 56117 \"http://192.168.0.125:80/\" \"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36\"",
              "@version" : "1",
              "log" : {
                "offset" : 197,
                "file" : {
                  "path" : "/var/log/nginx/hexo_access.log"
                }
              },
              "agent" : {
                "id" : "d2f43da1-5024-4000-9251-0bcc8fc10697",
                "type" : "filebeat",
                "version" : "7.13.4",
                "hostname" : "hexo",
                "ephemeral_id" : "77089197-d22d-497f-a064-76fbb2e369b3",
                "name" : "hexo"
              },
              "ecs" : {
                "version" : "1.8.0"
              }
            }
          },
    ......
    

4.2 Kibana设置

  1. 点击页面左上角的图标,在弹出菜单中点击底部的Stack Management

    kibana-1.PNG

  2. Index Patterns菜单中点击Create index pattern

    kibana-2.PNG

  3. 页面会显示已有的index,在输入框中输入需要的pattern,匹配你想要的index,点击Next step

    kibana-3.PNG

  4. 设置index使用的时间戳,创建index pattern。

    kibana-4.PNG

    kibana-5.PNG

  5. 完成index pattern创建后,点击左上角菜单栏,进入Discover

    kibana-6.PNG

  6. 在页面左上角选择适当的时间范围,就可以查看索引内容了。

    kibana-7.PNG

  7. 点击每条消息左侧的>按钮,可以查看消息详情,里面会包含Nginx日志的详情。

    kibana-8.PNG

5. 总结

经过前面一系列的操作,我们得到了一个ELK集群,并模拟了实际生产的场景,展示了从业务日志(nginx)产生到入库ES的过程,形成了一个日志平台的闭环。但这个只是雏形,后面我们会对这个集群不断进行优化,过程中会涉及到各个服务的配置优化和横向扩容等场景,我们拭目以待。

原文网址:ELK专题:Day1——最小化搭建ELK集群,采集Nginx日志