efk日志系统--elasticsearch多宿主机集群+elasticsearch监控+kibana+fluentd

30 篇文章 1 订阅
27 篇文章 0 订阅


项目地址:

https://github.com/a18792721831/efk.git

本文只是简单的快速搭建一个efk系统,不涉及efk理论知识。

如果你不想了解我搭建的过程,只是想直接获取到一个能用的环境,请直接下载项目即可,下载完项目然后在自己的微服务中配置。

即使你不了解我搭建的过程,我也尽可能保证你能得到一个可用的efk环境,并且能快速的使用到项目中。但是了解我是如何搭建的能更好的帮助你解决可能出现的问题。

我所指的efk是elasticsearch+fluentd+kibana.

1. elasticsearch

elasticsearch我们选择使用6.8.13版本,使用docker方式部署。(fluentd只支持6.x系列)

首先在docker-hub上找到官方的镜像

image-20210225192722855

对于6.x系列,最新的就是6.8.13

image-20210225192803296

我默认你已经安装好了docker和docker-compose并且可以访问docker-io。

OK,现在镜像找到了,但是如何使用这个镜像呢?

image-20210225193217411

继续往下拉,能找到How to use小节,但是仅仅给出了单机启动的方式。

How to use中,也直接给出了elasticsearch的文档的地址elasticsearch-doc

image-20210225193353342

我们找到6.8版本的文档

image-20210225193425104

请记住,当我们有不知道的内容的时候,从这里找要比在网上找更快,更准确。

我们打开全部的目录

image-20210225193930079

然后搜索docker

image-20210225194006201

就能找到如何docker启动elasticsearch了(这里和在docker-hub中找到的结果相同)

区别在于,在线文档其实还给出了docker-compose的例子,我们要的就是docker-compose文件。

image-20210225194146888

docker-compose例子中是如何在1台宿主机中启动集群模式的elasticsearch.

在一台机器上启动集群,主要是把数据尽可能的分片。除去这个因素,没有什么时机意义。

1.1 单宿主机集群

我们将这个文件拷贝到linux中,并进行一定的修改,主要是设置一些环境变量

version: "3.2"
services:
  elasticsearch0:
    image: docker.elastic.co/elasticsearch/elasticsearch:6.8.13
    restart: always
    container_name: elasticsearch0
    hostname: elasticsearch0
    environment:
      - TZ=Asia/Shanghai
      - "ES_JAVA_OPTS=-Xms256m -Xmx256m"
      - cluster.name=elasticsearch-cluster
      - node.name=elasticsearch0
      - http.cors.enabled=true
      - http.cors.allow-origin="*"
    ports:
      - 9200:9200
    volumes:
      - /etc/localtime:/etc/localtime
      - ~/efk/elasticsearch0/data:/usr/share/elasticsearch/data
      - ~/efk/elasticsearch0/logs:/usr/share/elasticsearch/logs
      - ~/efk/elasticsearch0/plugins:/usr/share/elasticsearch/plugins
    networks:
      - outside
  elasticsearch1:
    image: docker.elastic.co/elasticsearch/elasticsearch:6.8.13
    restart: always
    container_name: elasticsearch1
    hostname: elasticsearch1
    environment:
      - TZ=Asia/Shanghai
      - "ES_JAVA_OPTS=-Xms256m -Xmx256m"
      - cluster.name=elasticsearch-cluster
      - node.name=elasticsearch1
      - http.cors.enabled=true
      - http.cors.allow-origin="*"
    volumes:
      - /etc/localtime:/etc/localtime
      - ~/efk/elasticsearch1/data:/usr/share/elasticsearch/data
      - ~/efk/elasticsearch1/logs:/usr/share/elasticsearch/logs
      - ~/efk/elasticsearch1/plugins:/usr/share/elasticsearch/plugins
    networks:
      - outside
networks:
  outside:
    external:
      name: efk

或许你很好奇,这些环境变量代表什么含义呢?我又从什么地方看呢?

很简单,在线文档。

当我们写出上面的docker-compose文件,我们就需要明白两个问题:1.环境变量;2.文件挂载。

我们打开在线文档目录直接搜索其中的cluster-name环境变量(这个环境变量是示例中的环境变量)

image-20210225195757916

在线文档中给出的重要的环境变量只有几个,不是完整的。

另外一种搜索方式是使用在线文档的搜索功能搜索

在在线文档的任意一个界面,基本上都有一个放大镜的图标

image-20210225203523796

点击后输入我们想要搜索的内容即可

image-20210225203553928

这样你就能搜索到全部的文档了

image-20210225203629355

比如找node.name这个属性
在这里插入图片描述
在文档中,有这几个配置比较重要

image-20210301150906117

这里的配置基本上就够了。

配置名字配置说明说明
path.dataelasticsearch的数据存储目录
path.logselasticsearch的日志存储目录这里的日志主要是dc.log
cluster.nameelasticsearch的集群的名字同一个集群内节点的集群名字必须相同
node.name本节点在elasticsearch内的名字同一个集群内,避免节点名字相同
network.hostelasticsearch节点的网络elasticsearch会将这个host进行bind
一般这里是0.0.0.0,表示任何网络都能访问本节点.
network还有4个特殊值可以配置:network特殊配置
discovery.zen.ping.unicast.hostselasticsearch发现节点的列表这里一般是主节点列表。
是一个数组,可以配置很多个。
如果不带有端口,则是默认的9300。如果主节点不是9300,那么可以带有端口。
可以配置域名。
discovery.zen.minimum_master_nodeselasticsearch中选举主节点时最少支持节点数量elasticsearch中主节点时选举产生的。
elasticsearch中通过node.master配置节点是否可以作为主节点参与选举。
elasticsearch中通过node.data配置节点是否可以存储数据。
为了防止脑裂,一方面避免master待选节点数量为偶数,另一边需要满足半数原则.(半数原则是支持的节点数量必须大于50%)

如果要配置一个单宿主机集群,其实只需要在宿主机中启动多个实例,只要这些实例的集群名字保持相同即可。

elasticsearch会自己发现本网段中其他的elasticsearch实例,然后会相互通信。只要是同集群的,就会自动加入。

对于最开始的docker-compose.yaml,现在还不能运行,因为使用的是外部的网络,还需要手动创建网络。

docker network remove efk;docker network create efk --subnet 172.254.0.0/16;

image-20210301155047564

接着使用docker-compose up -d启动即可。

image-20210301154906704

发现启动失败,使用docker-compose logs -f elasticsearch0查看日志

image-20210301155007183

发现是权限问题使用chmod -R 777 ~/efk/elasticsearch*给与权限。因为在docker-compose.yaml中配置是自动重启的,所以等等就会启动成功了。

image-20210301155230791

接着我们使用rest-api查看集群状态,发现还是不能访问。等下elasticsearch节点又会重启。

查看日志发现是内存的问题

image-20210301155735493

使用sysctl --write vm.max_map_count=262144;设置,然后等会即可。

查看日志,发现已经启动了

image-20210301155902633

访问elasticsearch0的9200

image-20210301155935348

查看集群信息

image-20210301162045531

1.2 elasticsearch 配置

1.2.1 基础信息配置

path.logs和path.data配置

配置名配置值
path.data字符串
path.logs字符串

cluster.name配置

配置名配置值
cluster.name字符串

node.name配置

配置名配置值
node.name字符串

network.host配置

配置名配置值
network.hostip地址
特殊值(一般用0.0.0.0即可)

1.2.2 高级配置–network

这章节在Modules下的network小节

network.host

network.host为0.0.0.0表示任意的网络

image-20210301173040730

network.host特殊值

特殊值说明
_[networkInterface]_指定网卡或网段
_local_本机回环地址,比如127.0.0.1
_site_内网地址,比如192.168.0.1
_global_公网地址,比如114.114.114.114

默认支持ipv4和ipv6,如果需要配置指定网段是指定协议,需要增加协议。比如_en0:ipv4_

ipv6地址需要用[]将地址包起来,然后后面接:9200端口。

discovery.zen.ping.unicast.hosts

主节点的host列表。当前节点会尝试加入主节点的host列表内的集群。

默认是本机。

配置多个用逗号分割。

http.port

elasticsearch的http对外端口。也是rest-api的端口。默认9200~9300.选择这个范围内第一个可用的端口。

可以配置为一个范围。

比如http://127.0.0.1:9200

transport.port

elasticsearch的通信端口。elasticsearch集群内部需要进行通信,这个端口就是elasticsearch自己通信的端口。默认是9300~9400.选择这个范围内第一个可用的端口。

可以配置为一个范围。

network.bind_host

将elasticsearch节点绑定到哪个网段。

主要用于节点发现。其他节点如果也在这个网段,这两个节点就会通信。如果属于一个集群,那么就会参与选举。

默认取network.host的配置值。

network.publish_host

当前节点对外发布信息时,发布的host。用于代表当前节点的访问地址。

默认取network.host

1.2.3 高级配置–discovery

discovery.zen.ping.unicast.hosts

指定主节点列表。当前节点会尝试加入这些主节点,如果这些主节点无法加入,且当前节点允许成为主节点,而且满足最小选择支持数,那么本节点就会成为主节点。

这里面配置的是可以参与选举的节点。

这个配置含义可以简单这样理解:当前节点在将自己本身作为主节点之前,先尝试找其他主节点。

默认本机回环地址。

discovery.zen.ping,unicast,resolve_timeout

尝试发现主节点的ping的超时时间。

默认5s。

在某些网络不好的情况下,可能5s不够。

discovery.zen.ping_timeout

节点发现主节点的ping超时时间。

默认3s.

换句话说,从节点加入主节点,会给主节点ping,主节点需要给从节点进行回复。这个timeout就是从节点的一次ping的等待时间。

从节点对主节点列表中的一个主节点会尝试ping三次。

discovery,zen,join_timeout

节点加入主节点的超时时间。

默认20倍的ping超时时间。

我们给从节点配置了一个主节点地址列表。但是我们无法保证主节点列表中第一个就是主节点(主节点需要选举)

所以,就需要从节点一个一个的去尝试询问。如果节点不回复,那么一定不是主节点(不考虑网络问题)。

如果节点有回复,那么还需要确认,询问的节点是否是主节点。节点可以参与选举,但是不一定选举成功。

discovery.zen.master_election.ignore_no_master_pings

true或者false。

在选举主节点期间,是否忽略从节点的ping。

默认是false。

也就是说,在选举主节点期间,从节点给可以参与选举的主节点候选发送ping,是可以收到回复的。

discovery.zen.minimum_master_nodes

成功当选最少同意数量。

为了防止脑裂,至少需要一半以上的节点同意,选举才成功。

1.2.4 高级配置–transport

elasticsearch节点之间需要进行通信,使用的就是transport模块。

transport.port

当前节点与其他节点通信的端口。

默认9300~9400之间第一个可用端口。

transport.publish_port

当前节点对外发布的通信端口。

默认取transport.port的值。

transport.bind_host

elasticsearch绑定网段。

默认取transport.host或者network.bind_host的值。

transport.publish_host

当前节点对外发布的地址。

默认取transport.host或者network.publish_host的值。

transport.host

当前节点与其他节点通信的地址。

默认取network.host的值。

transport.connect_timeout

节点之间通信连接的超时时间。

默认30s

transport.compress

节点之间通信的数据是否进行压缩。

默认不压缩。

压缩会将节点之间沟通变慢。

1.2.5 高级配置–http

和transport类似

http配置

SettingDescription
http.portA bind port range. Defaults to 9200-9300.
http.publish_portThe port that HTTP clients should use when communicating with this node. Useful when a cluster node is behind a proxy or firewall and the http.port is not directly addressable from the outside. Defaults to the actual port assigned via http.port.
http.bind_hostThe host address to bind the HTTP service to. Defaults to http.host (if set) or network.bind_host.
http.publish_hostThe host address to publish for HTTP clients to connect to. Defaults to http.host (if set) or network.publish_host.
http.hostUsed to set the http.bind_host and the http.publish_host Defaults to http.host or network.host.
http.max_content_lengthThe max content of an HTTP request. Defaults to 100mb. If set to greater than Integer.MAX_VALUE, it will be reset to 100mb.
http.max_initial_line_lengthThe max length of an HTTP URL. Defaults to 4kb
http.max_header_sizeThe max size of allowed headers. Defaults to 8kB
http.compressionSupport for compression when possible (with Accept-Encoding). Defaults to true.
http.compression_levelDefines the compression level to use for HTTP responses. Valid values are in the range of 1 (minimum compression) and 9 (maximum compression). Defaults to 3.
http.cors.enabledEnable or disable cross-origin resource sharing, i.e. whether a browser on another origin can execute requests against Elasticsearch. Set to true to enable Elasticsearch to process pre-flight CORS requests. Elasticsearch will respond to those requests with the Access-Control-Allow-Origin header if the Origin sent in the request is permitted by the http.cors.allow-origin list. Set to false (the default) to make Elasticsearch ignore the Origin request header, effectively disabling CORS requests because Elasticsearch will never respond with the Access-Control-Allow-Origin response header. Note that if the client does not send a pre-flight request with an Origin header or it does not check the response headers from the server to validate the Access-Control-Allow-Origin response header, then cross-origin security is compromised. If CORS is not enabled on Elasticsearch, the only way for the client to know is to send a pre-flight request and realize the required response headers are missing.
http.cors.allow-originWhich origins to allow. Defaults to no origins allowed. If you prepend and append a / to the value, this will be treated as a regular expression, allowing you to support HTTP and HTTPs. for example using /https?:\/\/localhost(:[0-9]+)?/ would return the request header appropriately in both cases. * is a valid value but is considered a security risk as your Elasticsearch instance is open to cross origin requests from anywhere.
http.cors.max-ageBrowsers send a “preflight” OPTIONS-request to determine CORS settings. max-age defines how long the result should be cached for. Defaults to 1728000 (20 days)
http.cors.allow-methodsWhich methods to allow. Defaults to OPTIONS, HEAD, GET, POST, PUT, DELETE.
http.cors.allow-headersWhich headers to allow. Defaults to X-Requested-With, Content-Type, Content-Length.
http.cors.allow-credentialsWhether the Access-Control-Allow-Credentials header should be returned. Note: This header is only returned, when the setting is set to true. Defaults to false
http.detailed_errors.enabledEnables or disables the output of detailed error messages and stack traces in response output. Note: When set to false and the error_trace request parameter is specified, an error will be returned; when error_trace is not specified, a simple message will be returned. Defaults to true
http.pipeliningEnable or disable HTTP pipelining, defaults to true.
http.pipelining.max_eventsThe maximum number of events to be queued up in memory before an HTTP connection is closed, defaults to 10000.
http.max_warning_header_countThe maximum number of warning headers in client HTTP responses, defaults to unbounded.
http.max_warning_header_sizeThe maximum total size of warning headers in client HTTP responses, defaults to unbounded.

1.3 elasticsearch节点分类

1.3.1 单节点–discovery.type

如果整个集群中只有一个节点,而且没有集群的需求的时候。可以使用单机版。

通过设置discovery.type=single-node

image-20210301190131769

1.3.2 主节点–node.master

一个节点可以参加选举,就需要配置node.master=true.这样这个节点就会参与选举。

节点默认是可以参与选举的。也就是说,任何节点都可以成为主节点。

1.3.3 数据节点–node.data

如果集群内节点特别多,数据交互非常频繁,而且交互都是通过主节点进行的。此时主节点既要回复从节点的信息,还需要数据的存储。

当主节点即管理数据,又管理节点时,主节点自己就很容易成为性能瓶颈。

所以,当数据交互非常平凡的时候,就可以将主节点和数据节点分离。

如果配置多个主节点,那么这些主节点即不存储数据,也不是主节点。这时候,这些主节点就组成了哨兵模式。当真正的主节点死掉后,待选主节点可以升级为主节点。而真正的主节点回复后,又会成为待选主节点。

因为主节点不存储任何数据,因此换了主节点并不会影响数据。

1.3.4 解析节点–node.ingest

elasticsearch是一个分词数据库,当我们将一个字符串交给elasticsearch后,elasticsearch需要进行分词操作。分词也是需要耗费计算资源的。

解析节点就是专门用于解析分词的。

某种意义上来说,即不存储数据,有不是主节点的节点,就是专门的解析节点。

1.3.5 连接节点–tribe

当我们有多个集群时,如果这些集群之间需要进行数据通信,那么就需要用到连接节点进行连接。

tribe:
    t1: 
        cluster.name:   cluster_one
    t2: 
        cluster.name:   cluster_two

通过配置多个集群进行连接。

连接节点将在7.x移除。

1.3.6 机器学习节点–node.ml

机器学习节点配置说明

在实际使用中,可以并不需要明确区分节点的类型。在数据量小的时候,主节点也可以是数据节点,从节点也可以参与选举,任何节点都可以参与解析。

并没有明确的定义。

1.4 多宿主机集群

我们首先创建.env文件。在docker-compose.yaml中可以使用.env中的环境变量。这些环境变量也可以设置到操作系统中。
确保.env文件和docker-compose.yaml在同目录下。

# 本机ip
THIS_IP=
# 本机elasticsearch通信端口
THIS_PORT=
# 本机elasticsearch外部访问端口
THIS_HTTP_PORT=
# 集群主节点的ip
MASTER_IP=
# 集群主节点的端口
MASTER_PORT=
# 本机节点的名字
NODE_NAME=
# 当前节点是否可以成为主节点
IS_MASTER=

对应的docker-compose.yaml文件:

version: "3.2"
services:
  elasticsearch:
    image: 10.0.250.108/library/elasticsearch:6.8.13
    restart: always
    container_name: elasticsearch
    hostname: elasticsearch
    environment:
      - TZ=Asia/Shanghai
      - "ES_JAVA_OPTS=-Xms1024m -Xmx1024m"
      - cluster.name=boss-elasticsearch
      - network.host=0.0.0.0
      - http.cors.enabled=true
      - http.cors.allow-origin='*'
      - node.data=true
      - discovery.zen.ping.unicast.hosts.resolve_timeout=1d
      - discovery.zen.ping.unicast.hosts=${MASTER_IP}:${MASTER_PORT}
      - discovery.zen.minimum_master_nodes=1
      - path.data=/usr/share/elasticsearch/data
      - path.logs=/usr/share/elasticsearch/logs
      - node.name=${NODE_NAME}
      - transport.publish_host=${THIS_IP}
      - transport.publish_port=${THIS_PORT}
      - node.master=${IS_MASTER}
    ports:
      - ${THIS_HTTP_PORT}:9200
      - ${THIS_PORT}:9300
    volumes:
      - /etc/localtime:/etc/localtime
      - ~/bosselastic/elasticsearch/data:/usr/share/elasticsearch/data
      - ~/bosselastic/elasticsearch/logs:/usr/share/elasticsearch/logs
      - ~/bosselastic/elasticsearch/plugins:/usr/share/elasticsearch/plugins
    networks:
      - outside
networks:
  outside:
    external:
      name: efk

这是主节点列表中只有一个节点的。

如果你想给主节点列表中设置多个地址,那么需要使用- discovery.zen.ping.unicast.hosts=${MASTER_IP}:${MASTER_PORT},${MASTER_IP1}:${MASTER_PORT1},....

在多个宿主机上启动之后,访问主节点集群信息

image-20210301192922113

1.5 宿主机启动的坑

如果你将elasticsearch的数据和目录挂载出来,那么启动会异常的。

因为在容器内,elasticsearch是以elasticsearch的用户进行运行的。对外部的目录没有权限。

所以第一次启动会失败,日志中是权限不足。我们需要使用chmod -R 777 xxx进行权限赋予。赋予权限后不需要重启,我们定义docker-compose的时候,就是自动重启的。

一会之后,查看日志还是权限不足,此时还需要使用chmod -R 777 xxxx进行权限赋予。

第一次权限不足是因为elasticsearch需要在指定目录下创建elasticsearch的目录。

第二次权限不足是因为elasticsearch在log目录下创建gc.log,但是elasticsearch又没有gc.log的读写权限。所以需要第二次赋权。第二次赋权实际上修改的是gc.log的权限。

2. elasticsearch-head

现在网络上关于elasticsearch的可视化管理系统特别多,安装起来也非常的简单。甚至你熟悉elasticsearch的api接口,你通过http就能管理集群。

为了容易查看和管理,我们安装elasticsearch-head软件。

也是采用docker-compose安装。

因此我们在docker-hub上找到这个镜像。

docker-hub搜索elasticsearch-head结果
image-20210302185457001

需要注意的是,这个镜像没有latest标签,这就意味着,我们必须制定标签下载。

我们使用其中的5这个标签即可

image-20210302185608022

我们将其作为docker-compose中的服务

version: "3.2"
services:
  searchhead:
    image: docker.elastic.co/mobz/elasticsearch-head:5
    restart: always
    container_name: searchhead
    hostname: searchhead
    environment:
      - TZ=Asia/Shanghai
    volumes:
      - /etc/localtime:/etc/localtime
    ports:
      - 9100:9100
    networks:
      - outside
networks:
  outside:
    external:
      name: efk

这个端口是怎么来的呢?

我们点击这个5,就能查看这个镜像的dockerfile了

image-20210302190127046

接着通过EXPOSE的关键词就能找到容器内的端口

image-20210302190211254

当我们启动之后,就可以通过9100访问了

image-20210302190635147

访问是这样的

image-20210302190702964

我们填入elasticsearch的地址和端口

image-20210302191101391

这个监控还可以管理节点。但是因为没有权限管理和角色管理,最好不要让外网可以访问监控。

3. kibana

同样的操作,在docker-hub中搜索kibana

image-20210302191301125

kibana的版本一定要和elasticsearch的版本保持一致

image-20210302191437024

如何使用kibana

image-20210302191518051

基于此,我们可以编写出kibana的docker-compose文件

version: "3.2"
services:
  kibana:
    image: /kibana:6.8.13
    restart: always
    container_name: kibana
    hostname: kibana
    environment:
      - TZ=Asia/Shanghai
      - elasticsearch.hosts=http://${MASTER_IP}:${MASTER_PORT}
      - elasticsearch.pingTimeout=300000
      - kibana.index=.kibana
      - logging.timezone=UTC+8
      - server.host=0.0.0.0
      - server.name=kibana
      - server.port=5601
      - i18n.locale=zh-CN
      - xpack.monitoring.kibana.collection.enabled=false
      - xpack.monitoring.ui.container.elasticsearch.enabled=true
    volumes:
      - /etc/localtime:/etc/localtime
    ports:
      - 5601:5601
    depends_on:
      - elasticsearch
    networks:
      - outside
networks:
  outside:
    external:
      name: efk

其中MASTER_IP是环境变量。

初次之外,还需要配置kibana

kibana也是elastic公司的开源产品,因此,类似与elasticsearch一样,在elatic官网中直接搜索kibana

就能找到kibana的文档

image-20210302192138391

我们找到running kibana on docker小节,就可以知道配置一个最简单的kibana需要有哪些配置了

image-20210302192223748

image-20210302192247402

kibana完整的配置说明

image-20210302195704953

kibana全部的配置都可以用环境变量传入。也可以用配置文件挂载。

启动后立刻访问会提示kibana还未准备完成

image-20210302202400211

启动成功后,kibana会将自己的数据交给elasticsearch保存。

kibana在elasticsearch中保存数据的数据库索引是我们指定的.kibana开头的

image-20210302202554538

此时没有任何数据。

4. fluentd

我们在docker-hub中搜索fluentd

image-20210303090133956

需要注意的是,这个镜像只是纯镜像,没有任何插件。

我们选择这个版本

image-20210303090431900

通过查看how to run images我们可以知道fluentd需要对外开放24224端口,并且对tcp和udp协议都开放。

image-20210303090630659

看到这里,我们已经能够成功的启动一个fluentd的镜像了,但是,还有一个问题需要解决?fluentd如何与elasticsearch集成?

默认镜像只包含fluentd的功能,没有elasticsearch的。

我们通过docker-hub的界面链接到fluentd的github地址

image-20210303091055008

在github的readme中的第三小节,我们可以找到fluentd的插件市场

image-20210303091143378

而且给出的例子就是fluentd安装elasticsearch插件

image-20210303091236906

我们在fluentd的插件市场中搜索elasticsearch就可以找到elasticsearch的插件了

image-20210303091431087

点击就进入elasticsearch插件的github中了,在readme中找到安装小节

image-20210303091828691

通过这里,我们拿到了插件名称和下载方式。

接下来就开始编写我们自己的dockerfile吧

FROM fluentd:v1.9-1
USER root
WORKDIR /home/fluent
RUN gem install fluent-plugin-elasticsearch
EXPOSE 24224

简单粗暴,使用最新的fluentd以及使用root用户,直接切换到fluent目录下,使用命令安装插件,并传递开放24224端口(其实不知道另一个端口是干啥的,所以就没有开放)。

需要注意的是,这样构建镜像,需要构建的宿主机能够访问外网。

在宿主机上使用docker build -f fluentd-elasticsearch --tag=fluentd-elasticsearch:latest .进行构建。(别忘记了.)

image-20210303092433534

查看镜像,会发现多了一个

image-20210303092513312

如果需要上传私服,需要使用docker login http://your-harbor.com登录docker私服,然后使用docker commit -m "message"提交修改

image-20210303092709829

最终使用docker push fluentd-elasticsearch推送即可

image-20210303092847235

到了这里就需要编写docker-compose文件了

version: "3"
services:
  fluentd:
    image: fluentd-elasticsearch
    restart: always
    container_name: fluentd
    hostname: fluentd
    command: "fluentd -c /fluentd/etc/fluent.conf"
    environment:
      - TZ=Asia/Shanghai
    volumes:
      - /etc/localtime:/etc/localtime
      - ~/bosselastic/fluentd/logs:/fluentd/log
      - ~/bosselastic/fluentd/fluent.conf:/fluentd/etc/fluent.conf:rw
    ports:
      - 24224:24224/udp
      - 24224:24224
    extra_hosts:
      - 'elasticsearch: ${MASTER_IP}'
    networks:
      - outside
networks:
  outside:
    external:
      name: efk

这个文件,你或许有两个疑问?

  1. command是如何得到的?

    fluentd的github的readme中有自定义配置小节

    image-20210303093658701

    而且,我们在文件挂载中,将配置文件挂载到了/fluentd/etc/目录下。

    其实,只要将配置文件挂载到/fluentd/etc/目录下,而且文件名字是fluent.conf是不需要-c参数的。

    因为在官方的镜像中,默认取的就是这个目录下的这个配置文件

    fluentd最新镜像的dockerfile文件

    image-20210303093925344

  2. 为什么需要extra_hosts?

    看到这里,就不得不提另一个问题,那就是在上面我们挂载的配置文件。

    # Receive events from 24224/tcp
    # This is used by log forwarding and the fluent-cat command
    <source>
      @type forward
      port 24224
      bind 0.0.0.0
    </source>
    <match *.*>
      @type copy
      <store>
        @id elasticsearch
        @type elasticsearch
        @log_level debug
        host elasticsearch
        port 9200
        request_timeout 30s
        slow_flush_log_threshold 30s
        logstash_format true
        logstash_prefix fluentd
        logstash_dateformat %Y%m%d
        include_tag_key true
        tag_key @log_name
      </store>
    </match>
    

    配置文件长这样。里面需要配置elasticsearch的host。

    这个host你可以直接写死,但是这里我使用的是主机名,然后将真实地址通过hosts指定。

    这样做的好处是可以统一配置。

  3. 配置文件?

    fluentd的github的第二小节

    image-20210303101808433

    告诉了我们fluentd的配置文件的文档位置

    我们主要看的是input和output小节。

    image-20210303102001026

    image-20210303102041829

OK,目前为止,docker-composefluentd.conf都有了,可以启动了。

但是启动之后是没有数据的。

5. 微服务集成fluentd

微服务集成fluentd需要引入fluent-logger的依赖以及fluency-core和fluency-fluentd。

如果使用logback配置日志,还需要引入logback的依赖

	implementation 'org.fluentd:fluent-logger:0.3.4'
	implementation 'com.sndyuk:logback-more-appenders:1.8.3'
	implementation 'org.komamitsu:fluency-core:2.4.0'
	implementation 'org.komamitsu:fluency-fluentd:2.4.0'

比如一个web的全部依赖可以是这样的

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-web'
	implementation 'org.fluentd:fluent-logger:0.3.4'
	implementation 'com.sndyuk:logback-more-appenders:1.8.3'
	implementation 'org.komamitsu:fluency-core:2.4.0'
	implementation 'org.komamitsu:fluency-fluentd:2.4.0'
	compileOnly 'org.projectlombok:lombok'
	annotationProcessor 'org.projectlombok:lombok'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

启动之后微服务会尝试连接fluentd服务。

微服务还需要配置logback.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="30 seconds">
    <springProperty scope="context" name="appName" source="spring.application.name" defaultValue="localhost"/>
    <property name="suffix" value="dev"/>
<!--    环境变量-->
<!--    fluentd的地址-->
<!--    <property name="LOG_FLUENTD_IP" value="10.0.250.106"/>-->
<!--    fluentd的端口-->
<!--    <property name="LOG_FLUENTD_PORT" value="24224"/>-->
    <property name="logName" value="${appName}-${suffix}"/>
    <!-- 日志级别 -->
    <property name="logLevel" value="INFO"></property>
    <!-- 日志地址 -->
    <property name="logPath" value="logs/${appName}"></property>
    <!-- 最大保存时间 -->
    <property name="maxHistory" value="7"/>

    <!-- 控制台打印日志的相关配置 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <!-- 日志格式 -->
        <encoder>
            <pattern>
                <![CDATA[%d{HH:mm:ss.SSS} [%thread][TraceInfo:%X{traceId}:%X{spanId}] %-5level %logger{36} - %msg%n]]>
            </pattern>
        </encoder>
    </appender>

    <!-- 文件保存日志的相关配置,同步 -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 保存日志文件的路径 -->
        <file>${logPath}/${logName}.log</file>
        <!-- 日志格式 -->
        <encoder>
            <pattern>
                <![CDATA[%d{yyyy-MM-dd HH:mm:ss.SSS}%X{ip}[%thread][TraceInfo:%X{traceId}:%X{spanId}]  %-5level %logger{35} -%msg%n]]>
            </pattern>
        </encoder>
        <!-- 循环政策:基于时间创建日志文件 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日志文件名格式 -->
            <fileNamePattern>${logPath}/${logName}-%d{yyyy-MM-dd}.log</fileNamePattern>
            <!-- 最大保存时间-->
            <maxHistory>${maxHistory}</maxHistory>
        </rollingPolicy>
    </appender>

    <appender name="FLUENT_SYNC" class="ch.qos.logback.more.appenders.FluencyLogbackAppender">
        <!--fluentd中的tag-->
        <tag>boss.${logName:-UNKOWN}</tag>
        <remoteHost>${LOG_FLUENTD_IP:-10.0.250.106}</remoteHost>
        <port>${LOG_FLUENTD_PORT:-24224}</port>
        <fileBackupDir>/tmp</fileBackupDir>
        <bufferChunkInitialSize>2097152</bufferChunkInitialSize>
        <bufferChunkRetentionSize>16777216</bufferChunkRetentionSize>
        <maxBufferSize>268435456</maxBufferSize>
        <waitUntilBufferFlushed>30</waitUntilBufferFlushed>
        <waitUntilFlusherTerminated>40</waitUntilFlusherTerminated>
        <senderMaxRetryCount>12</senderMaxRetryCount>
        <useEventTime>true</useEventTime>
        <additionalField>
            <key>@log_name</key>
            <value>${logName:-UNKOWN}</value>
        </additionalField>
        <additionalField>
            <key>pod_name</key>
            <value>${POD_NAME:-UNKOWN}</value>
        </additionalField>
        <additionalField>
            <key>host_name</key>
            <value>${hostname:-UNKOWN}</value>
        </additionalField>
    </appender>

    <!--哪些包的日志需要处理-->
    <logger name="com.study" level="INFO" additivity="false">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="FILE"/>
        <appender-ref ref="FLUENT_SYNC"/>
    </logger>

    <root level="${logLevel}">
        <!-- appender referenced after it is defined -->
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="FILE"/>
        <appender-ref ref="FLUENT_SYNC"/>
    </root>
</configuration>

logback中配置的tag需要与fluentd.conf中的match进行匹配。

举个例子:

在logback中配置的tag是study.test,在fluentd.conf中match是study.*。因为在fluentd.conf中match是输出,只有匹配才会到对应的输出。

image-20210303111103290

这里需要注意。

我们启动微服务后,微服务通过logback进行日志处理,在logback中指定fluentd的服务端的地址和端口。接着fluentd的包会将日志上传给fluentd服务端。

fluentd服务端接受到日志后,进行格式化等处理,然后通过配置文件,匹配到elasticsearch的存储,接着fluentd通过elasticsearch的9200将数据存储到elasticsearch中。(没有指定elasticsearch的数据库索引,会以fluentd-日期创建,每天一个索引)

elasticsearch中存储了数据之后,kibana就能通过9200端口查询数据,并在界面中展示。

elasticsearch中存储了fluentd的数据后

image-20210303111611834

最后就能在kibana中查看日志了

image-20210303111823935

第一次进入kibana还不能直接查看日志,需要在Management中创建fluentd的索引模式。

image-20210303112056856

创建索引模式成功后,就可以在Discover中看到统计图了

image-20210303112207421

想看到统计图,需要在创建索引模式的第二步中选中时间属性,否则不会出现统计图

image-20210303112304555

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值