Docker ELK + docker-compose + filebeat部署教程

前言

目前主流日志采集系统,采用elk + filebeat来实现,记录一下部署的流程。

1. 所需资源:docker运行环境

2. 安装镜像sebp/elk

// 拉取镜像
docker pull sebp/elk:7.12.0

3. 使用docker-compose启动容器

  1. 安装docker-compose
    详见 https://docs.docker.com/compose/install/
  2. 创建挂载镜像elk-data,记录elasticsearch的存储内容(以用于如果容器销毁后重新创建,也可以重新加载数据)
docker volume create elk-data
  1. 创建挂载镜像elk-log,记录所有elk内的log日志
docker volume create elk-log
// 可以查看elk-log具体的挂载信息
sudo docker volume inspect elk-log
// 如果需要映射到/var/log下面
sudo mkdir /var/log/elk
sudo mount --bind /var/lib/docker/volumes/elk-log/_data /var/log/elk/
  1. 临时启动镜像,用于copy配置文件下来
// 启动镜像
sudo docker run -d sebp/elk:7.12.0
// 创建应用目录
mkdir /opt/elk
mkdir /opt/elk/elasticsearch
mkdir /opt/elk/logstash
mkdir /opt/elk/kibana
// cp出各个单服务的配置文件
sudo docker cp CONTAINER_ID:/opt/kibana/config/kibana.yml /opt/elk/kibana/.
sudo docker cp CONTAINER_ID:/etc/logstash/conf.d/30-output.conf /opt/elk/logstash/.
sudo docker cp CONTAINER_ID:/etc/logstash/conf.d/11-nginx.conf /opt/elk/logstash/.
sudo docker cp CONTAINER_ID:/etc/elasticsearch/elasticsearch.yml /opt/elk/elasticsearch/.
// 销毁创建的容器
sudo docker stop CONTAINER_ID
sudo docker rm CONTAINER_ID
  1. 修改elasticsearch配置文件,/opt/elk/elasticsearch/elasticsearch.yml
## 结尾增加如下配置,用于启用登录权限(xpack安全验证)
xpack.security.enabled: true
xpack.license.self_generated.type: basic
xpack.security.transport.ssl.enabled: true
  1. 修改kibana的配置文件,/opt/elk/kibana/kibana.yml
## 增加中文配置
i18n.locale: "zh-CN"
## es 设置的kibana用户名称
elasticsearch.username: "kibana"
## es 设置的kibana用户名称,此处密码是在后续进行设置,先预设admin1
elasticsearch.password: "admin1"
  1. 修改logstash的配置文件,/opt/elk/logstash/30-output.conf
## 修改为如下配置
output {
  elasticsearch {
    hosts => ["localhost"]
    manage_template => false
    index => "%{[fields][type]}-%{+YYYY.MM.dd}" ## 生成索引key
    user => "elastic"
    password => "admin1" ## admin1也是预设,后续会进行配置
  }
}
  1. 创建docker-compose.yml配置文件,并放置在/opt/elk/目录下
elk:
    image: sebp/elk:7.12.0
    ports:
      - "5601:5601"
      - "9200:9200"
      - "5044:5044"
    volumes:
      - elk-data:/var/lib/elasticsearch
      - elk-log:/var/log
      - /opt/elk/kibana/kibana.yml:/opt/kibana/config/kibana.yml
      - /opt/elk/logstash/30-output.conf:/etc/logstash/conf.d/30-output.conf
      - /opt/elk/logstash/11-nginx.conf:/etc/logstash/conf.d/11-nginx.conf
      - /opt/elk/elasticsearch/elasticsearch.yml:/etc/elasticsearch/elasticsearch.yml
    environment:
      "ES_CONNECT_RETRY": "180" ## ES的启动最大允许时间
      "ES_HEAP_SIZE": "4g" ## ES的最大堆内存
      "LS_HEAP_SIZE": "1g" ## logstash的最大堆内存
    restart: always
    privileged: true ## 使docker内的elk拥有外部root权限
  1. 启动docker-compose
sudo docker-compose up -d elk
  1. 配置es密码
## 进入容器内部
sudo docker exec -it CONTAINER_ID /bin/bash
## 执行命令,交互式设置密码(注意保存好全部密码)
sh /usr/share/elastic/bin/elasticsearch-setup-passwords interactive
## 和之前在kibana和logstash内的配置文件设置的密码相同即可
  1. ES内置用户介绍
Elastic内置用户
elastic:内置超级用户
kibana:仅可用于kibana用来连接elasticsearch并与之通信, 不能用于kibana登录
logstash_system:用于Logstash在Elasticsearch中存储监控信息时使用
  1. 此时已经可以登录kibana了,http://IP:5601

4. 安装filebeat & Log4j配置

1. log4j的xml配置,filebeat读取固定格式的日志文件,解析到logstash内,此处展示一个推荐的log4j配置(其中LOG_PATTERN内的trace_id需要用到spring-cloud-sleuth,用于分布式链路追踪)
<?xml version="1.0" encoding="UTF-8"?>
<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
<!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出-->
<!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数-->
<configuration status="WARN" monitorInterval="30">

    <Properties>
        <!--格式化输出-->
        <property name="LOG_PATTERN" value="%p|%d{yyyy-MM-dd HH:mm:ss:SSS}|%X{X-B3-TraceId}|%15.15t|%c:%L| %msg%n"></property>
        <!--项目名称-->
        <property name="SERVICE_NAME" value="xxxx-service"></property>
        <!--日志路径-->
        <property name="FILE_PATH" value="/var/logs"></property>
    </Properties>

    <!--先定义所有的appender-->
    <appenders>
        !--这个输出控制台的配置-->
        <console name="Console" target="SYSTEM_OUT">
            <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
            <ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY"/>
            <!--输出日志的格式-->
            <PatternLayout charset="UTF-8" pattern="${LOG_PATTERN}"/>
        </console>
        <!-- 这个会打印出所有的info及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
        <RandomAccessFile name="RandomFileInfo" fileName="${FILE_PATH}/${SERVICE_NAME}/info.log"
                     filePattern="${FILE_PATH}/${SERVICE_NAME}/${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log">
            <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
            <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout charset="UTF-8" pattern="${LOG_PATTERN}"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="20 MB"/>
            </Policies>
            <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,这里设置了20 -->
            <DefaultRolloverStrategy max="20"/>
        </RandomAccessFile>
        <RandomAccessFile name="RandomFileWarn" fileName="${FILE_PATH}/${SERVICE_NAME}/warn.log"
                     filePattern="${FILE_PATH}/${SERVICE_NAME}/${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log">
            <ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout charset="UTF-8" pattern="${LOG_PATTERN}"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="20 MB"/>
            </Policies>
            <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,这里设置了20 -->
            <DefaultRolloverStrategy max="20"/>
        </RandomAccessFile>
        <RandomAccessFile name="RandomFileError" fileName="${FILE_PATH}/${SERVICE_NAME}/error.log"
                     filePattern="${FILE_PATH}/${SERVICE_NAME}/$${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log">
            <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout charset="UTF-8" pattern="${LOG_PATTERN}"/>
            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="20 MB"/>
            </Policies>
            <!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,这里设置了20 -->
            <DefaultRolloverStrategy max="20"/>
        </RandomAccessFile>
    </appenders>
    <!--然后定义logger,只有定义了logger并引入的appender,appender才会生效-->
    <loggers>
        <!--打印Sql Debug日志-->
        <logger name="xxxxxxxxx.dao" level="debug"/>
        <root level="info">
            <appender-ref ref="Console"/>
            <appender-ref ref="RandomFileInfo"/>
            <appender-ref ref="RandomFileWarn"/>
            <appender-ref ref="RandomFileError"/>
        </root>
    </loggers>
</configuration>
2. 机器上增加filebeat服务
  1. 按照filebeat官网的quickstart安装
    https://www.elastic.co/guide/en/beats/filebeat/current/setup-repositories.html

  2. https://github.com/spujadas/elk-docker/tree/master/nginx-filebeat内的logstash-beats.crt 下载到本地,copy到/etc/filebeat/.

  3. 修改/etc/filebeat/路径下的filebeat.yml

filebeat.inputs:
- type: log
  enabled: true
  paths:
     - /var/logs/xxxxx-service/info.log #修改为对应服务的日志地址
  fields:
     type: xxxxx-service-dev #输出的index索引
- type: log
  enabled: true
  paths:
     - /var/logs/yyyyyy-service/info*.log
  fields:
     type: yyyyyy-service-dev
setup.template.settings:
  index.number_of_shards: 1
filebeat.config.modules:
  path: ${path.config}/modules.d/*.yml
  reload.enabled: false
output.logstash:
  hosts: ["logstash_ip:5044"]
  ssl.certificate_authorities: ["/etc/filebeat/logstash-beats.crt"]
processors:
  - add_host_metadata:
      when.not.contains.tags: forwarded
  - add_cloud_metadata: ~
  - add_docker_metadata: ~
  - add_kubernetes_metadata: ~
  1. 修改之前elk对应的/app/elk/logstash/11-nginx.conf,修改完毕后重启elk的容器
## 在filter内增加如下配置,根据log4j的日志格式进行解析
grok {
    match => {"message" => "%{DATA:level}\|%{DATA:datetime}\|%{DATA:trace_id}\|%{DATA:thread_id}\|%{DATA:method_name}\|%{DATA:msg}$"}
    remove_field => ["message"]
  }
  1. 执行命令
sudo systemctl enable filebeat
sudo systemctl restart filebeat
3. elk上增加index索引
  1. elk上增加index索引,与刚刚filebeat内配置的filebeat.inputs.fields.type相同,需逐个配置
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容