docker-compose部署elk并设置账户密码系列

最近因为在搭建微服务环境所以要用到elk首先介绍一下什么是elk,以及负责的功能模块(部署的过程比较坎坷我尽量把遇到的坑,以及如何排查问题的方式顺便介绍一下)

ELK是Elasticsearch、Logstash、Kibana三大开源框架首字母大写简称(但是后期出现的filebeat(beats中的一种)可以用来替代logstash的数据收集功能,比较轻量级)。市面上也被成为Elastic Stack。

  • Filebeat是用于转发和集中日志数据的轻量级传送工具。Filebeat监视您指定的日志文件或位置,收集日志事件,并将它们转发到Elasticsearch或 Logstash进行索引。Filebeat的工作方式如下:启动Filebeat时,它将启动一个或多个输入,这些输入将在为日志数据指定的位置中查找。对于Filebeat所找到的每个日志,Filebeat都会启动收集器。每个收集器都读取单个日志以获取新内容,并将新日志数据发送到libbeat,libbeat将聚集事件,并将聚集的数据发送到为Filebeat配置的输出。
  • Logstash是免费且开放的服务器端数据处理管道,能够从多个来源采集数据,转换数据,然后将数据发送到您最喜欢的“存储库”中。Logstash能够动态地采集、转换和传输数据,不受格式或复杂度的影响。利用Grok从非结构化数据中派生出结构,从IP地址解码出地理坐标,匿名化或排除敏感字段,并简化整体处理过程。
  • Elasticsearch是Elastic Stack核心的分布式搜索和分析引擎,是一个基于Lucene、分布式、通过Restful方式进行交互的近实时搜索平台框架。Elasticsearch为所有类型的数据提供近乎实时的搜索和分析。无论您是结构化文本还是非结构化文本,数字数据或地理空间数据,Elasticsearch都能以支持快速搜索的方式有效地对其进行存储和索引。
  • Kibana是一个针对Elasticsearch的开源分析及可视化平台,用来搜索、查看交互存储在Elasticsearch索引中的数据。使用Kibana,可以通过各种图表进行高级数据分析及展示。并且可以为 Logstash 和 ElasticSearch 提供的日志分析友好的 Web 界面,可以汇总、分析和搜索重要数据日志。还可以让海量数据更容易理解。它操作简单,基于浏览器的用户界面可以快速创建仪表板(dashboard)实时显示Elasticsearch查询动态

接下来看一下架构图,看明白之后更容易理解部署的过程,以及以后可以朝那些方向去做扩展

从架构图上看:

1.kibana是个客户端工具主要跟es进行交互

2.es可以做集群扩展(为了您的es安全,请避免es裸奔——账户密码设置)

3.logsstash主要是用来做日志采集(目前主流的两种方式 1.走通讯协议 2.走消息队列)

4.Filebeat用来监视指定的日志文件或位置,收集日志事件

搭建背景:这里部署采用的es单机没做集群,日志使用的是kafka进行日志收集

接下来先开始部署kafka.yml 

version: '2'
services:
   zookeeper:
     image: wurstmeister/zookeeper
     container_name: intelligentremotepatrol_zookeeper
     restart: always
     ports:
       - "2181:2181"

   # 消息组件
   kafka:
     image: wurstmeister/kafka
     container_name: kafka
     restart: always
     ports:
       - "9092:9092"
     environment:
       KAFKA_ADVERTISED_HOST_NAME: xxx.xx.xx.184
       KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
       KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://xxx.xx.xx.x:9092
       KAFKA_CREATE_TOPICS: "deepstream:1:1"
     volumes:
       - /var/run/docker.sock:/var/run/docker.sock
       - ./data/kafka:/kafka
     # depends_on:
     #   - zookeeper

   # Kafka Web UI
   # 基于Java开发,内存占用太大,非必要请勿使用
   kafdrop:
     image: obsidiandynamics/kafdrop
     container_name: intelligentremotepatrol_kafdrop
     restart: always
     mem_limit: 400m
     ports:
       - "9080:9000"
     environment:
       KAFKA_BROKERCONNECT: kafka:9092
       JVM_OPTS: "-Xms32M -Xmx64M"
       SERVER_SERVLET_CONTEXTPATH: "/"
     depends_on:
       - kafka

然后执行:docker-compose -f kafka.yml up -d 把容器拉起来,访问ip:9080查看kafka是否正常

然后开始部署elk服务,我的文件夹结构是这样的,可以按自己的方式来(这里的方式决定了一会yml文件的挂载路径) 在这些文件的最外面还有一个Elk文件夹

---es

                config

                             elasticsearch.yml

cluster.name: "es"
network.host: 0.0.0.0
http.port: 9200
# 开启es跨域
http.cors.enabled: true
http.cors.allow-origin: "*"
http.cors.allow-headers: Authorization,Content-Type
# 开启安全控制
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true

 

--filebeat

      filebeat.yml

filebeat.config:
  modules:
    path: ${path.config}/modules.d/*.yml
    reload.enabled: false

processors:
  - add_cloud_metadata: ~
  - add_docker_metadata: ~

filebeat.inputs:
- type: log
  paths:
    - /usr/share/filebeat/logs/*.log
  multiline.pattern: '^[0-9]{4}-[0-9]{2}-[0-9]{2}'
  multiline.negate: true
  multiline.match: after
  multiline.timeout: 10s
  
output.logstash:
  hosts: ["logstash:5044"]

 

--kibana

 

      kibana.yml

server.name: kibana
server.host: "0.0.0.0"
elasticsearch.hosts: [ "http://elasticsearch:9200" ] # 修改为自己的ip 
xpack.monitoring.ui.container.elasticsearch.enabled: true
elasticsearch.username: "elastic"  # es账号
elasticsearch.password: "hzs888"   # es密码
i18n.locale: zh-CN # 中文

 

--logstash

      conf

                             logstash

                                           logstash.yml

            logstash-simple.conf

 这个是yml

http.host: "0.0.0.0"
xpack.monitoring.elasticsearch.hosts: [ "http://elasticsearch:9200" ]
xpack.monitoring.enabled: true
path.config: /usr/share/logstash/config/*.conf
path.logs: /usr/share/logstash/logs

这个是conf

input {
  kafka {
    id => "kafkaLogs"
    group_id => "Logs"
    bootstrap_servers => "xxx.xx.xx.xxx:9092"
    topics => ["logs"]
    auto_offset_reset => "latest"
  }
}
filter {

    date {
       match => ["timestamp","yyyy-MM-dd'T'HH:mm:ss,sss"]
       remove_field => "timestamp"
       target => "@timestamp"
    }

}
output {
  elasticsearch {
    hosts => ["elasticsearch:9200"]
    #index => "%{[@metadata][beat]}-%{[@metadata][version]}-%{+YYYY.MM.dd}"
    #user => "elastic"
    #password => "changeme"
  }
}

 

这个 filter 也可做更多扩展,这里先不一一介绍,感兴趣可以自己进行扩展 

下面是正式部署

version: '3'

# 网桥es -> 方便相互通讯
networks:
  es:

services:
  elasticsearch:
    image: elastic/elasticsearch:7.17.2
    container_name: elasticsearch
    environment:
      - discovery.type=single-node
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
      - TZ=Asia/Shanghai
      - LANG= en_US.UTF-8
      - ELASTIC_PASSWORD= "hzs888" # elastic账号密码 这个地方设置完后,在容器启动后发现密码失败根本登录不进去的情况要进入到容器内部设置,一会细说
    volumes:
      - ./es/data/esdata:/usr/share/elasticsearch/data
      - ./es/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
    hostname: elasticsearch
    restart: always
    ports:
      - 9200:9200
      - 9300:9300
    networks:
      - es


  kibana:
    image: elastic/kibana:7.17.2
    container_name: kibana
    volumes:
      - ./kibana/kibana.yml:/usr/share/kibana/config/kibana.yml
    hostname: kibana
    depends_on:
      - elasticsearch
    links: # 这里用了links 所以 kibana.yml 配置es的时候就不用指定ip
      - elasticsearch
    restart: always
    ports:
      - "5601:5601"
    networks:
      - es

  logstash:
    image: elastic/logstash:7.17.2
    container_name: logstash
    hostname: logstash
    restart: always
    environment:
      - TZ=Asia/Shanghai
    volumes:
      - ./logstash/conf/logstash:/usr/share/logstash/config
      - ./logstash/log:/usr/share/logstash/logs
    depends_on:
      - elasticsearch
    ports:
      - 9600:9600
      - 5044:5044


  filebeat:
    image: elastic/filebeat:7.17.2
    hostname: filebeat
    restart: always
    depends_on:
      - logstash
    user: root
    volumes:
      - ./filebeat/data/filebeat:/usr/share/filebeat/data
      - ./filebeat/filebeat.yml:/usr/share/filebeat/filebeat.yml
      - ./filebeat/log:/usr/share/filebeat/logs
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - TZ=Asia/Shanghai
    command: ["--strict.perms=false"]
这个es可以做多个集群方式有兴趣可以自己扩展,我这里资源有限就不做演示了

这里弄完后有很重要的两步操作避免在容器挂在yml文件时无权限

 

 

1.文件所属必须为root

2.文件必须要有777权限

chown -R root ElK/

chmod 777 -R ElK/

执行docker-compose -f elk.yml up -d 挂载完毕后如下

 

 然后访问 ip:9200

 

登录成功后显示

这时输入账户密码 elastic hzs888  如果现在发现输入正确配置的账户密码无效后进行如下操作(登录进去就跳过)

执行如下命令进入容器

docker exec -it 容器id /bin/bash
bin/elasticsearch-setup-passwords interactive

然后依次输入密码(需要输入很多很多次,别挣扎了,输入吧!)

 

 再回过头来进行登录Ip:9200 和 ip:5601(友情提示要是网页无法访问,检查云服务器端口是否开放,不像我sb找了半天问题)

登录成功后如果kibana无法访问,试着重启下容器

如果遇到(Kibana server is not ready yet)查看容器的日志看是哪儿的问题,多半是因为无法读取到es导致的

kibana这个页面就正常了

目前部署完后,各访问正常,但是还没进行kafka消息写入,后面测试完后,再做补充有问题再做调整

本文参考连接 都是东拼西凑一点都因为场景问题参考的都不全

 https://blog.csdn.net/qq_36778532/article/details/114121085

https://www.cnblogs.com/csts/p/14674141.html

https://juejin.cn/post/6992757838758182919

https://www.cnblogs.com/leozhanggg/p/12390850.html

https://blog.51cto.com/riverxyz/3154605

https://www.cnblogs.com/kebibuluan/p/13900497.html

继续填坑

上面的方式部署完之后,相信确实能看到界面,但是是不是发现和自己想象中的效果不一样,而且也没有发现有数据源头供创建索引进行筛选 ok

以上用docker-compose的方式确实方便把所有的配置写到一起,但是,如果某个配置yml文件改动了,所有的数服务都得重新弄,而且很不利于排查问题

而且我在目前已经把最新的数据写入到了kafka但是在界面上却没发现数据内容 于是我又将什么的整个文件服务拆成了一个个服务进行验证

首先从终端开始,上面的docker-compose中一共是4个服务 

说一下我的逻辑(我这边要实现的是通过kafka来进行日志消息的收集,然后通过es 在kibana进行展示)

es属于基础的查询服务 可以先搭建 然后设置密码

其次是kibana 他需要依赖es进行数据展示和搜索

再其次是logstash 他在配置文件中提供input和output也就是数据的入口和出口 那这里的数据入口肯定是kafka出口那便是es了

再说说 filebeat 他可以自定义收集日志的来源,输出到es中 并且还支持配置过滤等功能,虽然在上面的部署中用了他但是在时间我项目中可能没太大必要,我是以kafka进行日志的唯一入口 这个服务这里就先放放,下次有这个需求了再看

好开始部署 方式很简单,把上面的elk.yml中的服务拆开

es.yml

version: '3'

# 网桥es -> 方便相互通讯
networks:
  es:

services:
  elasticsearch:
    image: elastic/elasticsearch:7.17.2
    container_name: elasticsearch
    environment:
      - discovery.type=single-node
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
      - TZ=Asia/Shanghai
      - LANG= en_US.UTF-8
      - ELASTIC_PASSWORD= "hzs888" # elastic账号密码
    volumes:
      - ./es/data/esdata:/usr/share/elasticsearch/data
      - ./es/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
    hostname: elasticsearch
    restart: always
    ports:
      - 9200:9200
      - 9300:9300
    networks:
      - es

然后看volumes: 下的挂载目录(es/config/elasticsearch.yml) 按照目录创建一个yml文件 内容为如下:

cluster.name: "es"
network.host: 0.0.0.0
http.port: 9200
# 开启es跨域
http.cors.enabled: true
http.cors.allow-origin: "*"
http.cors.allow-headers: Authorization,Content-Type
# 开启安全控制
xpack.security.enabled: true
xpack.security.transport.ssl.enabled: true

docker-compose -f es.yml up -d (设置密码的流程再上面) 访问ip:9200 输入密码后进入服务正常

然后是kibana 

version: '3'

# 网桥es -> 方便相互通讯
networks:
  es:

services:
 kibana:
    image: elastic/kibana:7.17.2
    container_name: kibana
    volumes:
      - ./kibana/kibana.yml:/usr/share/kibana/config/kibana.yml
    hostname: kibana
    #depends_on:
    #  - elasticsearch
    #links:
    # - elasticsearch
    restart: always
    ports:
      - "5601:5601"
    networks:
      - es

然后是挂载yml (/kibana/kibana.yml)

server.name: kibana
server.host: "0.0.0.0"
elasticsearch.hosts: [ "http://xxx.xxx.xx.xx:9200" ] # 修改为自己的ip 
xpack.monitoring.ui.container.elasticsearch.enabled: true
elasticsearch.username: "elastic"  # es账号
elasticsearch.password: "hzs888"   # es密码
i18n.locale: zh-CN # 中文

docker-compose -f kibana.yml up -d 访问ip:5601 输入密码后进入服务正常 这时就还差数据接入了

logstash

version: '3'

services:
  logstash:
    image: elastic/logstash:7.17.2
    container_name: logstash
    hostname: logstash
    restart: always
    environment:
      - TZ=Asia/Shanghai
    volumes:
      - ./logstash/conf/logstash:/usr/share/logstash/config
      - ./logstash/log:/usr/share/logstash/logs
    #depends_on:
    #  - elasticsearch
    ports:
      - 9600:9600
      - 5044:5044

然后是挂载 ./logstash/conf/logstash 下的 logstash-simple.conf 文件 和 logstash.yml 文件  

input {
  kafka {
    #id => "kafkalogs"
    group_id => "logs"
    bootstrap_servers => ["xxx.xx.xxx.xxx:9092"]
    topics => ["api-logs"]
    consumer_threads => 5
    #auto_offset_reset => "latest"
    codec => json
  }
}
filter {

    date {
       match => ["timestamp","yyyy-MM-dd'T'HH:mm:ss,sss"]
       remove_field => "timestamp"
       target => "@timestamp"
    }

}
output {
  elasticsearch {
    hosts => ["xxx.xxx.xxx.xx:9200"]
    index => "kafka‐%{+YYYY.MM.dd}"
    user => "elastic"
    password => "hzs888"
  }
}

yml文件

http.host: "0.0.0.0"
xpack.monitoring.elasticsearch.hosts: [ "http://xxx.xxx.xxx.xx:9200" ]
xpack.monitoring.enabled: true
path.config: /usr/share/logstash/config/*.conf
path.logs: /usr/share/logstash/logs

docker-compose -f logstash.yml up -d  这个服务看容器正常就行

总的目录结构如下

 然后往kafka里面写一组数据

 好然后看面板是否正常

 然后如果没有数据,就会告诉你需要集成哪些模块之类的 那就检查自己的服务就好

下面是有内容后的

 

 我这里还有个需求就是能不能按照微服务的服务名称进行类似于group by统计 这样在查询的时候就不用那么麻烦指定去搜索什么内容显示了 这个要是以后发展怎么用了再补充

 

posted on 2023-03-25 20:35  白码一号  阅读(2490)  评论(0编辑  收藏  举报