ELK搭建记录

一、Elasticsearch

1、新建用户

新版本的elasticsearch 不允许使用root用户

useradd els

2、下载软件

分别包括 elasticsearch-7.8.0 filebeat-7.8.0 kibana-7.8.0 logstash-7.8.0

解压缩文件到指定目录,这里放置到/home/app/下面,然后做软连接。

3、elasticsearch硬件要求

I、硬盘

  • 固态盘 SSD
    • 修改调度算法,可以使用deadline 或者 noopdeadline 调度程序基于写入等待时间进行优化, noop 只是一个简单的 FIFO 队列。
  • 机械硬盘
    • 选择高性能服务器硬盘,如15k RPM 驱动器
  • 使用RAID
    • 使用 RAID 0 是提高硬盘速度的有效途径,对机械硬盘和 SSD 来说都是如此。没有必要使用镜像或其它 RAID 变体,因为高可用已经通过 replicas 内建于 Elasticsearch 之中。
  • 避免使用网络附加存储(NAS)

II、内存

  • 64 GB 内存的机器是非常理想的, 但是32 GB 和16 GB 机器也是很常见的。少于8 GB 会适得其反(你最终需要很多很多的小机器),大于64 GB 的机器也会有问题,GC的时候会增加时间。

  • 如果不需要对分词字符串做聚合计算,堆内存越小,Elasticsearch(更快的 GC)和 Lucene(更多的内存用于缓存)的性能越好

  • 确保堆内存最小值( Xms )与最大值( Xmx )的大小是相同的,防止程序在运行时改变堆内存大小, 这是一个很耗系统资源的过程

  • 标准的建议是把 50% 的可用内存作为 Elasticsearch 的堆内存,保留剩下的 50%给非堆内存使用

  • 即便你有足够的内存,也尽量不要超过 32 GB。因为它浪费了内存,降低了CPU 的性能,还增加了 GC 的时间。

    • 查看JVM指针压缩支持的最大值

      JAVA_HOME=`/usr/libexec/java_home -v 1.7` 
      java -Xmx32600m -XX:+PrintFlagsFinal 2> /dev/null | grep UseCompressedOops
       bool UseCompressedOops   := true
      JAVA_HOME=`/usr/libexec/java_home -v 1.7` 
      java -Xmx32766m -XX:+PrintFlagsFinal 2> /dev/null | grep UseCompressedOops
       bool UseCompressedOops   = false
      

      调整-Xmx32600m中的值,来测试内存指针压缩使用的临界值,看系统到底设置多大内存合适。

  • 避免使用交换分区

III、CPU

  • 对CPU要求不高,选择更多的核心的会比主频高的好一点

IV、网络

  • 低延时能帮助确保节点间能容易的通讯,大带宽能帮助分片移动和恢复
  • 避免集群跨越多个数据中心。绝对要避免集群跨越地域

4、配置elasticsearch

.
├── config
│ ├── elasticsearch.keystore
│ ├── elasticsearch.yml
│ ├── jvm.options
│ ├── jvm.options.d
│ ├── log4j2.properties
│ ├── role_mapping.yml
│ ├── roles.yml
│ ├── users
│ └── users_roles

  • 修改jvm.options

    配置java虚拟机使用的内存, 正式环境中应:

    • Xms 和 Xmx 设置成相同的值;
    • Xmx 不要超过机器内存的 50%,并且不要设置超过 30GB。
    -Xms256m
    -Xmx256m
    
  • 修改elasticsearch.yml

    因为是测试环境,这里没有配置集群。

    path.data: /home/app/elasticsearch/data
    path.logs: /home/app/elasticsearch/logs
    network.host: 0.0.0.0
    http.port: 9200
    # 如果不配置下面两行的话,上面指定0.0.0.0的时候会报错
    transport.host: localhost
    transport.tcp.port: 9300
    
    xpack.ml.enabled: false
    http.cors.enabled: true
    http.cors.allow-origin: "*"
    

    创建启动需要的目录mkdir -p /home/app/elasticsearch/{data,logs}

5、启动elasticsearch

可以使用 bin/elasticsearch 前台启动

# 加参数可以放到后台运行

-d, --daemonize Starts Elasticsearch in the background

使用systemd管理启动

[Unit]
Description=elasticsearch
After=network.target
After=network-online.target
Wants=network-online.target
Documentation=https://www.elastic.co/

[Service]
# Type=notify
Type=simple
User=els
Group=els
LimitNOFILE=100000
LimitNPROC=100000
WorkingDirectory=/home/app/elasticsearch/
ExecStart=/home/app/elasticsearch/bin/elasticsearch 

Restart=no
PrivateTmp=true

#Restart=on-failure
#RestartSec=5
#LimitNOFILE=65536

[Install]
WantedBy=multi-user.target

6、查看状态

# curl localhost:9200
{
  "name" : "node-1",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "gWkawGONTtOtT_I6-YqYgA",
  "version" : {
    "number" : "7.8.0",
    "build_flavor" : "default",
    "build_type" : "tar",
    "build_hash" : "757314695644ea9a1dc2fecd26d1a43856725e65",
    "build_date" : "2020-06-14T19:35:50.234439Z",
    "build_snapshot" : false,
    "lucene_version" : "8.5.1",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}

7、配置上的优化建议

A、集群名

cluster.name: elasticsearch_production

B、节点名字

节点启动的时候会随机启动一个名字, 这样不方便管理和识别。

node.name: elasticsearch_005_data

C、数据存储路径

# 注意:你可以通过逗号分隔指定多个目录。
path.data: /path/to/data1,/path/to/data2
path.logs: /path/to/logs
path.plugins: /path/to/plugins

D、最小主节点数

防止集群发生脑裂的情况,使用公式计算最少候选节点个数(master 候选节点个数 / 2) + 1

# 在配置文件中指定
discovery.zen.minimum_master_nodes: 2

# 通过API设置
# 这将成为一个永久的配置,并且无论你配置项里配置的如何,这个将优先生效
PUT /_cluster/settings
{
    "persistent" : {
        "discovery.zen.minimum_master_nodes" : 2
    }
}

E、集群恢复方面的配置

如果不增加配置的情况下,加入集群中有的节点需要短暂停机维护,这时集群中其他节点会发现,数据不再均匀分布,其他节点会立即进行重新分片复制。如果维护节点又重新加入集群,这时,它会发现自己的数据已经在其他节点存在,那就会将本地删除,然后整个集群重新进行平衡。如果数据量大的情况下,来回移动数据,节点会消耗磁盘和网络带宽。

使用下面的配置,缓解上面提到的问题

# 下面配置项不支持动态调整,只能在配置文件或者是在命令行里指定
gateway.recover_after_nodes: 8 	# 存在8个及以上节点的时候不进行数据恢复

# 等待 5 分钟,或者10 个节点上线后,才进行数据恢复,这取决于哪个条件先达到。
gateway.expected_nodes: 10		
gateway.recover_after_time: 5m

# 这三个设置可以在集群重启的时候避免过多的分片交换。这可能会让数据恢复从数个小时缩短为几秒钟。

F、最好使用单播替换组播

使用单播,你可以为 Elasticsearch 提供一些它应该去尝试连接的节点列表。 当一个节点联系到单播列表中的成员时,它就会得到整个集群所有节点的状态,然后它会联系 master 节点,并加入集群。

如果你使用 master 候选节点作为单播列表,你只要列出三个就可以了。 这个配置在 elasticsearch.yml 文件中:

discovery.zen.ping.unicast.hosts: ["host1", "host2:port"]

8、集群备份

要备份你的集群,你可以使用 snapshot API。这个会拿到你集群里当前的状态和数据然后保存到一个共享仓库里,第一次全量备份,以后增量备份。支持的备份仓库:

  • 共享文件系统,比如 NAS
  • Amazon S3
  • HDFS (Hadoop 分布式文件系统)
  • Azure Cloud

A、创建仓库

PUT _snapshot/my_backup 
{
    "type": "fs", 
    "settings": {
        "location": "/mount/backups/my_backup" ,
         "max_snapshot_bytes_per_sec" : "50mb", 
         "max_restore_bytes_per_sec" : "50mb"
    }
}

# 给我们的仓库取一个名字,在本例它叫 my_backup
# 我们指定仓库的类型应该是一个共享文件系统。
# 最后,提供一个已挂载的设备作为目的地址。
# max_snapshot_bytes_per_sec 这个参数控制快照数据进入仓库的限流。默认是每秒 20mb 。
# max_restore_bytes_per_sec 当时,这个参数控制从仓库恢复数据的过程会被限流。默认是每秒 20mb。
# 注意:共享文件系统路径必须确保集群所有节点都可以访问到。
# 新建用PUT,更新用POST

B、快照所有打开的索引

# 备份所有打开的索引到 my_backup 仓库里,并命名快照为 snapshot_1
# 调用会立刻返回,然后快照会在后台运行
PUT _snapshot/my_backup/snapshot_1

# 添加一个 wait_for_completion 会阻塞调用直到快照完成。注意大型快照会花很长时间才返回。
PUT _snapshot/my_backup/snapshot_1?wait_for_completion=true

C、快照指定索引

# 只会备份 index1 和 index2 了
PUT _snapshot/my_backup/snapshot_2
{
    "indices": "index_1,index_2"
}

D、查看快照相关的信息

# 获取指定快照信息
GET _snapshot/my_backup/snapshot_2

# 获取所有快照信息
GET _snapshot/my_backup/_all

E、删除快照

DELETE _snapshot/my_backup/snapshot_2

用 API 删除快照很重要,而不能用其他机制(比如手动删除,或者用 S3 上的自动清除工具)。因为快照是增量的,有可能很多快照依赖于过去的段。delete API 知道哪些数据还在被更多近期快照使用,然后会只删除不再被使用的段。

但是,如果你做了一次人工文件删除,你将会面临备份严重损坏的风险,因为你在删除的是可能还在使用中的数据。

F、监控快照进度

# 这个 API 用的是快照机制相同的线程池。如果快照非常大的分片,状态更新的间隔会很大,因为 API 在竞争相同的线程池资源
GET _snapshot/my_backup/snapshot_3
# _status API 立刻返回,然后给出详细的多的统计值输出
GET _snapshot/my_backup/snapshot_3/_status

G、取消一个快照

# 这个会中断快照进程。然后删除仓库里进行到一半的快照。
DELETE _snapshot/my_backup/snapshot_3

9、恢复备份

A、恢复快照

# 默认行为是把这个快照里存有的所有索引都恢复
POST _snapshot/my_backup/snapshot_1/_restore

# 恢复指定索引
POST /_snapshot/my_backup/snapshot_1/_restore
{
    "indices": "index_1", 
    "rename_pattern": "index_(.+)", 
    "rename_replacement": "restored_index_$1" 
}
# 只恢复 index_1 索引,忽略快照中存在的其余索引。
# 查找所提供的模式能匹配上的正在恢复的索引。
# 然后把它们重命名成替代的模式。
# 这个恢复 index_1 到你集群里,但是会重命名成了 restored_index_1 。

restore 命令也会立刻返回,恢复进程会在后台进行。如果你更希望你的 HTTP 调用阻塞直到恢复完成,添加 wait_for_completion 标记

POST _snapshot/my_backup/snapshot_1/_restore?wait_for_completion=true

B、查看恢复进度

这个 API 可以为你在恢复的指定索引单独调用:

GET restored_index_3/_recovery

或者查看你集群里所有索引,可能包括跟你的恢复进程无关的其他分片移动:

GET /_recovery/

C、取消恢复

DELETE /restored_index_3

如果 restored_index_3 正在恢复中,这个删除命令会停止恢复,同时删除所有已经恢复到集群里的数据。

二、kibana

主要功能,从Elasticsearch中获取数据,然后进行分析绘图。

1、配置kibana

config
└── kibana.yml

server.port: 5601
server.host: "0.0.0.0"
elasticsearch.hosts: ["http://localhost:9200"]
elasticsearch.preserveHost: true
kibana.index: ".kibana"
kibana.defaultAppId: "home"
i18n.locale: "zh-CN"
xpack.reporting.encryptionKey: "7ccc4d8b359dcd6b5e8f98a7e8c16c3b"
xpack.security.session.idleTimeout: "1d"

2、启动kibana

  • 可以使用bin/kibana -c config/kibana.yml

  • 使用systemd管理启动

    kabana.service

    [Unit]
    Description=kibana
    After=network.target
    After=network-online.target
    Wants=network-online.target
    Documentation=https://www.elastic.co/kibana
    
    [Service]
    Type=simple
    User=els
    Group=els
    LimitNOFILE=100000
    LimitNPROC=100000
    WorkingDirectory=/home/app/kibana/
    ExecStart=/home/app/kibana/bin/kibana -c /home/app/kibana/config/kibana.yml
    
    Restart=no
    PrivateTmp=true
    
    #Restart=on-failure
    #RestartSec=5
    #LimitNOFILE=65536
    
    [Install]
    WantedBy=multi-user.target
    

3、查看监控状态

kibana-status

三、Filebeat

主要功能是收集指定位置的数据存储到指定位置

1、配置filebeat

/home/app/filebeat/filebeat.yml

filebeat.inputs:
- type: log
  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: "localhost:5601"
output.elasticsearch:
  hosts: ["localhost:9200"]
processors:
  - add_host_metadata: ~
  - add_cloud_metadata: ~
  - add_docker_metadata: ~
  - add_kubernetes_metadata: ~
logging.level: error

2、启动filebeat

可以使用./filebeat -c filebeat.yml 启动

3、常用的input方式

https://www.elastic.co/guide/en/beats/filebeat/current/configuration-filebeat-options.html

  • log

    filebeat.inputs:
    - type: log 
      enabled: true
      paths:
        - /var/log/system.log
        - /var/log/wifi.log
    - type: log 
      paths:
        - "/var/log/apache2/*"
      fields:
        apache: true
      fields_under_root: true
    
    - type: log
      paths:
        - "/var/log/apache2/*"
      include_lines: ['sometext']
      exclude_lines: ['^DBG']
      exclude_files: ['\.gz$']
    
    • 常用参数

      • encoding

      • exclude_lines

      • include_lines

      • exclude_files

      • multiline

      • ignore_older

      • json

        json.keys_under_root: true
        json.add_error_key: true
        json.message_key: log
        

4、常用的output

转换输出的格式

output.console:
  codec.json:
    pretty: true
    escape_html: false
output.console:
  codec.format:
    string: '%{[@timestamp]} %{[message]}'

5、常用处理器

  • 添加标签
processors:
  - add_fields:
      target: project
      fields:
        name: myproject
        id: '574734885120952459'
  • 添加tags

    如果已经存在,则追加到后面

    processors:
      - add_tags:
          tags: [web, production]
          target: "environment"
    
  • 转换 Convert

    可以对指定字段进行转换

    支持的类型包括: integer, long, float, double, string, boolean, and ip.

    processors:
      - convert:
          fields:
            - {from: "src_ip", to: "source.ip", type: "ip"}
            - {from: "src_port", to: "source.port", type: "integer"}
          ignore_missing: true
          fail_on_error: false
       
    
    • fields(必须)

      这是要转换的字段列表。 列表中至少必须包含一项。 列表中的每个项目都必须具有一个指定源字段的from键。 to键是可选的,它指定在何处分配转换后的值。 如果省略to,那么from字段就地更新。 类型键指定将值转换为的数据类型。 如果省略type,则处理器将复制或重命名该字段,而不进行任何类型转换。

    • ignore_missing(可选)

      如果为true,则在事件中未找到from键时,处理器将继续下一个字段。 如果为false,则处理器返回错误,并且不处理其余字段。 默认为false。

    • fail_on_error(可选)

      如果值为 false 类型转换失败将被忽略,处理器继续下一个字段。 默认值为“ true”。

    • tag(可选)

      标示当前处理器

    • mode

      当同时定义了from和to时,mode选项将控制类型转换成功后是copy还是rename该字段。 默认为copy。

  • 拷贝 filelds

    processors:
      - copy_fields:
          fields:
            - from: message
              to: event.original
          fail_on_error: false
          ignore_missing: true
    

    fields

    List of from and to pairs to copy from and to.

    fail_on_error

    可选)如果设置为true,则在发生错误的情况下将还原对事件的更改,并返回原始事件。 如果设置为false,则在发生错误时也将继续处理。 默认为true。

    ignore_missing

    (可选)是否忽略缺少源字段的事件。 默认值为false,如果缺少字段,则将无法处理事件

  • Decode csv fileds

    processors:
      - decode_csv_fields:
          fields:
            message: decoded.csv
          separator: ","
          ignore_missing: false
          overwrite_keys: true
          trim_leading_space: false
          fail_on_error: true
    
  • decode json fileds

    processors:
      - decode_json_fields:
          fields: ["field1", "field2", ...]
          process_array: false
          max_depth: 1
          target: ""
          overwrite_keys: false
          add_error_key: true
    

四、Logstath

1、安装

[elk-7.x]
name=Elastic repository for 7.x packages
baseurl=https://mirrors.tuna.tsinghua.edu.cn/elasticstack/7.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md

yum install logstash

或者二进制安装,使用openjdk启动的时候报错。使用oracal Java就没报错。

2、配置

https://www.elastic.co/guide/en/logstash/current/plugins-codecs-json.html

# 基本格式
input {
	stdin{}
}
filter{

}
output {
	stdout{
		codec => "rubydebug"
	}
}

五、测试收集nginx日志

  • 日志格式
# 因为当时配置的时候没有按标准格式来设置。所以需要特殊处理
log_format  main  '$clientRealIp - $remote_user [$time_local] $request '
'$status $body_bytes_sent $request_time $upstream_response_time $upstream_addr $http_referer '
'$http_user_agent $http_x_forwarded_for ';
  • filebeat 完整配置
filebeat.inputs:
- type: log
  enabled: true
  paths:
    - /home/testlog/access/access_log.*
  tags: "nginx-access"
  fields:
    project: nginx-access
    logname: nginx-log
    
  fields_under_root: true
processors:
  - drop_fields:
      fields: ["log","input","host","agent","@metadata","ecs"]
filebeat.config.modules:
  path: ${path.config}/modules.d/*.yml
  reload.enabled: false
  reload.period: 10s
setup.template.settings:
  index.number_of_shards: 1
  index.codec: best_compression
  #_source.enabled: false
setup.kibana:
  host: "localhost:5601"
output.console:
  enabled: false
  pretty: true
output.elasticsearch:
  enabled: false
  hosts: ["localhost:9200"]
  indices:
  - index: "nmb_log_%{[project]:default}-%{+yyyy.MM.dd}"
    when.contains:
      project: "nginx-access"
output.redis:
  enabled: true
  hosts: ["localhost"]
  password: ""
  timeout: 5
  key: "nginx-access"
  db: 0
  datatype: list
  codec.format:
    #string: '%{[@timestamp]} %{[message]}'
    string: '%{[message]}'
processors:
  - add_host_metadata: ~
  - add_cloud_metadata: ~
  - add_docker_metadata: ~
  - add_kubernetes_metadata: ~
logging.level: info
logging.files:
  path: ${path.config}/logs
  name: filebeat.log
  keepfiles: 7
  permissions: 0644
monitoring.enabled: false
logging.metrics.enabled: false
setup.template.name: "nmb_log"
setup.template.pattern: "nmb_log*"
setup.template.enabled: true
setup.template.overwrite: true
setup.ilm.enabled: false
setup.ilm.overwrite: false
  • logstash配置
input {
   redis {
       id => "nginx_access_redis"
       data_type => "list"
       key => "nginx-access"
       host => "127.0.0.1"
       port => 6379
       db => 0
       threads => 5
       type => "nginxlog"
   }
   # stdin{ type => "nginxlog"}
}
#
filter{
  if [type] == "nginxlog" {
        grok {
          patterns_dir => ["./patterns"]
          match => {
              "message" => "%{IP:clientip} %{NGUSER:ident} %{NGUSER:auth} \[%{HTTPDATE:logdate}\] %{WORD:match} %{URIPATHPARAM:request} HTTP/%{NUMBER:httpversion} %{NUMBER:status:int} (?:%{NUMBER:bytes}|-) (?:%{NUMBER}|-) (?:%{NUMBER}|-) %{HOSTPORT:proxyserv} (?:(%{URI:referrer}|-|%{QS:referrer})) %{ALL:agent}"
          }
          overwrite => [ "message" ]
        }
		# 用日志中的时间替换采集时间
        date{
                match=>["logdate","dd/MMM/yyyy:HH:mm:ss Z"]
                target => "@timestamp"
        }

        geoip {
               database => "/home/app/logstash/config/geoip/GeoLite2-City.mmdb"
               source => 'clientip'
               fields => ["country_name", "city_name", "location"]
              # remove_field => ["[geoip][latitude]", "[geoip][longitude]"
           }
       #有无法解析的地址就删除
       if "_geoip_lookup_failure" in [tags] { drop { } }

       mutate {
                   #convert => [ "[geoip][coordinates]", "float"]
                   #convert => [ "status","integer" ]
                   #convert => [ "bytes","integer" ]
                   remove_field => [ "host","tags","ident","@version","auth","proxyserv","logdate","message"]
       }
   }
}

output{
   elasticsearch {
       hosts => "127.0.0.1:9200"
       index => "logstash-%{type}-%{+YYYY.MM.dd}"
       template_overwrite => true
   }
   ## stdout{
   ##             codec => "rubydebug"
   ## }

}

patterns/nginxlog

NGUSERNAME [a-zA-Z\.\@\-\+_%]+
NGUSER %{NGUSERNAME}
HTTPDATE %{MONTHDAY}/%{MONTH}/%{YEAR}:%{TIME} %{INT}
URI %{URIPROTO}://?(?:%{URIHOST})?(?:%{URIPATHPARAM})?
ALL .*

先启动filebeat将日志文件存储到redis,然后启动logstash消费日志。

  • kibana中查看

    • 设置

kibina-index-log

创建图表

六、metricbeat组件

metricbeat是一个收集系统指标的软件,可以将数据放入elasticsearch中,同时导入kibana图表

1、修改配置文件

metricbeat.config.modules:
  path: ${path.config}/modules.d/*.yml
  reload.enabled: false

setup.template.settings:
  index.number_of_shards: 1
  index.codec: best_compression

setup.kibana:
  host: "localhost:5601"

output.elasticsearch:
  hosts: ["localhost:9200"]
  indices:
    - index: "metricbeat-7.8.0-%{+yyyy.MM.dd}"
setup.ilm.enabled: false
processors:
  - add_host_metadata: ~
  - add_cloud_metadata: ~
  - add_docker_metadata: ~
  - add_kubernetes_metadata: ~
logging.level: error
logging.files:
  path: ${path.config}/logs/metricbeat
  name: metricbeat
  keepfiles: 7
  permissions: 0644

2、启动

  • 导入kibana图表(可选)

    metricbeat -e setup

  • 启动

    ``metricbeat -c metricbeat.yml`

    配置systemd管理 metricbeat.service

    [Unit]
    Description=metricbeat service
    After=network.target
    After=network-online.target
    Wants=network-online.target
    
    [Service]
    Type=simple
    WorkingDirectory=/home/app/metricbeat
    ExecStart=/home/app/metricbeat/metricbeat  -c /home/app/metricbeat/metricbeat.yml
    
    Restart=on-failure
    
    [Install]
    WantedBy=multi-user.target
    RequiredBy=docker.service
    

七、grafana绘图

grafana是一款功能非常强大也是最常用的监控展示框架。可以读取多种源来绘制图形。

1、读取上面Elasticsearch中的监控数据

posted @ 2020-09-04 17:57  郭默涵  阅读(276)  评论(0)    收藏  举报