docker-compose部署多个微服务,ELK日志收集方案

目录

一、背景描述

二、初始方案

三、最终方案



一、背景描述

       项目是微服务架构,一共包含了二十几微服务,通过docker-compose部署到docker,即二十几个container。

      需求:项目集成ELK,实现日志的集中可视化管理,方便查阅。

      方案:在日志所在服务器安装filebeat,通过filebeat将日志发送到logstash集群,日志经logstash过滤处理生成索引并发送到ES集群存储,最后通过kibana做日志可视化管理。

二、初始方案

      由于docker的默认日志驱动是json-file,每一个container的日志文件存放在 /{docker data目录}/containers/{containerid}/{containerid}-json.log中。由于有二十几个服务,故日志文件分别存放在二十几个以containerid命名的目录下。

      综上,filebeat的配置文件filebeat.yml的配置中需分别配置这二十几个container的日志文件作为filebeat inputs,如下:

#=========================== Filebeat inputs =============================

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
  enabled: true
  paths:
    - /data/docker_data/containers/207c82ab51fcd17aa20e33e243d15f181f985dfbc70ec7b5a4873333c3c2fe2e/207c82ab51fcd17aa20e33e243d15f181f985dfbc70ec7b5a4873333c3c2fe2e-json.log
  fields:
    service:
      category: test
      name: service001
  fields_under_root: true
  multiline:
    pattern: '^\{'
    negate: true
    match: after
    timeout: 5s

- type: log
  enabled: true
  paths:
    - /data/docker_data/containers/ab04020aee4d4c3ad8b656dbf4a2cfe8d5c704ec98ba5824189763cfbe7266d0/ab04020aee4d4c3ad8b656dbf4a2cfe8d5c704ec98ba5824189763cfbe7266d0-json.log
  fields:
    service:
      category: test
      name: service002
  fields_under_root: true
  multiline:
    pattern: '^\{'
    negate: true
    match: after
    timeout: 5s

......

配置中添加了自定义的字段fields.service.category和fields.service.name,该字段会传递至logstash,在logstash通过脚本过滤日志生成index时,可以用来区分日志来源,以便不同容器的日志以生成不同的index。

if [service][category] == "test" {
    elasticsearch{
        hosts => ["Elasticsearch的地址"]
        index => "%{[service][name]}-%{+yyyy.MM.dd}"
    }
}

最后在kibana中根据上图配置的index创建index pattern,即可实现各个服务日志的可视化查看。

问题思考:此方案虽然可以实现不同container日志的分类展示,但是存在2个弊端:

1、每个容器都需要配置,配置臃肿。

2、filebeat的配置中,容器的id是固定值,如果容器被删除后重建,容器的id会改变,若想收集到日志,则必须重新配置filebeat并重启,这非常麻烦。

于是便有了下面的最终方案。

三、最终方案

filebeat的input配置通配路径,如下:

#=========================== Filebeat inputs =============================

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
  enabled: true
  paths:
    - /data/docker_data/containers/*/*-json.log
  fields:
    service:
      category: test
  fields_under_root: true
  multiline:
    pattern: '^\{'
    negate: true
    match: after
    timeout: 5s

由于上述配置无法区分各个容器的日志,故需要修改docker-compose.yml配置,给日志添加tag用于区分不同容器的日志:

version: '3'
services:
  eureka-server:
    image: java
    restart: "always" #重启策略,能够使服务保持始终运行,生产环境推荐使用
    container_name: ${env}-eureka-server #容器名称
    volumes:
      - /opt/jar/eureka-server-0.0.1-SNAPSHOT.jar:/usr/eureka-server.jar
    network_mode: "host"
    ports:
      - 8761:8761
    entrypoint: java -jar -Xms1g -Xmx1g /usr/eureka-server.jar --spring.profiles.active=${env}
    environment:
      - TZ=Asia/Shanghai
    labels:
      - "servicename=eureka-server"
    logging:
      driver: "json-file"
      options:
        labels: "servicename"
        tag: "{{.ImageName}}/{{.Name}}"

上述配置会导致日志内容会追加当前服务的名字(servicename)eureka-server,logstash中判断日志是否包含字符串eureka-server,从而将日志归集到eureka-server-*的index

#logstash output设置#
if [service][category] == "test" {
	if "eureka-server" in [log_info] {
	  elasticsearch{
		hosts => ["Elasticsearch地址"]
		index => "eureka-server-%{+yyyy.MM.dd}"
	  }
	}
	......
}

至此,微服务日志集成ELK完美完成!

你可能感兴趣的:(docker,docker,docker-compose,微服务,elk)