当前位置:   article > 正文

EFK(Elasticsearch+Fluentd+Kibana)部署手册_docker部署efk (elasticsearch,fluentbit,kibana)

docker部署efk (elasticsearch,fluentbit,kibana)

(Elasticsearch+Fluentd+Kibana)EFK部署手册

最近需要用到容器日志收集,目前比较流行的应该是EL(Logstash)K,EF(Fluentd)K,相比之下Fluentd要比Logstash轻量级,所以决定采用Fluentd。因此产生了此文档.

本文主要是通过docker-compose部署Elasticsearch + Fluentd + Kibana部署相关服务,并支持在多个docker-compose中收集不同容器产生的日志.

1.准备

1.1镜像拉取

docker pull kibana:7.6.0
docker pull elasticsearch:7.6.0
docker pull fluent/fluentd:v1.3.2
  • 1
  • 2
  • 3

1.2准备配置文件

准备fluentd配置文件和制作镜像的Dockerfile文件,fluent.conf这个是fluentd启动的配置文件.目录结构如下:

efk
  |fluentd
     | conf
    	|---fluent.conf
  	 |Dockerfile
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

其中 efk,fluentd,conf是文件夹, fluent.conf和Dockerfile是文件.

这个是fluent.conf里面的具体内容

<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>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

1.3 准备Dockerfile文件

FROM fluent/fluentd:v1.3.2
USER root
RUN echo "source 'https://mirrors.tuna.tsinghua.edu.cn/rubygems/'" > Gemfile && gem install bundler
RUN gem install fluent-plugin-elasticsearch -v 4.0.3 --no-document
CMD ["fluentd"]
  • 1
  • 2
  • 3
  • 4
  • 5

1.4 准备部署的yml文件

version: '2'
services:
  web:
    image: httpd
    ports:
      - "1080:80"
    links:
      - fluentd
    logging:
      driver: "fluentd"
      options:
        fluentd-address: localhost:24224
        tag: httpd.access
    container_name: web
  
  app_v1:
    image: app:v1
    ports:
      - "9090:9090"
    links:
      - fluentd
    logging:
      driver: "fluentd"
      options:
        fluentd-address: localhost:24224
        tag: app.h1
    container_name: app_v1
  
  fluentd:
    build: ./fluentd
    volumes:
      - ./fluentd/conf/:/etc/fluent/
    links:
      - "elasticsearch"
    ports:
      - "24224:24224"
      - "24224:24224/udp"
    container_name: fluentd

  elasticsearch:
    image: elasticsearch:7.6.0
    environment:
      - discovery.type=single-node
    expose:
      - 9200
    ports:
      - "9200:9200"
    container_name: elasticsearch

  kibana:
    image: kibana:7.6.0
    environment:
      I18N_LOCALE: "zh-CN"
    links:
      - "elasticsearch"
    ports:
      - "5601:5601"
    container_name: kibana
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58

1.5 准备能够输出日志的镜像

镜像一

docker pull httpd:latest
  • 1

镜像二

是自己制作的python镜像,需要依赖镜像python3.7.9 .首先得拉取下面的镜像

docker pull python:3.7.9
  • 1

镜像拉取完成后准备好一个简单的flask项目文件项目的目录结构如下,testapp是目录,app.pyDockerfile是文件.

test
  |app
    |---app.py
  |Dockerfile
  • 1
  • 2
  • 3
  • 4

app.py的文件内容如下:

#!/usr/bin/python
# -*- coding: UTF-8 -*
"""
@file_name: app.py
@author:lzl
@create date: 2021/3/30 0004 13:12
@description:
@update date: 
@file url:
@git path:
"""


from flask import Flask, request, jsonify

app = Flask(__name__)


@app.route('/')
def hello_world():
    a = {
        'code': 200,
        'msg': 'OK',
        'data': [1, 3, 4, 5]
    }
    return jsonify(a)

if __name__ == "__main__":
    app.run(host='0.0.0.0',port=9090)

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

这样在准备制作镜像二的Dockerfile文件,内容如下

FROM python:3.7.9
USER root
RUN pip install flask
COPY app /var/app
WORKDIR /var/app
EXPOSE 9090
CMD python app.py
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

为了测试我弄得比较简单.进入xxx/test/目录 Dockerfile目录执行

docker build -t app:v1 .
  • 1

完成app:v1镜像的构建.

1.6 不同docker-compose文件

version: '2'
services:
  app_v2:
    image: app:v1
    ports:
      - "9091:9090"
    external_links:
      - fluentd
    logging:
      driver: "fluentd"
      options:
        fluentd-address: 192.169.0.141:24224
        tag: app.h2
    container_name: app_v2
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

external_links : 用于链接到外部容器。所有容器需要在同一个网络中

1.7 kibana配置文件

配置文件路径/usr/share/kibana/kibana.yml

#
# ** THIS IS AN AUTO-GENERATED FILE **
#
# Default Kibana configuration for docker target
server.name: kibana
server.host: "0"
elasticsearch.hosts: [ "http://elasticsearch:9200" ]
xpack.monitoring.ui.container.elasticsearch.enabled: true
i18n.locale: zh-CN
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

1.8 elasticsearch基础配置文件

配置文件路径/usr/share/elasticsearch/elasticsearch.yml

cluster.name: "docker-cluster"
network.host: 0.0.0.0
  • 1
  • 2

2.启动

2.1 场景一

docker-compose文件的容器日志收集,首先启动同一个docker-compose文件里面的服务进行收集.启动命令,在有文件docker-compose.yml文件的目录执行如下命令

docker-compose up -d
  • 1

在这里插入图片描述

查看服务运行状态

在这里插入图片描述

这样界面通过访问 192.169.0.141:5601打开kibana UI界面

在这里插入图片描述

点击试用我的样例数据,进入

在这里插入图片描述

添加索引如图

在这里插入图片描述
点击创建索引模式
在这里插入图片描述

选择索引时间筛选字段名称,我这里选择的是@timestamp

在这里插入图片描述

点击创建索引模式

在这里插入图片描述

然后在点击Discover

在这里插入图片描述

这样就能看见相关的日志了.这样只要安装的服务在控制台有产生日志输出就能看见日志了

在这里插入图片描述

上图标红的就是我们启动的容器的服务名称.我们就完成了容器为web和app_v1两个容器的日志收集.

2.2 场景二

场景一只解决了在同一个docker-compose中容器日志的收集.然而实际工作中会存在启动多个docker-compose文件的容器日志收集,我们只需要配置为两个docker-compose能够通信,这样先启动场景一的docker-compose,然后在启动ext.yml里面配置的另外一个服务.具体启动命令如下:

docker-compose up -d
docker-compose -f ext.yml up -d
  • 1
  • 2

重新刷新kibana就能看见另外一个docker-compose部署的服务日志也被有效的收集起来了.

在这里插入图片描述

2.3 场景三

在windows系统中安装日志收集器,并完成日志收集.这是自己模拟的一个定时日志数据源.

# !/usr/bin/python
# -*- coding: utf-8 -*-
"""
 @file_name  : test_log.py
 @author     : lzl
 @create date: 2021/4/1 0001 10:40
 @description:
 @update date:
 @file url   :
 @git path   :
"""
import time
import logging
import os
import random
# 1.创建1个logger:
from logging import handlers

mylog = logging.getLogger("Error")


def init_log():
    log_path = os.getcwd() + "/log"
    try:
        if not os.path.exists(log_path):
            os.makedirs(log_path)
    except:
        print("创建日志目录失败")
        exit(1)
    if len(mylog.handlers) == 0:  # 避免重复
        # 2.创建handler(负责输出,输出到屏幕streamhandler,输出到文件filehandler)
        filename = os.path.join(log_path, 'cscips.log')
        # fh = logging.FileHandler(filename,mode="a",encoding="utf-8")#默认mode 为a模式,默认编码方式为utf-8
        sh = logging.StreamHandler()  
        fh = handlers.TimedRotatingFileHandler(filename=filename, when="D", interval=2, backupCount=3,
                                               encoding="utf-8")  #
        fh.suffix = "%Y-%m-%d.log"
        # 3.创建formatter:
        formatter = logging.Formatter(
            fmt='%(asctime)s - %(levelname)s - Model:%(filename)s - Fun:%(funcName)s - Message:%(message)s - Line:%(lineno)d')
        # 4.绑定关系:①logger绑定handler
        mylog.addHandler(fh)
        mylog.addHandler(sh)
        # # ②为handler绑定formatter
        fh.setFormatter(formatter)
        sh.setFormatter(formatter)
        # # 5.设置日志级别(日志级别两层关卡必须都通过,日志才能正常记录)
        # mylog.setLevel(40)
        # fh.setLevel(40)
        # sh.setLevel(40)
        mylog.setLevel('INFO')
        fh.setLevel('INFO')
        sh.setLevel('INFO')


def log_record(level):
    if level == 'INFO':
        msg = '处理请求或者状态变化等日常事务'
        mylog.info(f'{msg} - {time.time()}')
        time.sleep(15)
    elif level == 'ERROR':
        msg = '发生错误时,如IO操作失败或者连接问题'
        mylog.error(f'{msg} - {time.time()}')
        time.sleep(30)
    elif level == 'WARNING':
        msg = '发生很重要的事件,但是并不是错误时,如用户登录密码错误'
        mylog.warning(f'{msg} - {time.time()}')
        time.sleep(20)
    elif level == 'CRITICAL':
        msg = '特别糟糕的事情,如内存耗尽、磁盘空间为空,一般很少使用'
        mylog.critical(f'{msg} - {time.time()}')
        time.sleep(60)
    elif level == 'DEBUG':
        msg = '调试过程中使用DEBUG等级,如算法中每个循环的中间状态'
        mylog.debug(f'{msg} - {time.time()}')
        time.sleep(5)
    else:
        msg = '致命错误'
        mylog.debug(f'{msg} - {time.time()}')
        time.sleep(120)


while True:
    init_log()
    """
    日志等级:使用范围
    FATAL:致命错误
    CRITICAL:特别糟糕的事情,如内存耗尽、磁盘空间为空,一般很少使用
    ERROR:发生错误时,如IO操作失败或者连接问题
    WARNING:发生很重要的事件,但是并不是错误时,如用户登录密码错误
    INFO:处理请求或者状态变化等日常事务
    DEBUG:调试过程中使用DEBUG等级,如算法中每个循环的中间状态
    """
    l = ['INFO', 'ERROR', 'WARNING', 'DEBUG', 'FATAL', 'CRITICAL']
    s = random.choice(l)
    log_record(s)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96

windows中使用filebeat可以完成日志的采集,首先得下载好windows版本的filebeta.我这里下载的zip包,直接解压就能够使用.

filebeat-7.12.0-windows-x86_64.zip
  • 1

解压后的目录结构为

在这里插入图片描述

有了这个文件我们需要修改filebeat.yml中的配置项为

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:
  	# 配置日志文件的路径
    - E:\TestDemo\loging\log\*.log
    
setup.kibana:
  host: "192.169.0.234:5601"
  

output.elasticsearch:
  # Array of hosts to connect to.
  hosts: ["192.169.0.234:9200"]

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

然后使用 cmd进入解压好的filebeat目录,执行启动命令

filebeat.exe -e -c filebeat.yml 
  • 1

这样filebeat windows版本的日志收集器就安装成功了 我们就可以进入kibana中配置好相应的索引,然后就可以通过Discover 选择创建好的索引就能看见收集到的日志了.

在这里插入图片描述

3.注意事项

kibana设置默认语言为中文,配置文件/usr/share/kibana/config/kibana.yml中添加

i18n.locale: "zh-CN"
  • 1

redis日志标准输出,在配置文件中注释 logfile配置

logfile
  • 1

nginx日志文件标准输出配置

error_log /dev/stdout warn;
access_log /dev/stdout main;
  • 1
  • 2

gunicorn日志标准输出配置

accesslog='-'
  • 1

uwsgi 日志标准输出配置

log-master=true
  • 1

elasticsearch配置和数据文件

/usr/share/elasticsearch/config/elasticsearch.yml
/usr/share/elasticsearch/data
  • 1
  • 2

kibana配置和数据文件

/usr/share/kibana/config/kibana.yml
/usr/share/kibana/data
  • 1
  • 2
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小蓝xlanll/article/detail/587609
推荐阅读
相关标签
  

闽ICP备14008679号