Skip to content

Latest commit

 

History

History
947 lines (683 loc) · 42.3 KB

File metadata and controls

947 lines (683 loc) · 42.3 KB

十二、使用 Elasticsearch、Logstash 和 Kibana 管理日志

部署 ElasticsearchLogstashKibana ( ELK Stack )相对简单,但是在安装这些组件时需要考虑几个因素。虽然这不是对弹性栈的深入指导,但主要的要点将是实现方面、通过流程做出的决策,以及作为架构师,您在做出这些决策时应该如何思考。

作为架构师,本章将帮助您定义部署 ELK 栈所需的方面,以及在使用组成弹性栈的组件时使用什么配置。

在本章中,我们将讨论以下主题:

  • 安装和配置 Elasticsearch
  • 安装和配置 Logstash 和 Kibana
  • 安装和解释 Beats
  • 配置 Kibana 仪表板

技术要求

本章将使用以下工具和安装:

部署概述

对于这个部署,我们将使用 Elasticsearch 版本(这是编写本文时的最新版本)。这意味着所有后续组件必须是相同的版本。基本操作系统将是 CentOS 7.6。虽然这一具体部署将在本地虚拟机 ( 虚拟机)设置上实施,但这些概念仍然可以应用于云。

Elasticsearch 将使用 2 个节点部署在 2 个 vCPU 虚拟机上,每个虚拟机具有 4 GB 内存(在第 11 章设计 ELK 栈中,我们确定所需的最小内存约为 2.5 GB)。虚拟机的底层存储是非易失性快速内存 ( NVMe ),因此在其他地方复制设置时需要考虑一些事项。在空间方面,Elasticsearch 节点将各有 64 GB 的磁盘空间;节点将把 64 GB 的磁盘装入/var/lib/elasticsearch目录。

Logstash 和 Kibana 将使用 2 个 vCPUs 和 4 GB 内存部署在同一个虚拟机上。正如在第 11 章设计 ELK 栈中看到的,Logstash 对队列的持久存储有要求。为此,我们将使用 32 GB 的专用磁盘。该磁盘将被装入/var/lib/logstash目录,用于持久排队。

我们可以将用于部署的内容总结如下:

  • 基本操作系统是 CentOS 7.6
  • Elasticsearch v6.5
  • log tash v 6.5
  • 没有 v6.5
  • 使用 2 个虚拟机管理程序虚拟机上的 2 个节点进行 Elasticsearch,内存为 4 GB
  • 在单个虚拟机上使用 2 个虚拟机管理程序和 4 GB 内存来记录存储和基巴纳
  • Elasticsearch 节点的 64 GB 磁盘
  • 用于 Logstash 持久队列的 32 GB 磁盘

下图说明了整个实现,并让您了解事物是如何联系在一起的:

安装 Elasticsearch

从一无所有到功能性 Elasticsearch 设置需要安装软件;这可以通过几种方式在不同的平台上完成。其中一些安装选项如下:

  • 从源安装
  • 为基于 Debian 的 Linux 发行版安装deb
  • 安装红帽企业 Linux ( RHEL )、CentOS、嵌入式系统函数库 ( SLES )、OpenSLES 和基于 RPM 的发行版
  • 安装车窗msi
  • 部署 Docker 映像

在这个设置中,我们将使用 RPM 存储库来保持不同版本之间的一致性,并在有更新时进行简化。

转速存储库

要为 RHEL 和 CentOS 安装 RPM 存储库,我们需要在/etc/yum.repos.d目录中创建一个文件。在这里,文件名并不重要,但实际上,它需要有意义。文件内容表明yum将如何去搜索软件。

创建一个名为/etc/yum.repos.d/elastic.repo的文件,其代码如下:

[elasticsearch-6.x]
name=Elasticsearch repository for 6.x packages
baseurl=https://artifacts.elastic.co/packages/6.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md

创建存储库文件后,只需运行以下命令:

yum makecache

这将刷新所有已配置存储库的元数据。在安装 Elasticsearch 之前,我们需要安装 OpenJDK 版本,1.8.0;为此,我们可以运行以下命令:

yum install java-1.8.0-openjdk

接下来,确认java已安装,如下:

java -version

然后,您应该会看到类似于以下输出的内容:

[root@elastic1 ~]# java -version
openjdk version "1.8.0_191"
OpenJDK Runtime Environment (build 1.8.0_191-b12)
OpenJDK 64-Bit Server VM (build 25.191-b12, mixed mode)

然后我们可以继续安装elasticsearch,如下所示:

yum install elasticsearch

Before starting Elasticsearch, some configuration needs to be done.

Elasticsearch 数据目录

Elasticsearch 的默认配置将数据目录设置为/var/lib/elasticsearch路径。这是通过/etc/elasticsearch/elasticsearch.yml文件中的path.data配置选项控制的:

# ---------------------------------Paths-------------------------------
#
# Path to directory where to store the data (separate multiple locations by comma):
#
path.data: /var/lib/elasticsearch

在此设置中,64 GB 磁盘将装载到此位置。

When deploying in Azure, make sure that the path.data option is configured to use a data disk rather than the OS disk.

对磁盘进行分区

在创建文件系统之前,需要对磁盘进行分区。为此,我们可以使用parted实用程序。

首先,我们需要将磁盘初始化为gpt;为此,我们可以使用以下命令:

sudo parted /dev/sdX mklabel gpt

然后,我们创建分区:

sudo parted /dev/sdX mkpart xfs 0GB 64GB

这里,我们告诉parted创建一个从0GB64GB的分区,或者从磁盘的开始到结束。此外,我们使用xfs签名,因为这是将用于数据目录的文件系统。

最后,我们通过运行以下命令来验证分区是否已成功创建并具有正确的边界:

sudo parted /dev/sdX print

输出应该类似于以下代码块:

[root@elastic1 ~]# parted /dev/sdb print
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sdb: 68.7GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number  Start End     Size    File system  Name Flags
1      1049kB  64.0GB 64.0GB               xfs

格式化文件系统

为了能够在新创建的分区上存储数据,我们首先需要创建一个文件系统。对于这个设置,我们将使用 XFS 文件系统。

要格式化磁盘,运行mkfs.xfs命令,如下所示:

[root@elastic1]# mkfs.xfs /dev/sdb1
meta-data=/dev/sdb1              isize=512    agcount=4, agsize=3906176 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=0, sparse=0
data     =                       bsize=4096   blocks=15624704, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal log           bsize=4096   blocks=7629, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0

默认情况下,XFS 使用与内存页面大小匹配的 4K 块大小;这也非常适合相对较小的文件。

Note that the partition of the device file is specified rather than the entire disk. While it is possible to use the disk itself, it is recommended that you create filesystems on partitions. Additionally, if the filesystem is going to be used on a RAID setup, then changing the stripe unit and stripe size generally helps with performance.

使用 fstab 持久安装

现在已经创建了文件系统,我们需要确保它在每次重新启动后都装载在正确的位置。

一般来说,不建议使用设备文件挂载文件系统,尤其是在云中。这是因为磁盘顺序可能会改变,导致磁盘的设备文件混合在一起。为了解决这个问题,我们可以使用磁盘的 UUID,这是一个唯一的标识符,即使磁盘被移动到另一个系统,它也将持续存在。

要获得磁盘的 UUID,运行blkid命令:

[root@elastic1 ~]# blkid
/dev/sda1: UUID="58c91edb-c361-470e-9805-a31efd85a472" TYPE="xfs"
/dev/sda2: UUID="H3KcJ3-gZOS-URMD-CD1J-8wIn-f7v9-mwkTWn" TYPE="LVM2_member"
/dev/sdb1: UUID="561fc663-0b63-4d2a-821e-12b6caf1115e" TYPE="xfs" PARTLABEL="xfs" PARTUUID="7924e72d-15bd-447d-9104-388dd0ea4eb0"

在本例中,/dev/sdb1是我们将用于 Elasticsearch 的 64 GB 磁盘。使用 UUID,我们可以将其添加到/etc/fstab文件中,该文件控制将在引导期间装载的文件系统。只需编辑文件并添加以下条目:

UUID=561fc663-0b63-4d2a-821e-12b6caf1115e       /var/lib/elasticsearch  xfs     defaults,nobarrier,noatime,nofail       0 0

下面是前面命令中需要注意的一些重要细节:

  • nobarrier:这有助于提高写入性能,因为它禁用了 XFS 用于在写入到达持久存储时确认写入的机制。这通常用于没有电池备份写缓存的物理存储系统。
  • noatime:这将在文件被访问或修改时禁用记录机制。当atime被启用时,每次读取将导致少量写入,因为访问时间需要更新。禁用可以帮助读取,因为它不会生成任何不必要的写入。
  • nofail:这允许系统在支持装载点的磁盘丢失的情况下正常启动。如果无法访问控制台,在云上部署尤其有用。

接下来,在启动 Elasticsearch 服务之前,验证磁盘是否已装载到正确的位置:

[root@elastic1 /]# df -h
Filesystem               Size  Used Avail Use% Mounted on
/dev/mapper/centos-root   14G  1.6G   12G  12% /
devtmpfs                 1.9G     0  1.9G   0% /dev
tmpfs                    1.9G     0  1.9G   0% /dev/shm
tmpfs                    1.9G  8.5M  1.9G   1% /run
tmpfs                    1.9G     0  1.9G   0% /sys/fs/cgroup
/dev/sdb1                 60G   33M   60G   1% /var/lib/elasticsearch
/dev/sda1               1014M  184M  831M  19% /boot
tmpfs                    379M     0  379M   0% /run/user/0

最后,确保配置了/var/lib/elasticsearch目录的正确所有权:

chown elasticsearch: /var/lib/elasticsearch

配置 Elasticsearch

在启动 Elasticsearch 服务之前,我们需要定义几个参数来控制 Elasticsearch 的行为。配置文件采用 YAML 格式,位于/etc/elasticsearch/elasticsearch.yml上。让我们探索哪些主要参数需要更改。

Elasticsearch YAML

Elasticsearch 的中央控制是通过/etc/elasticsearch/elasticsearch.yml文件完成的,该文件采用 YAML 格式。默认的配置文件有合理的文档记录,并解释了每个参数控制的内容,但是有些条目应该作为配置过程的一部分进行更改。

要查找的主要参数如下:

  • 群集名称
  • 发现设置
  • 节点名
  • 网络主机
  • 路径设置

群集名称

Elasticsearch 节点只有在配置中指定了相同的群集名称时,才能加入群集。这是通过cluster.name参数来处理的;对于该设置,我们将使用elastic-cluster:

# --------------------------------Cluster------------------------------
#
# Use a descriptive name for your cluster:
#
cluster.name: elastic-cluster
#

应该在两个节点上配置此设置,以便它们具有相同的值。否则,第二个节点将无法加入群集。

发现设置

发现参数控制 Elasticsearch 如何管理用于群集和主选举的节点内通信。

关于发现的两个主要参数是discovery.zen.ping.unicast.hostsdiscovery.zen.minimum_master_nodes

discovery.zen.ping.unicast.hosts设置控制哪些节点将用于聚类。由于我们的设置将使用两个节点,node1的配置应该有node2的域名,而node2应该有node1的域名。

discovery.zen.minimum_master_nodes设置控制集群中主节点的最小数量;这用于避免在集群中有多个主节点处于活动状态的大脑分裂情况。此参数的数值可以基于一个简单的等式计算,如下所示:

这里, N 是集群中的节点数。对于该设置,由于只需配置2节点,因此设置应为2。这两个参数应该如下:

# -----------------------------Discovery-------------------------------
#
# Pass an initial list of hosts to perform discovery when new node is started:
# The default list of hosts is ["127.0.0.1", "[::1]"]
#
discovery.zen.ping.unicast.hosts: ["elastic2"]
#
# Prevent the "split brain" by configuring the majority of nodes (total number of master-eligible nodes / 2 + 1):
#
discovery.zen.minimum_master_nodes: 2
#
# For more information, consult the zen discovery module documentation.

For node2, change discovery.zen.ping.unicast.hosts: ["elastic2"] to discovery.zen.ping.unicast.hosts: ["elastic1"].

节点名

默认情况下,Elasticsearch 使用随机生成的 UUID 作为其节点名,这不是非常用户友好的。该参数相对简单,因为它控制特定节点的名称。对于这个设置,我们将使用elasticX,其中X是节点号;node1应如下:

#------------------------------Node---------------------------------
#
# Use a descriptive name for the node:
#
node.name: elastic1

Change node2 to match the naming convention, so it is elastic2.

网络主机

这控制 Elasticsearch 将绑定到哪个 IP 地址并侦听请求。默认情况下,它绑定到环回 IP 地址;需要更改此设置,以允许集群中的其他节点或允许其他服务器上的 Kibana 和 Logstash 发送请求。此设置还接受特殊参数,如网络接口。对于此设置,我们将通过将network.host参数设置为0.0.0.0来让 Elasticsearch 监听所有地址。

在两个节点上,确保设置如下:

#-----------------------------Network-------------------------------
#
# Set the bind address to a specific IP (IPv4 or IPv6):
#
network.host: 0.0.0.0

路径设置

最后,路径参数控制 Elasticsearch 存储数据和日志的位置。

默认配置为/var/lib/elasticsearch下存储数据,/var/log/elasticsearch下日志:

#-------------------------------Paths---------------------------------
#
# Path to directory where to store the data (separate multiple locations by comma):
#
path.data: /var/lib/elasticsearch
#
# Path to log files:
#
path.logs: /var/log/elasticsearch

该参数的一个重要方面是,在path.data设置下,可以指定多条路径。Elasticsearch 将使用这里指定的所有路径来存储数据,从而提高整体性能和可用空间。在这个设置中,我们将保留之前步骤中的默认值,即在/var/lib/elasticsearch目录下安装一个数据磁盘。

开始 Elasticsearch

现在我们已经配置了 Elasticsearch,我们需要确保服务在引导过程中自动正确启动。

启动并启用 Elasticsearch 服务,如下所示:

systemctl start elasticsearch && systemctl enable elasticsearch

然后,通过运行以下命令验证 Elasticsearch 是否正确启动:

curl -X GET "elastic1:9200"

输出应该类似于以下代码块:

[root@elastic1 /]# curl -X GET "elastic1:9200"
{
 "name" : "elastic1",
 "cluster_name" : "elastic-cluster",
 "cluster_uuid" : "pIH5Z0yAQoeEGXcDuyEKQA",
 "version" : {
 "number" : "6.5.3",
 "build_flavor" : "default",
 "build_type" : "rpm",
 "build_hash" : "159a78a",
 "build_date" : "2018-12-06T20:11:28.826501Z",
 "build_snapshot" : false,
 "lucene_version" : "7.5.0",
 "minimum_wire_compatibility_version" : "5.6.0",
 "minimum_index_compatibility_version" : "5.0.0"
 },
 "tagline" : "You Know, for Search"
}

添加 Elasticsearch 节点

此时,我们可以向 Elasticsearch 集群添加第二个节点。

同样的配置应该应用于前面的步骤,确保设置被更改以反映node2的域名。

要将节点添加到集群中,我们只需启动 Elasticsearch 服务。

当服务启动时,消息被记录到/var/log/elasticsearch,这表明该节点已成功添加到集群中:

[2018-12-23T01:39:03,834][INFO ][o.e.c.s.ClusterApplierService] [elastic2] detected_master {elastic1}{XVaIWexSQROVVxYuSYIVXA}{fgpqeUmBRVuXzvlf0TM8sA}{192.168.1.150}{192.168.1.150:9300}{ml.machine_memory=3973599232, ml.max_open_jobs=20, xpack.installed=true, ml.enabled=true}, added {{elastic1}{XVaIWexSQROVVxYuSYIVXA}{fgpqeUmBRVuXzvlf0TM8sA}{192.168.1.150}{192.168.1.150:9300}{ml.machine_memory=3973599232, ml.max_open_jobs=20, xpack.installed=true, ml.enabled=true},}, reason: apply cluster state (from master [master {elastic1}{XVaIWexSQROVVxYuSYIVXA}{fgpqeUmBRVuXzvlf0TM8sA}{192.168.1.150}{192.168.1.150:9300}{ml.machine_memory=3973599232, ml.max_open_jobs=20, xpack.installed=true, ml.enabled=true} committed version [1]])

您可以使用以下代码来确认集群已启动并正在运行:

curl -X GET "elastic1:9200/_cluster/state?human&pretty"

输出应该类似于以下代码块:

{
  "cluster_name" : "elastic-cluster",
  "compressed_size" : "10kb",
  "compressed_size_in_bytes" : 10271,
  "cluster_uuid" : "pIH5Z0yAQoeEGXcDuyEKQA",
  "version" : 24,
  "state_uuid" : "k6WuQsnKTECeRHFpHDPKVQ",
  "master_node" : "XVaIWexSQROVVxYuSYIVXA",
  "blocks" : { },
  "nodes" : {
    "XVaIWexSQROVVxYuSYIVXA" : {
      "name" : "elastic1",
      "ephemeral_id" : "fgpqeUmBRVuXzvlf0TM8sA",
      "transport_address" : "192.168.1.150:9300",
      "attributes" : {
        "ml.machine_memory" : "3973599232",
        "xpack.installed" : "true",
        "ml.max_open_jobs" : "20",
        "ml.enabled" : "true"
      }
    },
    "ncVAbF9kTnOB5K9pUhsvZQ" : {
      "name" : "elastic2",
      "ephemeral_id" : "GyAq8EkiQGqG9Ph-0RbSkg",
      "transport_address" : "192.168.1.151:9300",
      "attributes" : {
        "ml.machine_memory" : "3973599232",
        "ml.max_open_jobs" : "20",
        "xpack.installed" : "true",
        "ml.enabled" : "true"
      }
    }
  },
  "metadata" : {
...(truncated)

对于任何需要添加到集群中的后续节点,应遵循前面的步骤,确保cluster.name参数设置为正确的值。

安装 Logstash 和 Kibana

随着 Elasticsearch 集群的启动和运行,我们现在可以继续安装 Logstash 和 Kibana 了。

前面步骤中使用的存储库对于其余组件是相同的。因此,之前用于添加存储库的相同过程应该应用于 Logstash 和 Kibana 节点。

这是一个总结,同样的过程之前已经探索过:

  1. 将存储库添加到/etc/yum.repos.d/elastic.repo
  2. yum缓存更新为sudo yum makecache
  3. 使用sudo yum install logstash kibana安装 Logstash 和 Kibana
  4. /var/lib/logstashsudo parted /dev/sdX mklabel gpt初始化磁盘
  5. 创建sudo parted /dev/sdX mkpart xfs 0GB 32GB分区(注意这是一个 32 GB 的磁盘)
  6. 创建sudo mkfs.xfs /dev/sdX1文件系统
  7. 更新fstab
  8. 更新sudo chown logstash: /var/lib/logstash目录权限

默认情况下不添加 Logstash systemd单位;为此,运行 Logstash 提供的脚本:

sudo /usr/share/logstash/bin/system-install

最后,需要一个特定的组件来协调 Elasticsearch 节点。这将作为 Elasticsearch 集群的负载平衡器,基巴纳用它来安装 Elasticsearch:

sudo yum install elasticsearch

有关协调节点配置的更多信息,请参见配置基巴纳部分。

配置 Logstash

与 Elasticsearch 类似,Logstash 的主配置文件位于/etc/logstash/logstash.yml下,需要更改一些设置才能实现所需的功能。

日志 tash YAML

首先,应该调整node.name参数,使其正确识别 Logstash 节点。默认情况下,它使用机器的主机名作为node.name参数。但是,由于我们在同一个系统上运行 Logstash 和 Kibana,因此值得更改此设置以避免混淆。

接下来,我们需要考虑排队设置;这些控制着 Logstash 如何管理队列的类型以及它存储队列数据的位置。

第一个设置是queue.type,它定义了 Logstash 使用的队列类型。对于此设置,我们使用持久队列:

# ------------ Queuing Settings --------------
#
# Internal queuing model, "memory" for legacy in-memory based queuing and
# "persisted" for disk-based acked queueing. Defaults is memory
#
queue.type: persisted
#

由于排队设置为持久,事件在发送到 Elasticsearch 之前需要存储在临时位置;这由path.queue参数控制:

# If using queue.type: persisted, the directory path where the data files will be stored.
# Default is path.data/queue
#
# path.queue:
#

如果缺省情况下保留,Logstash 将使用path.data/queue目录来存储队列中的事件。path.data目录默认为/var/lib/logstash,这是我们配置 32 GB 磁盘的地方;这是所需的配置。如果需要为排队指定另一个位置,应调整此设置以匹配正确的路径。

logstash.yml文件中最后一个要更改的设置是queue.max_bytes设置,它控制队列允许的最大空间。对于此设置,由于我们只为此目的添加了一个专用的 32 GB 磁盘,因此如果需要更多空间,可以将设置更改为 25 GB,以留出缓冲区。设置应该如下所示:

# If using queue.type: persisted, the total capacity of the queue in number of bytes.
# If you would like more unacked events to be buffered in Logstash, you can increase the
# capacity using this setting. Please make sure your disk drive has capacity greater than
# the size specified here. If both max_bytes and max_events are specified, Logstash will pick
# whichever criteria is reached first
# Default is 1024mb or 1gb
#
queue.max_bytes: 25gb

作为一个选项,xpack.monitoring.enabled设置可以设置为真,以便通过基巴纳进行监控。

Make sure that the parameters in the yaml file don't have a space at the beginning of the line or it might fail to load the configuration.

Logstash 管道

Logstash 输出由管道控制,管道通过放置在/etc/logstash/conf.d/下的文件进行配置;这些文件控制 Logstash 如何获取数据、处理数据,然后将其作为输出返回给 Elasticsearch。管道配置类似于以下代码:

# The # character at the beginning of a line indicates a comment. Use
 # comments to describe your configuration.
 input {
 }
 # The filter part of this file is commented out to indicate that it is
 # optional.
 # filter {
 #
 # }
 output {
 }

在这里,input部分定义了接受哪些数据和来自哪个来源;在这个设置中,我们将使用beats作为输入。过滤器部分控制数据在发送到输出端之前的转换方式,输出部分定义数据的发送位置。在这种情况下,我们将向 Elasticsearch 节点发送数据。

让我们为syslog消息创建一个配置文件,由 Logstash 过滤,然后发送到 Elasticsearch 集群。文件需要放在/etc/logstash/conf.d中,因为输入来自beats模块;我们称之为beats-syslog.conf文件:

sudo vim /etc/logstash/conf.d/beats-syslog.conf

该文件的内容如下:

input {
  beats {
    port => 5044
  }
}
filter {
  if [fileset][module] == "system" {
    if [fileset][name] == "auth" {
      grok {
        match => { "message" => ["%{SYSLOGTIMESTAMP:[system][auth][timestamp]} %{SYSLOGHOST:[system][auth][hostname]} sshd(?:\[%{POSINT:[system][auth][pid]}\])?: %{DATA:[system][auth][ssh][event]} %{DATA:[system][auth][ssh][method]} for (invalid user )?%{DATA:[system][auth][user]} from %{IPORHOST:[system][auth][ssh][ip]} port %{NUMBER:[system][auth][ssh][port]} ssh2(: %{GREEDYDATA:[system][auth][ssh][signature]})?",
                  "%{SYSLOGTIMESTAMP:[system][auth][timestamp]} %{SYSLOGHOST:[system][auth][hostname]} sshd(?:\[%{POSINT:[system][auth][pid]}\])?: %{DATA:[system][auth][ssh][event]} user %{DATA:[system][auth][user]} from %{IPORHOST:[system][auth][ssh][ip]}",
                  "%{SYSLOGTIMESTAMP:[system][auth][timestamp]} %{SYSLOGHOST:[system][auth][hostname]} sshd(?:\[%{POSINT:[system][auth][pid]}\])?: Did not receive identification string from %{IPORHOST:[system][auth][ssh][dropped_ip]}",
                  "%{SYSLOGTIMESTAMP:[system][auth][timestamp]} %{SYSLOGHOST:[system][auth][hostname]} sudo(?:\[%{POSINT:[system][auth][pid]}\])?: \s*%{DATA:[system][auth][user]} :( %{DATA:[system][auth][sudo][error]} ;)? TTY=%{DATA:[system][auth][sudo][tty]} ; PWD=%{DATA:[system][auth][sudo][pwd]} ; USER=%{DATA:[system][auth][sudo][user]} ; COMMAND=%{GREEDYDATA:[system][auth][sudo][command]}",
                  "%{SYSLOGTIMESTAMP:[system][auth][timestamp]} %{SYSLOGHOST:[system][auth][hostname]} groupadd(?:\[%{POSINT:[system][auth][pid]}\])?: new group: name=%{DATA:system.auth.groupadd.name}, GID=%{NUMBER:system.auth.groupadd.gid}",
                  "%{SYSLOGTIMESTAMP:[system][auth][timestamp]} %{SYSLOGHOST:[system][auth][hostname]} useradd(?:\[%{POSINT:[system][auth][pid]}\])?: new user: name=%{DATA:[system][auth][user][add][name]}, UID=%{NUMBER:[system][auth][user][add][uid]}, GID=%{NUMBER:[system][auth][user][add][gid]}, home=%{DATA:[system][auth][user][add][home]}, shell=%{DATA:[system][auth][user][add][shell]}$",
                  "%{SYSLOGTIMESTAMP:[system][auth][timestamp]} %{SYSLOGHOST:[system][auth][hostname]} %{DATA:[system][auth][program]}(?:\[%{POSINT:[system][auth][pid]}\])?: %{GREEDYMULTILINE:[system][auth][message]}"] }
        pattern_definitions => {
          "GREEDYMULTILINE"=> "(.|\n)*"
        }
        remove_field => "message"
      }
      date {
        match => [ "[system][auth][timestamp]", "MMM  d HH:mm:ss", "MMM dd HH:mm:ss" ]
      }
      geoip {
        source => "[system][auth][ssh][ip]"
        target => "[system][auth][ssh][geoip]"
      }
    }
    else if [fileset][name] == "syslog" {
      grok {
        match => { "message" => ["%{SYSLOGTIMESTAMP:[system][syslog][timestamp]} %{SYSLOGHOST:[system][syslog][hostname]} %{DATA:[system][syslog][program]}(?:\[%{POSINT:[system][syslog][pid]}\])?: %{GREEDYMULTILINE:[system][syslog][message]}"] }
        pattern_definitions => { "GREEDYMULTILINE" => "(.|\n)*" }
        remove_field => "message"
      }
      date {
        match => [ "[system][syslog][timestamp]", "MMM  d HH:mm:ss", "MMM dd HH:mm:ss" ]
      }
    }
  }
}
output {
  elasticsearch {
    hosts => ["elastic1", "elastic2"]
    manage_template => false
    index => "%{[@metadata][beat]}-%{[@metadata][version]}-%{+YYYY.MM.dd}"
  }
}

确保output部分有 Elasticsearch 节点的域名或 IP:

output {
 elasticsearch {
    hosts => ["elastic1", "elastic2"]
    manage_template => false
    index => "%{[@metadata][beat]}-%{[@metadata][version]}-%{+YYYY.MM.dd}"
 }
}

在这个管道配置中,beats模块将日志发送到 Logstash 节点。然后 Logstash 将处理数据,并在 Elasticsearch 节点之间负载平衡输出。我们现在可以继续配置基巴纳了。

配置 Kibana

弹性栈的最后一块是基巴纳;配置由/etc/kibana/kibana.yml以类似于 Elasticsearch 和 Logstash 的方式处理。

基贝拉亚姆

默认情况下,基巴纳监听端口5601;这是由server.port参数控制的,如果需要在不同的端口上访问 Kibana,可以更改该参数。对于此设置,将使用默认值。

server.host设置控制基巴纳将监听哪些地址的请求。由于需要从外部来源(即localhost以外)访问,我们可以使用以下设置:

# Specifies the address to which the Kibana server will bind. IP addresses and host names are both valid values.
 # The default is 'localhost', which usually means remote machines will not be able to connect.
 # To allow connections from remote users, set this parameter to a non-loopback address.
 server.host: "0.0.0.0"

server.name参数默认为基巴纳运行的主机名,但是由于 Logstash 与基巴纳一起运行,我们可以更改它来标识基巴纳部分:

# The Kibana server's name.  This is used for display purposes.
server.name: "kibana"

最后,elasticsearch.url指定 Kibana 将连接到哪个 Elasticsearch 节点。如前所述,我们将使用 Elasticsearch 坐标节点作为其他两个节点之间的负载平衡器。

以下是用于所有查询的 Elasticsearch 实例的网址:

elasticsearch.url: "http://localhost:9200"

协调节点

协调节点是不接受输入、不存储数据、也不参与主或从选举的 Elasticsearch 节点。

该节点的目标是在集群中不同的 Elasticsearch 节点之间负载平衡对 Kibana 的请求。安装过程与我们之前使用的过程相同,即确保也安装了 Java(开放 JDK)。

配置会有所不同,因为我们想要实现许多目标:

  • 禁用主节点角色
  • 禁用接收节点角色
  • 禁用数据节点角色
  • 禁用跨集群搜索

为此,我们需要在/etc/elasticsearch/elasticsearch.yml文件上进行以下设置:

cluster.name: elastic-cluster
node.name: coordinate
network.host: 0.0.0.0
node.master: false
node.data: false
node.ingest: false
cluster.remote.connect: false
discovery.zen.ping.unicast.hosts: ["elastic1", "elastic2"]

开始洛格斯塔什和基巴纳

所有的组件都已经配置好了,我们可以启动 Logstash、Kibana 和协调的 Elasticsearch 节点。

Logstash 可以首先启动,因为它不需要启动任何其他组件:

sudo systemctl start logstash && sudo systemctl enable logstash

然后,我们可以启动并启用elasticsearch协调节点:

sudo systemctl start elasticsearch && sudo systemctl enable elasticsearch

最后但同样重要的是,kibana可以经历相同的程序:

sudo systemctl start kibana && sudo systemctl enable kibana

要验证一切启动是否正确,请将浏览器指向端口5601 http://kibana:5601上的kibana地址。单击监控,然后单击启用监控;几秒钟后,您将看到类似以下截图的内容:

您应该可以在线看到所有组件;黄色状态是由于系统索引没有被复制,但这是正常的。

这样,集群就可以启动并运行,并准备好接受来自日志和指标的传入数据。我们将使用 Beats 向集群提供数据,这将在下一节中探讨。

什么是节拍?

Beats 是来自 Elastic.co(elastic search 背后的公司)的轻量级数据托运人。Beats 设计为易于配置和运行。

Beats 是等式的客户端部分,生活在要被监控的系统上。Beats 从整个环境中的服务器捕获指标、日志等,并将其发送到 Logstash 进行进一步处理,或者发送到 Elasticsearch 进行索引和分析。

有多个官方 Beats(由 Elastic 开发和维护),社区开发了大量开源 Beats。

我们将在这个设置中使用的主要节拍是文件节拍公制节拍

文件节拍

Filebeat 函数从源(如 syslog、Apache 和 Nginx)收集日志,然后将这些日志发送到 Elasticsearch 或 Logstash。

需要在需要数据收集的每台服务器上安装 Filebeat 客户端才能启用。该组件允许将日志发送到一个集中的位置,以便无缝搜索和索引。

公制尺寸标注

Metricbeat 收集指标,如 CPU 使用情况、内存使用情况、磁盘 IO 统计信息和网络统计信息,然后将其发送到 Elasticsearch 或 Logstash。

真的没有必要进一步转换度量数据,所以将数据直接输入 Elasticsearch 更有意义。

Metricbeat 应安装在所有需要监控资源使用情况的系统中;将 Metricbeat 安装在 Elasticsearch 节点上可以让您更好地控制资源使用,从而避免出现问题。

还存在其他节拍,例如:

  • 数据包:用于网络流量监控
  • 日志节拍:对于systemd日志
  • 审计节拍:对于登录等审计数据

此外,Beats 还可以通过使用模块来适应特定的需求。例如,Metricbeat 有一个收集 MySQL 性能统计数据的模块。

让我们不要跳过一个节拍——安装节拍

Elasticsearch 提供的 Beats 的安装可以通过以前用于安装 Elasticsearch、Logstash 和 Kibana 的弹性存储库来完成。

首先,让我们在其中一个 Elasticsearch 节点上安装 Filebeat:

sudo yum install -y filebeat

安装完成后,通过运行以下代码确认安装已经完成:

filebeat version

输出应该类似于以下命令块:

[root@elastic1 ~]# filebeat version
filebeat version 6.5.4 (amd64), libbeat 6.5.4 [bd8922f1c7e93d12b07e0b3f7d349e17107f7826 built 2018-12-17 20:22:29 +0000 UTC]

安装metricbeat的过程和它在同一个库中的过程是一样的:

sudo yum install metricbeat

要在其他客户端上安装 Beats,只需按照我们之前解释的那样添加弹性存储库,并通过yum进行安装。Beats 也作为独立包提供,以防没有可用于分发的存储库。

配置 Beats 客户端

在其中一个 Elasticsearch 节点上安装了 Filebeat 和 Metricbeat 后,我们可以继续配置它们,将数据馈送到 Logstash 和 Elasticsearch。

Filebeat YAML

现在,大多数弹性组件都是通过 YAML 文件配置的,这并不奇怪。Filebeat 也不例外,它的配置由/etc/filebeat/filebeat.yml文件处理。

首先,我们需要告诉filebeat在哪里寻找将要被运送到 Logstash 的日志文件。在yaml文件中,这是在filebeat.inputs部分;将enabled: false改为enabled: true,如下:

#=========================== Filebeat inputs =============================
filebeat.inputs:
# Each - is an input. Most options can be set at the input level, so
# you can use different inputs for various configurations.
# Below are the input specific configurations.
- type: log
 # Change to true to enable this input configuration.
 enabled: true
 # Paths that should be crawled and fetched. Glob based paths.
 paths:
    - /var/log/*.log

Filebeat 嵌入了 Kibana 仪表板,可轻松可视化发送的数据。这允许 Filebeat 加载仪表板,然后将 Kibana 地址添加到setup.kibana部分:

#==============================Kibana================================
# Starting with Beats version 6.0.0, the dashboards are loaded via the Kibana API.
# This requires a Kibana endpoint configuration.
setup.kibana:
 # Kibana Host
 # Scheme and port can be left out and will be set to the default (http and 5601)
 # In case you specify and additional path, the scheme is required: http://localhost:5601/path
# IPv6 addresses should always be defined as: https://[2001:db8::1]:5601
 host: "kibana:5601"

加载dashboards,如下:

filebeat setup --dashboards

对于每个新的 Beat 安装,此配置只需执行一次;没有必要在进一步的 Filebeat 安装中更改此设置,因为仪表板已经加载。

既然我们将向 Logstash 发送数据,请注释掉output.elasticsearch部分;然后,取消对output.logstash部分的注释,并添加 Logstash 的详细信息:

#------------------------ Elasticsearch output ----------------------------
#output.elasticsearch:
 # Array of hosts to connect to.
 # hosts: ["localhost:9200"]
 # Optional protocol and basic auth credentials.
 #protocol: "https"
 #username: "elastic"
 #password: "changeme"
#-------------------------- Logstash output -------------------------------
output.logstash:
 # The Logstash hosts
 hosts: ["logstash:5044"]

接下来,我们将使用 Filebeat 的系统模块将输出发送到 Logstash 要启用此功能,只需运行以下命令:

filebeat modules enable system

然后,将索引模板加载到elasticsearch中,如下:

filebeat setup --template -E output.logstash.enabled=false -E 'output.elasticsearch.hosts=["elastic1:9200", "elastic2"]'

最后,启动并启用filebeat,如下:

sudo systemctl enable filebeat && sudo systemctl start filebeat

为了验证数据正在发送,我们可以使用提供的仪表板之一来可视化syslog事件。在基巴纳,转到仪表板,在搜索栏中键入Syslog Dashboard;您将看到类似以下截图的内容:

Kibana Dashboard showing search results for Syslog Dashboard

YAML 度量单位

Metricbeat 遵循与 Filebeat 类似的流程,其中/etc/metricbeat/metricbeat.yml文件需要编辑才能发送输出到 Elasticsearch,Kibana 仪表盘需要加载(即需要运行一次)。

为此,编辑metricbeat.yml文件以允许 Metricbeat 加载基巴纳仪表板:

setup.kibana:
 host: "kibana:5601"

接下来,指定Elasticsearch集群:

#------------------------ Elasticsearch output ----------------------------
output.elasticsearch:
 # Array of hosts to connect to.
 hosts: ["elastic1:9200", "elastic2:9200"]

加载基巴纳dashboards,如下所示:

metricbeat setup --dashboards

默认情况下,metricbeat启用了系统模块,该模块将捕获 CPU、系统负载、内存和网络的统计数据。

启动并启用metricbeat服务,如下所示:

sudo systemctl enable metricbeat && sudo systemctl start metricbeat

要确认数据正在发送到群集,请转到 kibana 屏幕上的发现;然后,选择 metricbeat-*索引模式,并验证是否正在发送事件:

Events filtered with the metricbeat-* index pattern

后续步骤

此时,集群现已完全运行。剩下的就是在集群的其他节点上安装 Metricbeat 和 Filebeat,以确保集群的运行状况和资源使用情况完全可见。

根据需要监控的内容和需要索引的日志,向集群中添加更多客户端需要安装适当的 Beat。

如果集群上的负载增加,则有许多选项可用—要么向集群中添加更多节点来平衡负载请求,要么增加每个节点的可用资源数量。在某些情况下,简单地添加更多资源是一种更具成本效益的解决方案,因为它不需要配置新节点。

像这样的实现可以用来监控 Kubernetes 设置的性能和事件(比如在 第 11 章设计 ELK 栈中描述的)。一些 Beats 具有特定的模块,用于从 Kubernetes 集群中提取数据。

最后,为了简化配置和维护,可以对这个设置进行一个增强,就是让 Beat 客户端指向协调的 Elasticsearch 节点,作为节点之间的负载平衡器;这避免了在 Beats 的输出配置中硬编码每个 Elasticsearch 节点——只需要一个地址。

摘要

在本章中,我们经历了许多步骤来配置弹性栈,它是四个主要组件的集合——Elasticsearch、Logstash、基巴纳和节拍。对于设置,我们使用了三个虚拟机;我们托管了两个 Elasticsearch 节点,然后,在单个系统上,我们安装了 Logstash 和 Kibana,对每个组件使用 6.5 版本。我们使用 Elastic Stack 提供的 RPM 存储库安装了 Elasticsearchyum用于安装所需的软件包。Elasticsearch 配置是使用elasticsearch.yml文件完成的,该文件控制elasticsearch的行为。我们定义了功能集群所需的许多设置,例如cluster.name参数和discovery.zen.minimum_master_nodes

我们通过配置集群名称和发现设置添加了一个新的 Elasticsearch 节点,这允许该节点自动加入集群。然后,我们继续安装 Kibana 和 Logstash,它们是在用于 Elasticsearch 的同一个 RPM 存储库中提供的;配置 Logstash 和 Kibana 是通过它们各自的.yml文件完成的。

一旦所有三个主要组件都启动,并且操作准备好接受传入的数据,我们就开始安装 Beats,这是 Elasticsearch 和 Logstash 用来接收数据的数据发货商。对于日志和事件,我们使用 Filebeat,对于内存使用和 CPU 等系统指标,我们使用 Metricbeat。

在下一章中,我们将了解系统管理和 Salt 架构的挑战。

问题

  1. 如何安装 Elasticsearch?
  2. 如何对磁盘进行分区?
  3. 如何持久地挂载文件系统?
  4. 哪个文件控制 Elasticsearch 配置?
  5. cluster.name设置是做什么的?
  6. Elasticsearch 集群中推荐的节点数量是多少?
  7. 如何将 Elasticsearch 节点添加到现有集群中?
  8. 安装 Logstash 和 Kibana 需要什么过程?
  9. 什么是持久排队?
  10. 什么是协调节点?
  11. 什么是节拍?
  12. Filebeat 是用来做什么的?

进一步阅读