Docker方式搭建ELK集群

此篇文章记录一下搭建过程和一些思考总结

目录

    • What is ELK ?
    • Why use ELK ?
    • How build ELK with docker?
      • 1. 部署 Elasticsearch 集群
        • 1.1 创建文件夹和配置文件
        • 1.2 检查系统相关参数
        • 1.3 创建容器
      • 2. 部署 Kibana
        • 2.1 创建文件夹和配置文件
        • 2.2 创建容器
        • 2.3 nginx 代理访问
      • 3. 部署 Logstash
        • 3.1 创建文件夹和配置文件
        • 3.2 创建容器
      • 4. SpringBoot 集成 Logstash
      • 5. 访问 kibana
      • 6. 定期清除过期日志索引
    • 结束语

What is ELK ?

官方网站 https://www.elastic.co/cn/what-is/elk-stack

“ELK”是三个开源项目的首字母缩写,这三个项目分别是:Elasticsearch、Logstash 和 Kibana。

Elasticsearch 是一个搜索和分析引擎。

Logstash 多源采集数据,转换数据,然后将数据发送到诸如 Elasticsearch 等“存储库”中。

Kibana 则可以让用户在 Elasticsearch 中使用图形和图表对数据进行可视化。

Elastic Stack 是 ELK Stack 的更新换代产品

Why use ELK ?

微服务场景下,少则3~4个微服务,多则10几20个微服务,而且还有负载均衡等,
开发人员查看定位问题看日志,如果不能提供一个可视化的日志查看平台,将十分痛苦!

目前市面上收集日志的产品不止 ELK,本人比对了几款产品,考虑到 Elasticsearch 除了日志还有很多全文检索的业务场景,因此就选择了 ELK了。

而且 Logstash 可以用的地方不止是logback ,他可以收集mysql redis等数据,进行传输也可以!

How build ELK with docker?

全网一百度,成千上万篇 博客都有记载如何用 docker快速搭建一个 ELK 集群,这里的集群基本上是指Elasticsearch 集群。

想快?但现实是大多数人第一次搭建过程都多少遇到阻碍,这些一切缘由都是没有仔细查看官方文档!

1. 部署 Elasticsearch 集群

安装物理环境如下:

主机:3台 ECS

es 节点名称 内网 ip 地址
es01 10.133.190.6
es02 10.133.190.7
es03 10.133.190.8

网络:局域网部署, 三台 ECS 直接可以互相访问,无防火墙限制

版本:ELK 三个软件版本都是 7.11.2,操作系统版本 CentOS Linux release 7.6.1810

1.1 创建文件夹和配置文件

10.133.190.6 上创建目录 /apps/es01/config /apps/es01/data
10.133.190.7 上创建目录 /apps/es02/config /apps/es02/data
10.133.190.8 上创建目录 /apps/es03/config /apps/es03/data

10.133.190.6 上创建文件 /apps/es01/config/elasticsearch.yml 内容如下:


cluster.name: es-docker-cluster
node.name: es01
network.host: 10.133.190.6
http.port: 9201
transport.tcp.port: 9301
http.cors.enabled: true
http.cors.allow-origin: "*"
node.master: true
node.data: true
discovery.seed_hosts: ["10.133.190.7:9301","10.133.190.8:9301"]
cluster.initial_master_nodes: ["es01","es02","es03"]

10.133.190.7 上创建文件 /apps/es01/config/elasticsearch.yml 内容如下:


cluster.name: es-docker-cluster
node.name: es02
network.host: 10.133.190.7
http.port: 9201
transport.tcp.port: 9301
http.cors.enabled: true
http.cors.allow-origin: "*"
node.master: true
node.data: true
discovery.seed_hosts: ["10.133.190.6:9301","10.133.190.8:9301"]
cluster.initial_master_nodes: ["es01","es02","es03"]

10.133.190.8 上创建文件 /apps/es01/config/elasticsearch.yml 内容如下:


cluster.name: es-docker-cluster
node.name: es03
network.host: 10.133.190.8
http.port: 9201
transport.tcp.port: 9301
http.cors.enabled: true
http.cors.allow-origin: "*"
node.master: true
node.data: true
discovery.seed_hosts: ["10.133.190.6:9301","10.133.190.7:9301"]
cluster.initial_master_nodes: ["es01","es02","es03"]

请确保 /apps/es01/data /apps/es02/data /apps/es03/data 目录有写的权限!
可以先直接 chmod -R 777 /apps/es02/ 授权

上面yml文件中的每一个属性含义如下:

配置项 说明
cluster.name 配置的集群名称,默认是elasticsearch A node can only join a cluster when it shares its cluster.name
node.name 集群中这台es节点的名称
network.host 用来同时设置 network.bind_host和 network.publish_host 两个参数 There are many network settings but usually all you need to configure is network.host
http.port restful http 访问端口
transport.tcp.port tcp 访问端口
http.cors.enabled 是否支持跨域
http.cors.allow-origin 支持跨域访问的方式
node.master 指定该节点是否有资格被选举成为node 默认为true
node.data 指定该节点是否存储索引数据 默认为true
discovery.seed_hosts 要与哪些可访问的节点组成集群, 原来老的配置名称为 discovery.zen.ping.unicast.hosts 已经过时了
cluster.initial_master_nodes 集群初始化启动时,指明哪些节点 (可以是节点ip或节点名称) 可以参与主节点选举,首次成功形成群集后,从每个节点的配置中删除 cluster.initial_master_nodes 设置。重新启动群集或向现有群集添加新节点时,请勿使用此设置。 原来老的配置名称为 discovery.zen.minimum_master_nodes 已经过时了
cluster.publish.timeout 等待其他节点加入集群竞选master节点的最大时长,默认30s

关于initial_master_nodes 和 seed_hosts 等其他集群参数可查看这里

1.2 检查系统相关参数

这一步很多人忽略了,导致后面启动docker容器的时候报各种类型出错!
点击 Bootstrap Checkses 查看明细
Docker方式搭建ELK集群_第1张图片
尤其注意 max_map_count 参数检查, 启动时候会报 “ max virtual memory areas vm.max_map_count [65530] is too low , you must configure vm.max_map_count via sysctl to be at least 262144 ”这样的提示,
然后修改Linux 内核参数文件 /etc/sysctl.conf 里面增加一行 vm.max_map_count=262144
然后 sysctl -p 生效。

vim  /etc/sysctl.conf

Docker方式搭建ELK集群_第2张图片

 sysctl -p

上面 必须注意: 如果要生效 /etc/sysctl.conf 请务必确保 net.ipv4.ip_forward=1 ,默认他是0,如果是0
则ip4转发功能将限制, 很可能本机上 docker版本的nginx 全部抛出502错误 ,启动docker端口映射则会抛出“ IPv4 forwarding is disabled. Networking will not work” 错误!

1.3 创建容器

10.133.190.6 上运行


docker run --restart=always  --network=host
-d -p 9201:9200 -p 9301:9300 \
-e ES_JAVA_OPTS="-Xms1024m -Xmx1024m" \
-e "discovery.type=zen" \
-v /apps/es01/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /apps/es01/data:/usr/share/elasticsearch/data \
--name es01 elasticsearch:7.11.2

10.133.190.7 上运行


docker run --restart=always    --network=host
-d -p 9201:9200 -p 9301:9300 \
-e ES_JAVA_OPTS="-Xms1024m -Xmx1024m" \
-e "discovery.type=zen" \
-v /apps/es02/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /apps/es02/data:/usr/share/elasticsearch/data \
--name es02 elasticsearch:7.11.2

10.133.190.8 上运行


docker run --restart=always   --network=host
-d -p 9201:9200 -p 9301:9300 \
-e ES_JAVA_OPTS="-Xms1024m -Xmx1024m" \
-e "discovery.type=zen" \
-v /apps/es03/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-v /apps/es03/data:/usr/share/elasticsearch/data \
--name es03 elasticsearch:7.11.2

这里说一下 我这边的 elasticsearch是经过加工的 镜像,我将 分词ik工具集成进去了,重新提交了一个新镜像, 之前是单节点启动的,希望你还记得单节点es docker命令:
ES 单节点安装:

docker run -p 9200:9200 -p 9300:9300 -d --name=es  \
-e "ES_JAVA_OPTS=-Xms512m -Xmx512m"  \ 
-e "discovery.type=single-node"  \
-v /apps/es/data:/usr/share/elasticsearch/data elasticsearch:7.11.2

这有什么问题? 新的镜像中包括了 -e “discovery.type=single-node” ,这样启动会报错!
通过查看 es 源码,发现 discovery.type 一共两种模式 zen 和 single-node, 集群模式需要为zen,因此: 我们启动集群方式增加了 -e “discovery.type=zen” \

任意一个es节点上运行查看集群情况: curl 10.133.190.6:9201/_cat/nodes
Docker方式搭建ELK集群_第3张图片
可以看见一共三个节点,master节点目前是 10.133.190.7 es02 这个节点。

2. 部署 Kibana

这里就没有集群,kibana 只作为一个可视化的访问平台,目前随便选择一台主机部署一下即可。

2.1 创建文件夹和配置文件

10.133.190.8 上创建目录 /apps/kibana/config/kibana.yml 文件
内容如下:

server.name: kibana
server.basePath: "/kibana"
server.rewriteBasePath: true
server.host: "10.133.190.8"
elasticsearch.hosts: ["http://10.133.190.6:9201","http://10.133.190.7:9201","http://10.133.190.8:9201"]
monitoring.ui.container.elasticsearch.enabled: true
i18n.locale: "zh-CN"

说明一下 上面的 server.rewriteBasePathserver.basePath ,目的是为了要nginx代理访问kibana,因此kibana最好有一个前缀,8.x中 server.rewriteBasePath默认为true,7.x如果不配做,则server.basePath不生效。
i18n.locale 是让kibana 中文界面,但个人觉得还是最好不要中文界面。

2.2 创建容器


docker run -d -p 5601:5601 --name kibana --network=host \
-v  /apps/kibana/config/kibana.yml:/usr/share/kibana/config/kibana.yml \
 kibana:7.11.2 

2.3 nginx 代理访问

nginx 增加配置如下:

location /kibana
  {
    proxy_redirect off;
    proxy_set_header Host $host:$server_port; 
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://10.133.190.8:9201/kibana;
  }

3. 部署 Logstash

在任意一台主机上部署 Logstash程序

3.1 创建文件夹和配置文件

创建 /apps/elk/logstash/config 目录, 下面创建两个文件 logstash.yml logstash.conf

编辑 logstash.yml 配置文件
logstash.yml配置文件放在宿主机 /apps/elk/logstash 目录下,内容如下:

path.config: /usr/share/logstash/config/*.conf
path.logs: /var/log/logstash

编辑 logstash.conf文件
logstash.conf文件放在宿主机 /apps/elk/logstash/config 目录下,内容如下:

input {
    tcp {
	    mode => "server"
        port => 5055
        codec => "json_lines"
    }
}

output {
  elasticsearch { 
		hosts => ["http://10.133.190.6:9201","http://10.133.190.7:9201","http://10.133.190.8:9201"]
		index => "spboot-%{+YYYY.MM.dd}"		
  }
}

3.2 创建容器


docker run -d --restart=always --network=host \
 --log-driver json-file \
 --log-opt max-size=100m \
 --log-opt max-file=4 \
 -p 5055:5055 --name logsh \
 -v /apps/elk/logstash/logstash.yml:/usr/share/logstash/config/logstash.yml \
 -v /apps/elk/logstash/:/usr/share/logstash/config/ logstash:7.11.2

4. SpringBoot 集成 Logstash

pom.xml 引入包:



    <dependency>
        <groupId>net.logstash.logbackgroupId>
        <artifactId>logstash-logback-encoderartifactId>
        <version>6.6version>
    dependency>

logback-spring.xml 配置中增加:

....其他信息

    <appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
        <destination>10.133.190.8:5055destination>
        
        <encoder class="net.logstash.logback.encoder.LogstashEncoder">
            <customFields>{"appname":"${LOG_FILE_NAME}", "hostname": "${HOSTNAME}"}customFields>
        encoder>
        <keepAliveDuration>5 minuteskeepAliveDuration>
    appender>

....其他信息

    <springProfile name="prod,test">
        
        <logger name="org.springframework" level="WARN"/>
        <logger name="com.middol" level="DEBUG"/>
        <root level="${LOG_LEVEL}">
            <appender-ref ref="ASYNC_FILE"/>
            <appender-ref ref="STDOUT"/>
            <appender-ref ref="LOGSTASH"/>
        root>
    springProfile>
    

destination 中 是logstash 所部署的主机ip地址, 5055 是 logstash input 中配置的端口。

5. 访问 kibana

访问 http://xxxxx/app/management/kibana/indexPatterns/create 创建logback的索引模式,
为什么要创建索引模式? kibana 希望你创建一个可以集中查询的检索方式, logback 我们设置的是一天一个索引,但是我们可能要查询近7天的日志数据。你总不至于一个索引一个索引的查询吧?

logstash中我们配置的索引名称 格式是 “spboot-%{+YYYY.MM.dd}”
Define an index pattern 这一栏我们直接写成 spboot* 即可。

Docker方式搭建ELK集群_第4张图片

下一步 选择 一个Select a primary time field,一般默认都选择 @timestamp
Docker方式搭建ELK集群_第5张图片

接下来 可以查看索引具体内容了, 回到home 选择 Discover 然后选择你的索引模式 spboot* 即可查看

Docker方式搭建ELK集群_第6张图片
sdfsd

6. 定期清除过期日志索引

这个网上一搜一大把。

ElasticSearch定期删除过期数据,随便创建一个可执行的sh文件,例如: /apps/delEsLog.sh

如果在windows上编写的sh脚本传递到linux上执行 ,记得 使用 VI 命令修改一下格式:

vi  /apps/delEsLog.sh 
:set ff=unix
chmod -x delEsLog.sh 
#!/bin/bash
#保留近 N 天的日志数据
KEEP_DAYS=7 
# 删除前 N的所有天到 前N+10天==>每天执行
function get_todelete_days()
{
    # declare -A DAY_ARR
    # DAY_ARR=""
    for i in $(seq 1 10);
    do
        THIS_DAY=$(date -d "$(($KEEP_DAYS+$i)) day ago" +%Y.%m.%d)
 
        DAY_ARR=( "${DAY_ARR[@]}" $THIS_DAY)
    done
    echo ${DAY_ARR[*]} 
}
# 返回数组的写法
TO_DELETE_DAYS=(`get_todelete_days`)
for day in "${TO_DELETE_DAYS[@]}"
do
    echo "$day will be delete"  
    curl -XDELETE 'http://10.133.190.7:9201/spboot-'${day}
done

输入:crontab -e
输入内容:

30 23 * * 7   /apps/delEsLog.sh 

然后按Esc输入 :wq 即可

每周日晚上23:30执行一次。
定时任务执行log文件地址:/var/spool/mail/root 可查看执行错误信息。

结束语

over !

抽空多看看 es官方文档,多思考,很难有直接给你用的东西,只能自己琢磨思考。

你可能感兴趣的:(运维,elasticsearch,es,elk,集群,docker)