Docker通过EFK(Elasticsearch + Fluentd + Kibana)查询日志

发布时间:2020-04-03 09:59:58编辑:admin阅读(3038)

    一、概述

    Elasticsearch是一个开源搜索引擎,以易用性着称。kibana是一个图形界面,可以在上面条件检索存储在ElasticSearch里数据,相当于提供了ES的可视化操作管理器。

    fluentd

    fluentd是一个针对日志的收集、处理、转发系统。通过丰富的插件系统,可以收集来自于各种系统或应用的日志,转化为用户指定的格式后,转发到用户所指定的日志存储系统之中。

    fluentd 常常被拿来和Logstash比较,我们常说ELK,L就是这个agent。fluentd 是随着Docker,GCP 和es一起流行起来的agent。

    这篇文章里概括一下的话,有以下区别:

    • fluentd 比 logstash 更省资源;

    • 更轻量级的 fluent-bid 对应 filebeat,作为部署在结点上的日志收集器;

    • fluentd 有更多强大、开放的插件数量和社区。插件列表这一点值得多说,插件太多了,也非常灵活,规则也不复杂。

     

    基本的架构

    1.png

     

     

    这里主要解决的问题是日志查询,日志来源是docker。我们使用docker部署任务时,可以使用docker logs -f <容器id>查看日志,也可以去/var/lib/docker/containers/<容器id>/<容器id>-json.log查看日志文件。但是这都很难去做查询,本文介绍的EFK就可以解决这个问题。

    我们会创建四个容器:

     

    环境说明:

    请安装最新的docker及docker-compose,老版本会有些问题。

    docker安装,请参考链接:

    https://www.cnblogs.com/xiao987334176/p/11771657.html

    docker-compose安装,请参考链接:

    https://www.cnblogs.com/xiao987334176/p/12377113.html

     

    操作系统:centos 7.6

    配置:2核8g

    docker版本:19.03.6

    docker-compose版本:1.24.1

     

    本文使用一台centos7.6服务器,来演示EFK。

    注意:内存至少在4g或者以上。

     

    二、docker-compose运行EFK

    目录结构

     创建一个空目录

    mkdir /opt/efk/

    目录结构如下:

    ./
    ├── docker-compose.yml
    └── fluentd
        ├── conf
        │   └── fluent.conf
        └── Dockerfile

     

    docker-compose.yml

    version: '2'
    services:
      web:
        image: httpd
        ports:
          - "1080:80" #避免和默认的80端口冲突
        links:
          - fluentd
        logging:
          driver: "fluentd"
          options:
            fluentd-address: localhost:24224
            tag: httpd.access
    
      fluentd:
        build: ./fluentd
        volumes:
          - ./fluentd/conf:/fluentd/etc
        links:
          - "elasticsearch"
        ports:
          - "24224:24224"
          - "24224:24224/udp"
    
      elasticsearch:
        image: elasticsearch:7.6.0
        environment:
          - discovery.type=single-node
        expose:
          - 9200
        ports:
          - "9200:9200"
    
      kibana:
        image: kibana:7.6.0
        links:
          - "elasticsearch"
        ports:
          - "5601:5601"

    注意:elasticsearch 7.6.0要使用单机模式,必须传入环境变量discovery.type=single-node

     

    所有web里的日志会自动发送到fluentd-address: localhost:24224,也就是fluentd容器。

    Elasticsearch 和 Kibana是目前最新的版本7.6.0,如果想要选择更新的,可以去这里查看

    Elasticsearch image tags in DockerHub

    Kibana image tags in DockerHub

     

    Fluentd的配置和插件

    新建文件fluentd/Dockerfile,使用官方镜像Fluentd’s official Docker image,安装需要的插件

    # fluentd/Dockerfile
    FROM fluent/fluentd:v0.12-debian
    RUN ["gem", "install", "fluent-plugin-elasticsearch", "--no-rdoc", "--no-ri", "--version", "1.9.7"]

    然后新建文件fluentd/conf/fluent.conf,编写Fluentd的配置文件

    <source>
      @type forward
      port 24224
      bind 0.0.0.0
    </source>
    <match *.**>
      @type copy
      <store>
        @type elasticsearch
        host elasticsearch
        port 9200
        logstash_format true
        logstash_prefix fluentd
        logstash_dateformat %Y%m%d
        include_tag_key true
        type_name access_log
        tag_key @log_name
        flush_interval 1s
      </store>
      <store>
        @type stdout
      </store>
    </match>

    官方设置文档config-file

     

    修改/etc/sysctl.conf 

    此参数一定要改,否则Elasticsearch 无法启动

    vm.max_map_count = 2621440

    加载配置

    sysctl -p

     

    启动容器

    在后台启动,使用docker-compose up -d

    # docker-compose up -d
    Starting efk_elasticsearch_1 ... done
    Starting efk_fluentd_1       ... done
    Starting efk_kibana_1        ... done
    Starting efk_web_1           ... done

    查看所有容器

    复制代码

    # docker ps
    CONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS              PORTS                                                          NAMES
    d82b1a16c970        httpd                 "httpd-foreground"       21 hours ago        Up 51 minutes       0.0.0.0:1080->80/tcp                                           efk_web_1
    1085be0f9c6e        efk_fluentd           "tini -- /bin/entryp…"   21 hours ago        Up 51 minutes       5140/tcp, 0.0.0.0:24224->24224/tcp, 0.0.0.0:24224->24224/udp   efk_fluentd_1
    3e837917f4cf        kibana:7.6.0          "/usr/local/bin/kiba…"   21 hours ago        Up 51 minutes       0.0.0.0:5601->5601/tcp                                         efk_kibana_1
    3d860ca7e0db        elasticsearch:7.6.0   "/usr/local/bin/dock…"   21 hours ago        Up 51 minutes       0.0.0.0:9200->9200/tcp, 9300/tcp                               efk_elasticsearch_1

    复制代码

     

    产生日志

    使用curl执行3遍

    curl http://localhost:1080/
    curl http://localhost:1080/
    curl http://localhost:1080/

    查看日志

    打开http://localhost:5601,提示需要先建索引,输入fluentd-*刷新即可

    1.png

     

     

    选择时间戳

    1.png

     

     

     

     去Discover页面,然后就可以看到之前的日志了。

    1.png

     

     

    如何接入其他docker日志

    这里是以docker-compose形式启动的一个服务,如果还有别的任务需要将日志发送到fluentd,需要这几个步骤。

    默认情况下,docker-compose会为我们的应用创建一个网络,服务的每个容器都会加入该网络中。这样,容器就可被该网络中的其他容器访问,不仅如此,该容器还能以服务名称作为hostname被其他容器访问。

    所以我们首先需要找到我们现在创建的EFK的网络名,

    复制代码

    # docker network ls
    NETWORK ID          NAME                DRIVER              SCOPE
    afa576d45dff        bridge              bridge              local27d56becedb8        efk_default         bridge              local1d5b4653e1df        host                host                local
    901f8a349049        none                null                local

    复制代码

     

    我是在efk目录下创建的docker-compose.yml文件,所以这里默认的名字就是efk_default。

    再看看之前web的设置

    web:
        image: httpd
        ports:
          - "1080:80" #避免和默认的80端口冲突
        links:
          - fluentd
        logging:
          driver: "fluentd"
          options:
            fluentd-address: localhost:24224
            tag: httpd.access

    有几个关键设置是:links和logging,link 用于容器直接的互通,logging则是日志的输出设置。

    那我们这里再启动一个新docker需要这些设置

    docker run \
        --link efk_fluentd_1 \
        --net efk_default  \
        --log-driver=fluentd \
        --log-opt fluentd-address=localhost:24224 \
        --log-opt tag=httpd.access \
        -d hello-world

    我们去kibana看看,果然,日志已经发送到kibana了。

    搜索hello

    1.png

    如果是其他机器,需要指定fluentd ip,比如:

    docker run \
        --log-driver=fluentd \
        --log-opt fluentd-address=172.19.155.138:24224 \
        --log-opt tag=httpd.access \
        -d hello-world

    最后想要做的就是如何在一台服务器上搜集所有的日志,理论上来说,只需要一台服务器部署上EFK,暴露端口,其他服务器去发送即可,实际上还没试过。

     

    本文参考链接:

    https://zhuanlan.zhihu.com/p/63105931


关键字