Docker 部署 Elasticsearch8.14.3 + kibana

271 阅读4分钟

部署

首先要创建一个网络,将两个容器置在同一网络中。

docker network create es-net

# 镜像
docker pull elasticsearch:8.14.3
docker pull kibana:8.14.3

ES 命令

  • -e "ES_JAVA_OPTS=Xms512m -Xmx512m" JVM 的内存大小
  • -e "discovery.type=single-node" 单点启动
  • 分别挂载了数据卷、插件卷、日志卷和配置文件
  • privileged 赋予了更高的权限,授予逻辑卷访问权
  • 9200 是http端口,9300 是es内部通信端口
docker run -d --name es -e "ES_JAVA_OPTS=-Xms512m -Xmx512m" -v D:/docker_config/elasticsearch/data:/usr/share/elasticsearch/data -v D:/docker_config/elasticsearch/plugins:/usr/share/elasticsearch/plugins -v D:/docker_config/elasticsearch/logs:/usr/share/elasticsearch/logs -v D:/docker_config/elasticsearch/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml --privileged --network es-net -p 19200:9200 -p 19300:9300 elasticsearch:8.14.3

补全一下配置

yml 文件

cluster.name: "docker-cluster"
# 访问支持
network.host: 0.0.0.0
# 关闭安全认证
xpack.security.enabled: false
# 单节点模式
discovery.type: single-node

为什么要做https

要使用 kibana 进行绑定,必须是https

需要在 exec 中执行一些命令

  1. 生成证书,设置本机IP即可,localhost和127.0.0.1 目测没用。最终会在 /usr/share/elasticsearch/config/certs 下生成一个证书文件。
/usr/share/elasticsearch/bin/elasticsearch-certutil cert --pass 123456 --self-signed --out config/certs/elastic-certificates.p12 --ip 172.21.0.2
  1. 生成登录密码,用于登录9200端口
/usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic

image.png

  1. 生成密钥用于登录 kibana

安裝 kibana,一定要和es在同一个网络。

docker run -d --name kibana  -v D:/docker_config/kibana/kibana.yml:/usr/share/kibana/config/kibana.yml --network=es-net -p 5601:5601 kibana:8.14.3

配置文件

server.host: "0.0.0.0"
server.shutdownTimeout: "5s"
# es 地址
elasticsearch.hosts: [ "http://es:9200" ]
monitoring.ui.container.elasticsearch.enabled: true

# 中文界面
i18n.locale: "zh-CN"

安装 ik 分词器

首先打开地址:IK 分词器

选择合适自己的版本,我这里是 8.14.3

解压到之前的挂载的插件目录即可。

image.png

重启 elasticsearch

yml 部署

核心配置

version: '3.8'

services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.11.3
    container_name: elasticsearch
    environment:
      - discovery.type=single-node
      - ELASTIC_PASSWORD=1234
      - ES_JAVA_OPTS=-Xms2g -Xmx2g
    ports:
      - "9200:9200"
      - "9300:9300"
    # volumes:
      # - ./es_data:/usr/share/elasticsearch/data
    # Compose v3.8 在 Windows 上稳定分配内存
    deploy:
      resources:
        limits:
          memory: 2g

  kibana:
    image: docker.elastic.co/kibana/kibana:8.11.3
    container_name: kibana
    ports:
      - "5601:5601"
    # environment:
      # - SERVER_HOST=0.0.0.0
    depends_on:
      - elasticsearch

  logstash:
    image: docker.elastic.co/logstash/logstash:8.11.3
    container_name: logstash
    ports:
      - "5044:5044"   # SpringBoot 日志发送端口
    volumes:
      - ./logstash/pipeline:/usr/share/logstash/pipeline
    depends_on:
      - elasticsearch

# volumes:
  # es_data:

logstash.conf

# -----------------------------
# Input: 接收 SpringBoot 日志
# -----------------------------
input {
  tcp {
    port => 5044           # SpringBoot 日志发送端口
    codec => json_lines    # 日志 JSON 格式
  }
}

# -----------------------------
# Filter: 可以在这里处理日志(可选)
# -----------------------------
# filter {
#   mutate {
#     add_field => { "environment" => "dev" }
#   }
# }

# -----------------------------
# Output: 输出到 Elasticsearch 和控制台调试
# -----------------------------
output {
  # 1. 写入 Elasticsearch
  elasticsearch {
    hosts => ["https://host.docker.internal:9200"]   # Docker Compose 内部服务名
    index => "app-log-%{+YYYY.MM.dd}"       # 按日期生成索引
    user => "elastic"                        # 如果 ES 开启认证,需要填账号
    ssl => true
    ssl_verification_mode => "none"
    password => "1234"                   # 默认密码,开发可用
  }

  # 2. 控制台调试
  stdout {
    codec => rubydebug
  }
}

登录 kibana

在 es 的终端执行命令

# 在 es 执行,获取token
/usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s kibana
# 在 kibana 生成密码,通常不需要执行,默认就执行了
bin/kibana-verification-code

测试es是否启动成功

curl -vk -u elastic:1234 https://localhost:9200

SpringBoot 将日志上传到 LogStash

<!-- 日志-->
<dependency>
    <groupId>net.logstash.logback</groupId>
    <artifactId>logstash-logback-encoder</artifactId>
    <version>7.4</version>
</dependency>

创建 logback-logstash.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 日志存放路径 -->
    <property name="log.path" value="/home/ruoyi/logs" />
    <!-- 日志输出格式 -->
    <property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />

    <!-- 控制台输出 -->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>

    <appender name="logstash" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
        <!--logstash的服务地址和端口,可以实际情况设置-->
        <destination>localhost:5044</destination>
        <!-- 日志输出编码 -->
        <encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder">
            <providers>
                <timestamp>
                    <timeZone>UTC</timeZone>
                </timestamp>
                <pattern>
                    <pattern>
                        {
                        <!--应用名称 -->
                        "app": "ruoyi-admin",
                        <!--打印时间 -->
                        "timestamp": "%d{yyyy-MM-dd HH:mm:ss.SSS}",
                        <!--线程名称 -->
                        "thread": "%thread",
                        <!--日志级别 -->
                        "level": "%level",
                        <!--日志名称 -->
                        "logger_name": "%logger",
                        <!--日志信息 -->
                        "message": "%msg",
                        <!--日志堆栈 -->
                        "stack_trace": "%exception"
                        }
                    </pattern>
                </pattern>
            </providers>
        </encoder>
    </appender>

    <!-- 系统日志输出 -->
    <appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/sys-info.log</file>
        <!-- 循环政策:基于时间创建日志文件 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日志文件名格式 -->
            <fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!-- 日志最大的历史 60天 -->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!-- 过滤的级别 -->
            <level>DEBUG</level>
            <!-- 匹配时的操作:接收(记录) -->
            <onMatch>ACCEPT</onMatch>
            <!-- 不匹配时的操作:拒绝(不记录) -->
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/sys-error.log</file>
        <!-- 循环政策:基于时间创建日志文件 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日志文件名格式 -->
            <fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!-- 日志最大的历史 60天 -->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <!-- 过滤的级别 -->
            <level>ERROR</level>
            <!-- 匹配时的操作:接收(记录) -->
            <onMatch>ACCEPT</onMatch>
            <!-- 不匹配时的操作:拒绝(不记录) -->
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- 用户访问日志输出  -->
    <appender name="sys-user" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${log.path}/sys-user.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 按天回滚 daily -->
            <fileNamePattern>${log.path}/sys-user.%d{yyyy-MM-dd}.log</fileNamePattern>
            <!-- 日志最大的历史 60天 -->
            <maxHistory>60</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>${log.pattern}</pattern>
        </encoder>
    </appender>

    <!-- 系统模块日志级别控制  -->
    <logger name="com.ruoyi" level="info" />
    <!-- Spring日志级别控制  -->
    <logger name="org.springframework" level="warn" />

    <root level="info">
        <appender-ref ref="console" />
    </root>

    <!--系统操作日志-->
    <root level="info">
        <appender-ref ref="logstash" />
        <appender-ref ref="file_info" />
        <appender-ref ref="file_error" />
    </root>

    <!--系统用户操作日志-->
    <logger name="sys-user" level="info">
        <appender-ref ref="sys-user"/>
    </logger>
</configuration> 

启动配置

# 日志配置
logging:
  # 添加额外的日志配置
  config: classpath:logback-logstash.xml

kibana 查看日志

创建索引

查看索引,通过SpringBoot 会自己创建索引

image.png

创建视图

image.png

image.png

查看日志

image.png

条件查询

image.png

一般检查时间检索的字段为:@timestamp,可以提供以下几种时间范围查询方式

image.png

  • 按照年查询
@timestamp < "2024"
  • 按照年月查询
@timestamp < "2024-09"
  • 按照年月日查询
@timestamp:"2024-09-05"
  • 按照年月日时分秒查询
@timestamp < "2024-09-02T21:55:59"

通过指定字段名进行搜索,可以更精确地定位到包含特定信息的日志条目。例如,message:"error"会匹配消息字段中包含“error”的日志条目。