美文网首页程序员
简单的ELK搭建

简单的ELK搭建

作者: 亦伴亦侣 | 来源:发表于2019-11-22 15:18 被阅读0次

    1. 前言

    针对nginx的访问日志需要进行一个近实时的监控,以便统计用户的访问情况,包括用户的请求IP,请求数据等。因为服务器是和负载均衡用的是阿里云的,阿里云本身也有提供针对负载均衡的日志统计功能,但是作为一个通用日志其是有严重缺陷的:

    • 无法收集用户自定义的请求头(我们的实际情况是通过一个自定义的请求头来做用户的身份识别,请求头有用户的唯一识别信息
    • 无法获取到用户的请求数据($request_body) (很多时候,当出现异常访问的时候,是需要通过查询用户的访问数据的,特别像搜索这种业务模块时

    由于存在上面比较严重的缺点,基本上阿里云的日志对我来说就有点鸡肋(食之无味,弃之可惜,你不得不同意他除了上面两点缺点外,日志的其他方面都是做得不错的)。因此我决定自己动手搭建符合自己业务的ELK日志服务。

    之前我是有搭建过ELK的经验的,但是没在生产环境试过,起初在搭建的时候我考虑到可能会有以下几个问题:

    1. Elasticsearch对内存的占用情况
    2. 收集nginx访问日志,相当于需要打开nginx的access日志开关,硬盘的读写情况,硬盘的占用,会不会影响到用户。
    3. 日志收集对应用服务器的影响

    我现在还是在一两台服务器开启了日志收集,做一个灰度测试。

    2. Elasticsearch搭建

    2.1 Elasticsearch下载安装

    Elasticsearch的安装比较简单,直接下载解压缩即可

    ### 下载
    wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.4.2-linux-x86_64.tar.gz
    
    ### 解压缩:
    tar -zxvf elasticsearch-7.4.2-linux-x86_64.tar.gz
    

    2.2 Elasticsearch配置

    1. 修改cluster-name和node-name

    cluster.name: my-application
    node.name: node-1
    node.master: true
    node.data: true
    

    2. 修改网络相关

    network.host: 0.0.0.0  ## 0.0.0.0允许所有的ip,这里我是为了方便,后面可以根据实际情况填写
    http.port: 9200  ## default
    transport.tcp.port: 9300  ## defalut
    
    在这里插入图片描述

    3. 修改head插件的跨域问题

    # 以下的两个配置是为了解决跨域问题,在head插件访问es的时候报跨域了
    http.cors.enabled: true
    http.cors.allow-origin: "*"
    

    4. 发现配置

    # Pass an initial list of hosts to perform discovery when this node is started:
    # The default list of hosts is ["127.0.0.1", "[::1]"]
    discovery.seed_hosts: ["192.168.1.57"]  ## 可被发现的节点IP集合
    cluster.initial_master_nodes: ["node-1", "node-2"]
    

    5. 解决es启动时的报错问题,.ElasticSearch集群启动错误,错误的原因是:因为Centos6不支持SecComp,而ES默认bootstrap.system_call_filter为true进行检测,所以导致检测失败

    bootstrap.memory_lock: false
    bootstrap.system_call_filter: false
    

    2.3 问题

    1. 外网访问不了9200的Elasticsearch?

    1. 配置防火墙端口
    2. 修改elasticsearch.yml,主要是要修改host(我改成0.0.0.0,方便调试,后期稳定之后会再修改)

    2. 启动报错

    • vm.max_map_count过小,java虚拟机的virtual memory过小

    在/etc/sysctl.conf最后加入一行vm.max_map_count=262144数量根据实际情况定


    在这里插入图片描述
    • max user threads过小(root和dves两个用户的max user threads不一样)

    针对这个问题,可以通过ulimit -a查看目前可支持的max user threads

    在这里插入图片描述

    修改 max user process

    Linux系统为每一个用户都设置了一个最大进程数,这个特性可以让我们控制服务器上现有用户可以创建的进程数量

    1. 修改方式1:

    修改/etc/security/limits.conf文件,添加以下配置

    ## 针对所有用户的可开启最大线程数为4096
    *  soft      nproc      4096
    *  hard      nproc      4096
    
    1. 修改方式2:

    修改/etc/security/limits.d/90-nproc.conf文件,添加以下配置(先把其他默认的给注释掉):

    *          soft    nproc     4096  ## 非root用户配置为4096,这个对es来说够用了
    root       soft    nproc     unlimited  ## root用户配置最大 128354
    

    针对这两种修改方式解释下,我是在 /etc/security/limits.d/90-nproc.conf这个文件下修改的。对于max user process的配置,Linux系统默认先读取/etc/security/limits.conf中的信息,如果/etc/security/limits.d/目录下还有配置文件的话,也会依次遍历读取,最终/etc/security/limits.d/的配置会覆盖/etc/security/limits.conf的相同配置信息

    3. FileBeat搭建

    3.1 Filebeat下载安装

    curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.4.2-x86_64.rpm
    
    rpm -vi filebeat-7.4.2-x86_64.rpm
    

    安装完成,filebeat命令已配置到service服务中,配置文件在/etc/filebeat,日志文件在/var/log/filebeat/filebeat,注意,每次重启filebeat的时候,该日志文件都会重新生成,这个时候若如果你是通过tail命令来观察的,需要结束当前的tail命令再重复执行一次tail命令 tail -900f filebeat

    3.2 Filebeat收集nginx访问日志

    3.2.1 nginx的访问日志格式及配置

    nginx访问日志是如何配置的,我这里不细说,我只是说下我是如何配置的,如果对nginx的访问日志配置不熟悉的,可以查看这个:ngx_http_log_module

    1. 日志格式

    因为我们最终要通过Kibana进行展示的,我们需要对访问日志的每个字段都进行解析,所以我们就需要确定nginx的日志是json格式的

    ## 这个是写在http模块的
    log_format json_main  '{"@times" : "$time_iso8601",' ## 该time作为Kibana的date类型,在创建Kibana的index_pattern时作为时间筛选的key
                            '"userAgent" : "$http_user_agent",'
                            '"remoteAddr" : "$remote_addr", '
                            '"realIp" : "$http_x_forwarded_for", '
                            '"requestUri" : "$request", '
                            '"status" : "$status", '
                            '"referer" : "$http_referer", '
                            '"requestTime" : "$request_time", '
                            '"requestBody" : "$request_body", '  ## 请求数据
                            '"domoCustom" :  "$http_domo_custom"}';  ## 自定义请求头
    
    2. 打开请求日志

    对map模块有兴趣的可以查看这里:ngx_http_map_module

    ## 这个在server模块
    access_log /opt/nginx/logs/requestLog.log  json_main  if=$myUri;
    
    ## /opt/nginx/logs/requestLog.log:这个是日志收集的地方,若该日志不存在,在reload或重启nginx的是,会自动创建
    ## json_main:`log_format`定义的日志格式名
    ## if=$myUri:一个判断,如果`$myUri`为0或者空字符串,则该日志不收集。这个的作用可以过滤掉一些我们不想收集的日志信息,我是根据请求头来设置的。
    
    ## 这个写在http模块,使用map这个内置模块,可以通过判断`$request`这个
    ## 内置变量是否符合下面的判断,然后把0或1赋值给`$myUri`.
    ## 这里我的用法就是,如果是OPTIONS请求为0不记录日志信息,
    ## 如果是`/api/qiqyu`这个第三方的请求也为0不记录日志信息
    ## 其他的`/api/`正则的则为1记录日志信息
    ## 非上面集中情况的一律为0不记录相应的日志信息
     map $request $myUri {
           ~OPTIONS 0;
           ~/api/qiyu/ 0;
           ~/api/ 1;
           default 0;
      }
    

    reloadnginx之后就能在/opt/nginx/logs/requestLog.log这个文件夹下看到相应的日志了

    在这里插入图片描述

    3.3 Filebeat配置

    3.3.1 基本配置文件配置

    在这里插入图片描述
    vim /etc/filebeat/filebeat.yml 
    
    1. Filebeat inputs
    - type: log
    
      # Change to true to enable this input configuration.
      enabled: true  ## 打开开关
      exclude_lines: ['^DBG']  ## 忽略的行
      # Paths that should be crawled and fetched. Glob based paths.
      paths:
        #- /var/log/*.log
        - /opt/nginx/logs/requestLog.log  ## 配置从哪里按行读取日志
            #- c:\programdata\elasticsearch\logs\*
      ## 如果要让filebeat输入json格式的数据,除了nginx的日志本身是json格式
      ## 的外,还必须在filebeat中配置一下设置
      json.keys_under_root: true
      json.overwrite_keys: true
      json.add_error_key: true
      json.message_key: message  ## 如果message在启动的时候报错,可以改成"json"(带双引号)  
    
    2. Elasticsearch template setting
    setup.ilm.enabled: false  ## 这个必须要配置成false,否则自定义index就不会生效
    setup.template.enabled: false  ## 关掉filebeat默认的es模板
    setup.template.overwrite: true ## 表示我们自定义的模板和index会覆盖默认的
    setup.template.fields: "/etc/filebeat/self/fields.yml"  ## 自定义的fields.yml,这个文件不熟悉的话就别瞎折腾了,我直接从原来的copy了一份而已
    setup.template.name: "nginx-access-log"  ## 模板名,这个和后面要创建的es模板名保持一致
    setup.template.pattern: "nginx-access-log-*"  ## 模板对应的pattern,也是对应的index,这些都是有规律的。因为你模板名是`nginx-access-log`,则你接下来的自定义索引名就最好是`nginx-access-log-%{[agent.version]}-%{+yyyy.MM.dd}`,pattern的正则就是`nginx-access-log-*`
    
    3. Dashboards(这个配置可不配,主要是看你的filebeat是否安装了默认看板,这个安装后会生效的前提是:你必须使用filebeat的默认模板,默认索引,一旦你执行了上面第二步,这里的配置就不会生效)
    setup.dashboards.enabled: true
    setup.dashboards.index: "nginx-access-log-*"
    
    4. Kibana
    setup.kibana:
      host: "192.168.1.57:5601"
      # 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: "localhost:5601"
    
    5. Outputs(Elasticsearch)
    #-------------------------- Elasticsearch output ------------------------------
    output.elasticsearch:
      # Array of hosts to connect to.
      hosts: ["192.168.1.57:9200"]
      ## 这里的index的前缀要和上面第二步配置的模板名保持一致,而且,index的名字中不能包含大写字母,这是我的教训来着
      index: "nginx-access-log-%{[agent.version]}-%{+yyyy.MM.dd}"
      # Optional protocol and basic auth credentials.
      #protocol: "https"
      #username: "elastic"
      #password: "changeme"
    

    3.3.2 启用nginx模块

    其实对于filebeat中,它提供了多个模块,比如nginx,mysql等,这些能够让我们快速地上手filebeat。但是我一直搞不懂这些模块的用途是什么,明明我可以在filebeat.yml中配置的。nginx的模块格式如下:

    我虽然安装了该模块,但是该模块我是关掉的,一方面是我对该模块的理解不够,我不启用该模块也能正常收集日志,另一方面,开启该模块的时候,在收集日志的时候会不定时地报错Provided Grok expressions do not match field value:

    # Module: nginx
    # Docs: https://www.elastic.co/guide/en/beats/filebeat/7.4/filebeat-module-nginx.html
    
    - module: nginx
      # Access logs
      access:
        enabled: false
        var.paths: ["/opt/nginx/logs/requestLog.log"]
    
       # Set custom paths for the log files. If left empty,
        # Filebeat will choose the paths depending on your OS.
        #var.paths:
    
      # Error logs
      error:
        enabled: false
    
        # Set custom paths for the log files. If left empty,
        # Filebeat will choose the paths depending on your OS.
        #var.paths:
    
    安装过程

    在配置好filebeat.ymt后执行如下命令:

    filebeat modules enable nginx
    

    3.3.3 启动filebeat模块

    filebeat setup
    service filebeat start
    

    4. Kibana搭建

    4.1 Kibana下载安装

    注意:如果es是7版本,那么kibana的版本也要是7,两者之间的大版本要互相对应

    wget https://artifacts.elastic.co/downloads/kibana/kibana-7.4.2-linux-x86_64.tar.gz
    
    ## 解压缩后即可使用
    tar -zxvf kibana-7.4.2-linux-x86_64.tar.gz
    

    4.2 Kibana配置

    vim kibana.yml
    
    ## 端口号,默认5601
    #server.port: 5601
    ## 指定kibana指定的IP
    server.host: "192.168.1.57"
    ## 因为我的kibana和Elasticsearch是在同一台机器上的,所以我不需要去配置es的IP和端口等信息,kibana会自动在本机寻找
    #elasticsearch.hosts: ["http://localhost:9200"]
    

    4.2.1 自定义Elasticsearch的template

    这个template_nameindex_patterns要和前面我们在Elasticsearch中配置的一致。除了template_nameindex_patterns要修改外,还有一个要修改的地方就是mapping,这个因人而异,我觉得默认的mapping输出太多我不需要用到的东西,所以才去简化的,其余的都保持默认。新建好template后重启filebeat即可。重启filebeat之前建议把nginx的访问日志也清空掉,免得有脏数据影响

    mapping信息:
    {
      "_meta": {
        "beat": "filebeat",
        "version": "7.4.2"
      },
      "dynamic_templates": [
        {
          "labels": {
            "path_match": "labels.*",
            "mapping": {
              "type": "keyword"
            },
            "match_mapping_type": "string"
          }
        },
        {
          "container.labels": {
            "path_match": "container.labels.*",
            "mapping": {
              "type": "keyword"
            },
            "match_mapping_type": "string"
          }
        },
        {
          "dns.answers": {
            "path_match": "dns.answers.*",
            "mapping": {
              "type": "keyword"
            },
            "match_mapping_type": "string"
          }
        },
        {
          "fields": {
            "path_match": "fields.*",
            "mapping": {
              "type": "keyword"
            },
            "match_mapping_type": "string"
          }
        },
        {
          "docker.container.labels": {
            "path_match": "docker.container.labels.*",
            "mapping": {
              "type": "keyword"
            },
            "match_mapping_type": "string"
          }
        },
        {
          "kubernetes.labels.*": {
            "path_match": "kubernetes.labels.*",
            "mapping": {
              "type": "keyword"
            },
            "match_mapping_type": "*"
          }
        },
        {
          "kubernetes.annotations.*": {
            "path_match": "kubernetes.annotations.*",
            "mapping": {
              "type": "keyword"
            },
            "match_mapping_type": "*"
          }
        },
        {
          "docker.attrs": {
            "path_match": "docker.attrs.*",
            "mapping": {
              "type": "keyword"
            },
            "match_mapping_type": "string"
          }
        },
        {
          "cef.extensions": {
            "path_match": "cef.extensions.*",
            "mapping": {
              "type": "keyword"
            },
            "match_mapping_type": "string"
          }
        },
        {
          "kibana.log.meta": {
            "path_match": "kibana.log.meta.*",
            "mapping": {
              "type": "keyword"
            },
            "match_mapping_type": "string"
          }
        },
        {
          "strings_as_keyword": {
            "mapping": {
              "ignore_above": 1024,
              "type": "keyword"
            },
            "match_mapping_type": "string"
          }
        }
      ],
      ## 这里是指是否要指定一个key作为date类型来进行时间筛选,如果不为true,
      ## 后面你就无法根据@times进行时间筛选
      "date_detection": true
    }
    
    在这里插入图片描述 在这里插入图片描述

    4.2.2 devtool工具查询

    在未建立kibana的index_pattern之前,我们是无法在discover发现面板上去查看自己的数据的,这个时候我们并不着急去创建index_pattern,我们要先验证一下日式数据是否已成功收集。打开kibana的dev tool

    在这里插入图片描述
    1. 查看目前es中的索引,确认我们的自定义索引是否已生成
    get _cat/indices?v
    

    这个索引出现了表明索引已自动生成了


    在这里插入图片描述
    2. 查看该索引目前的数据,是否符合我们预期
    GET /nginx-access-log-7.4.2-2019.11.18/_search
    

    数据结果是json格式的,而且我们需要的数据都有,符合我们的预期。


    在这里插入图片描述

    4.2.3 自定义index_pattern

    在上面的步骤确认好之后,就可以创建kibana的index_pattern

    在这里插入图片描述
    在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

    4.2.3 Discover功能

    选择刚我们创建的index_pattern就可以看到和我们index_pattern格式相对应的数据了

    在这里插入图片描述

    4.2.4 Visualize功能

    新建一个可视化的图表,它里面帮我们内嵌了多个图表,但数据源都不是我们自定义的数据,可以参考,但是没多大意义,我们可以自己创建。


    在这里插入图片描述
    在这里插入图片描述 在这里插入图片描述 在这里插入图片描述

    4.2.5 Dashboard功能

    多个 Visualize放在一起就是一个面板,这里不多赘述,没什么技术含量

    5. 参考链接

    开始使用Filebeat
    快速开始Elasticsearch
    Es的官网教学
    自定义index template
    Filebeat自定义index的一个坑
    Filebeat模块与配置
    Linux修改max user threads
    ElkStack运维手册
    Es中文手册
    nginx中文地址

    6. 总结

    搭建这个简单的ELK还是花费了我一些时间的,一方面主要是我太久没接触ES,另一方面我对filebeat和kibana一直都是一知半解的状态。在搭建的过程中,没有像我上面写得那么顺利,一路磕磕碰碰,遇到很多问题,最后通过查询大量资料加上自己的理解才终于搞定。大家如果在搭建的时候有不明白的可以直接联系756795605@qq.com这个邮箱

    相关文章

      网友评论

        本文标题:简单的ELK搭建

        本文链接:https://www.haomeiwen.com/subject/nehqwctx.html