Docker详细部署单机es8+kibana全过程文档

coverImg

Elasticsearch 8.x 向量支持版部署命令(带账号密码认证)

快速部署

Elasticsearch 8.x 内置向量支持(无需额外插件),默认开启 SSL 和账号密码认证,以下命令简化配置(关闭复杂 SSL 验证,仅保留账号密码登录):

# 1. 先创建网络(如果已创建可跳过)
docker network create es-net

# 创建文件
mkdir /opt/tools/docker-workspace/es8/es-data
mkdir /opt/tools/docker-workspace/es8/es-plugins

# 2. 启动 Elasticsearch 8.x(支持向量、账号密码登录)
# 核心认证配置:启用账号密码,关闭复杂 SSL(仅保留基础安全)
#   -e "xpack.security.enabled=true"
#   -e "xpack.security.transport.ssl.enabled=false" \
#   -e "xpack.security.http.ssl.enabled=false" \
# 初始化默认用户密码(elastic 是超级管理员)
#   -e "ELASTIC_PASSWORD=123456" \
# 指定 ES8 版本(推荐 8.11+,向量功能更稳定)
docker run -d \
    --name es \
    -e "ES_JAVA_OPTS=-Xms512m -Xmx512m" \
    -e "discovery.type=single-node" \
    -e "xpack.security.enabled=true" \
    -e "xpack.security.transport.ssl.enabled=false" \
    -e "xpack.security.http.ssl.enabled=false" \
    -e "ELASTIC_PASSWORD=123456" \
    -v /opt/tools/docker-workspace/es8/es-data:/usr/share/elasticsearch/data \
    -v /opt/tools/docker-workspace/es8/es-plugins:/usr/share/elasticsearch/plugins \
    --privileged \
    --network es-net \
    -p 9200:9200 \
    -p 9300:9300 \
    elasticsearch:8.15.3

关键说明:

    1. 向量支持:ES8 内置 dense_vector 字段类型,可直接存储向量数据(无需安装插件),支持余弦相似度、L2 距离等计算。
    2. 账号密码:
      • 用户名:elastic(默认超级管理员)
      • 密码:YourStrongPassword123!(可自行修改,需符合复杂度)
    1. 安全配置:关闭了 HTTP/Transport SSL(简化本地测试),生产环境建议开启 SSL(需额外配置证书)。

**访问:**172.16.114.23:9200

**用户名密码:**elastic/123456

输入用户名密码访问:

img

验证连通

# 用账号密码访问 ES 接口(返回 JSON 则成功)
curl -u elastic:YourStrongPassword123! http://localhost:9200

创建kibana 可视化

前置操作

步骤一:创建专用服务账号

ES8 高版本(8.0+)禁止 Kibana 使用 elastic 超级管理员账号直接连接!官方要求 Kibana 必须使用 专用服务账号(Service Account) 或 自定义角色账号,避免超级权限滥用。

在 ES 中创建 Kibana 专用账号(核心)

需要通过 ES 的命令行工具创建账号并分配权限,操作如下:

1、进入 ES 容器内部(确保 ES 已正常启动):

docker exec -it es /bin/bash

2、在容器内执行账号创建命令(创建用户 kibana_user,密码自定义,比如 KibanaPass123!):

# 1. 创建 Kibana 专用用户(用户名:kibana_user,密码:KibanaPass123!,可自行修改)
/usr/share/elasticsearch/bin/elasticsearch-users useradd kibana_user \
  -p KibanaPass123! \
  -r kibana_system,superuser  # 分配关键角色:kibana_system(Kibana 必需角色)+ superuser(兼容所有操作)
  • 角色说明:kibana_system 是 Kibana 运行必需的系统角色(包含读写 Kibana 系统索引的权限),superuser 是兼容权限(避免后续操作受限,测试环境可用;生产环境可按需缩减角色)。
  • 警告是 正常的权限调整提示,不用管!

img

# 2. 验证账号是否创建成功(可选)
/usr/share/elasticsearch/bin/elasticsearch-users list

img

当前用户为:

kibana_user
KibanaPass123!

步骤二:生成加密密钥

1)需要生成必要的加密密钥。您可以使用以下命令:

# 临时运行一个Kibana容器来生成密钥
docker run --rm kibana:8.15.3 bin/kibana-encryption-keys generate

img

得到密钥:

Settings:
xpack.encryptedSavedObjects.encryptionKey: 45d298a8bc2cd5e12376c2dc9b89e14d
xpack.reporting.encryptionKey: 57b68202be11be8f967fed68beab5936
xpack.security.encryptionKey: b2dfc99ab31228d29d6916b85ece2d77

2)创建Kibana配置文件

创建一个Kibana配置文件:

mkdir -p /opt/tools/docker-workspace/es8/kibana-config
chmod 777 -R /opt/tools/docker-workspace/es8/kibana-config

替换三个密钥:

img

# 写到特定配置文件中
# 用户名密码是单独创建的
# xpack密钥需要单独补充
cat > /opt/tools/docker-workspace/es8/kibana-config/kibana.yml << EOF
server.host: "0.0.0.0"
server.shutdownTimeout: "5s"
elasticsearch.hosts: [ "http://es:9200" ]
elasticsearch.username: "kibana_user"
elasticsearch.password: "KibanaPass123!"
monitoring.ui.container.elasticsearch.enabled: true
xpack.security.encryptionKey: "45d298a8bc2cd5e12376c2dc9b89e14d"
xpack.encryptedSavedObjects.encryptionKey: "57b68202be11be8f967fed68beab5936"
xpack.reporting.encryptionKey: "b2dfc99ab31228d29d6916b85ece2d77"
EOF

3)创建数据目录和插件目录

# 数据目录
mkdir -p /opt/tools/docker-workspace/es8/kibana-data
chmod 777 -R /opt/tools/docker-workspace/es8/kibana-data

快速部署

注意:一定要前置两个操作完成!!!

基于上面的es服务:

# 停止并删除旧 Kibana 容器(必须先删,否则配置不生效)
docker stop kibana
docker rm kibana

# 基于前置两个操作后,我们启动docker服务,一定要有挂载文件
docker run -d \
  --name kibana \
  --network es-net \
  -p 5601:5601 \
  -v /opt/tools/docker-workspace/es8/kibana-config/kibana.yml:/usr/share/kibana/config/kibana.yml:ro \
  -v /opt/tools/docker-workspace/es8/kibana-data:/usr/share/kibana/data \
  -v /opt/tools/docker-workspace/es8/es-plugins:/usr/share/elasticsearch/plugins
  kibana:8.15.3

成功跑起来:

img

img

测试访问

我们访问下kibana:http://172.16.114.23:5601/login

img

现在您可以通过浏览器访问 Kibana:

  • URL: http://172.16.114.23:5601
  • 用户名: elastic
  • 密码: 123456

此时即可进入:

img

进入dev-tools开始测试:

img

初步验证

分词器测试

测试默认自带分词器

GET _analyze
{
  "analyzer": "standard",
  "text": "自学java开发真的很容易"
}

img

测试ik中文分词器:

POST /_analyze
{
  "analyzer": "ik_max_word",
  "text": "自学java开发真的很容易"
}

初步测试会报错:

img

解决见下面:快速构建插件/配置ik中文分词器

安装成功后即可进行使用分析:

img

快速构建插件

配置ik中文分词器

问题分析:默认是没有ik中文分词器的

img

analyzer: "ik_max_word" 表明您正在使用 IK 分词器。请注意,IK 分词器不是 Elasticsearch 内置的,它是一个需要额外安装的插件。

如果您在运行上述命令时收到类似 analyzer [ik_max_word] not found 的错误,说明您的 ES 容器中没有安装该插件。

快速安装步骤:

# 1、进入es容器内部
docker exec -it es /bin/bash

# 2、在线安装 IK 插件 (确保容器可以访问互联网)
# 在容器内执行
# 确保插件版本与您的 ES 版本 (8.15.3) 匹配
# 官方仓库:https://github.com/infinilabs/analysis-ik/releases
# 参考文档:https://blog.csdn.net/u014282578/article/details/127815352
./bin/elasticsearch-plugin install https://get.infini.cloud/elasticsearch/analysis-ik/8.15.3

安装完成:

img

需要重启下es:

# 退出容器
exit

# 重启es
docker restart es

你会发现此时已经映射了:

img

常用操作汇总

索引相关

目的 命令 说明
列出所有索引 **GET /_cat/indices?v** 最常用,查看所有索引的概览和状态。
查看单个索引详情 **GET /your_index_name** 查看指定索引的完整配置(映射、设置等)。
查看索引结构 **GET /your_index_name/_mapping** 只查看索引的字段映射。
查看索引数据 **GET /your_index_name/_search** 查看索引中的文档数据。

示范:

# 查看所有索引的列表(最常用)列出集群中的所有索引及其关键信息。
# /_cat/indices: 这是 Cat API 的一个端点,用于提供人类可读的索引信息
# ?v: 这个参数很重要,它代表 verbose,会显示列的标题
GET /_cat/indices?v

# 获取单个索引的详细信息(创建索引信息)
# 查看blog_index这个索引
GET /blog_index

# 只查看索引的结构
# 只关心索引的字段映射,而不关心其他设置,可以使用 _mapping 端点。
GET /blog_index/_mapping

# 查看索引中的数据
# 当不提供任何查询条件时,它会返回索引中的所有文档(默认最多 10 条)
GET /blog_index/_search

实用命令查看索引分片节点:

# 查看所有索引的分片信息(汇总)
GET _cat/indices/file_document?v&s=index
# 查看索引的分片详情(单独某一个片,列举出来)
GET _cat/shards/file_document?v

# 查看当前分片数
GET _cat/indices/file_document?v
# 查看索引的详细参数信息【可查看该参数number_of_routing_shards】
GET /file_document/_settings?include_defaults=true

查询相关

查询: 核心是 GET /index_name/_search。

  • 组合查询用 bool。
  • 全文搜索用 must + match / multi_match。
  • 精确过滤用 filter + term / terms / range。
  • 排序用 sort。
  • 分页用 from 和 size。
组件 作用 使用场景 示例
bool 组合多个查询条件 复杂查询逻辑 同时满足A和B条件
must+match 全文内容搜索 关键词搜索 搜索标题包含"编程"
filter+term 精确值过滤 分类、状态筛选 分类=“技术”
sort 结果排序 按价格、时间排序 价格从高到低
from/size 分页控制 分页显示 第2页,每页10条
# 分页搜索
GET /索引名称/_search
{
  "from": 0,
  "size": 10
}

## 精确id查询
GET /索引名称/_doc/1

# 查询多个id
GET /索引名称/_search
{
  "query": {
    "ids": {
      "values": ["1", "2", "3"]
    }
  }
}

# 搜索包含关键词
GET /索引名称/_search
{
  "query": {
    "match": {
      "content": "搜索引擎"
    }
  }
}

# 精确匹配短语 (内容中包含的)
GET /索引名称/_search
{
  "query": {
    "match_phrase": {
      "content": "全文搜索引擎"
    }
  }
}

# 精确匹配内容(强制eq)
# 字段就是查询条件
GET /索引名称/_search
{
  "query": {
    "term": {
      "字段.keyword": "张三"
    }
  }
}

高亮查询

基础原生高量:

# 基础高量
GET /自定义索引/_search
{
  "query": {
    "match": {
      "content": "搜索关键词"
    }
  },
  "highlight": {
    "fields": {
      "content": {}  // 对content字段进行高亮
    }
  }
}

img

自定义高亮:

# 自定义高亮
GET /自定义索引/_search
{
  "query": {
    "match": {
      "title": "elasticsearch"
    }
  },
  "highlight": {
    "pre_tags": ["<em class=\"highlight\">"],  // 高亮开始标签
    "post_tags": ["</em>"],                   // 高亮结束标签
    "fields": {
      "title": {
        "fragment_size": 150,                 // 片段大小
        "number_of_fragments": 3              // 返回片段数量
      },
      "content": {
        "type": "plain"                       // 高亮器类型
      }
    }
  }
}

img

删除索引

// 删除字段索引
DELETE /自定义索引

个人学习案例

入门案例1:初步博客文章内容检索

完整的、从零开始的案例,包括:

1、创建索引:定义我们博客文章的数据结构。

2、插入数据:添加几篇博客文章到索引中。

3、全文检索:使用不同的查询方式来搜索我们的文章。

假设要创建一个博客文章的索引,每篇文章包含 title (标题), author (作者), publish_date (发布日期), 和 content (内容)。

第一步:创建索引

在插入数据之前,最好先定义好索引的“映射”。映射就像是数据库中的表结构,它定义了每个字段的数据类型(如 text, keyword, date 等)。

  • text 类型会被分词,用于全文搜索。
  • keyword 类型不会被分词,用于精确匹配、排序和聚合。

在 Dev Tools 中执行以下命令来创建一个名为 blog_index 的索引:

PUT /blog_index
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "fields": {
          "keyword": { 
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },
      "author": {
        "type": "text",
        "fields": {
          "keyword": { 
            "type": "keyword"
          }
        }
      },
      "publish_date": {
        "type": "date"
      },
      "content": {
        "type": "text"
      }
    }
  }
}

响应成功:

img

第二步:插入数据

单条插入数据

向 blog_index 中插入几篇博客文章。我们使用 PUT 命令并指定文档的 ID(例如 1, 2, 3)。

# 第一篇文章
PUT /blog_index/_doc/1
{
  "title": "Elasticsearch 入门教程",
  "author": "张三",
  "publish_date": "2024-05-20",
  "content": "Elasticsearch 是一个基于 Lucene 库的搜索引擎。它提供了一个分布式、多租户能力的全文搜索引擎,具有 HTTP Web 接口和无模式 JSON 文档。"
}

第一篇成功:

img

再次插入第二篇、第三篇:

第二篇:

PUT /blog_index/_doc/2
{
  "title": "使用 Python 进行数据分析",
  "author": "李四",
  "publish_date": "2024-05-21",
  "content": "Python 是一种强大的编程语言,广泛应用于数据科学、机器学习和 Web 开发。Pandas 和 NumPy 是进行数据分析的核心库。"
}

第三篇:

PUT /blog_index/_doc/3
{
  "title": "Elasticsearch 在日志监控中的应用",
  "author": "王五",
  "publish_date": "2024-05-22",
  "content": "ELK Stack (Elasticsearch, Logstash, Kibana) 是一个强大的日志管理和分析解决方案。Elasticsearch 负责存储和索引日志数据,实现快速的全文检索。"
}

每执行一条 PUT 命令,你都会收到一个确认响应,表明文档已成功创建。

多条批量插入数据

使用 _bulk API 批量插入数据,指定id的话就不会多插入的:

POST /blog_index/_bulk
{ "index": { "_id": 4 } }
{ "title": "机器学习基础", "author": "赵六", "publish_date": "2024-05-23", "content": "机器学习是人工智能的重要分支,涉及多种算法和模型。" }
{ "index": { "_id": 5 } }
{ "title": "数据库优化技巧", "author": "孙七", "publish_date": "2024-05-24", "content": "数据库性能优化包括索引优化、查询优化等多个方面。" }
{ "index": { "_id": 6 } }
{ "title": "Elasticsearch 集群部署", "author": "张三", "publish_date": "2024-05-25", "content": "生产环境中的 Elasticsearch 集群部署需要考虑节点配置和网络设置。" }

img

第三步:执行全文检索

示例 1:搜索包含特定关键词的文章

目标:搜索 content 字段中包含 "搜索引擎" 的所有文章。

GET /blog_index/_search
{
  "query": {
    "match": {
      "content": "搜索引擎"
    }
  }
}

img

**结果分析:**这个查询会返回第一篇和第三篇文章。因为它们的 content 字段都包含了“搜索引擎”这个词。ES 会根据相关性(_score)对结果进行排序。

示例 2:搜索标题或内容中包含 "Python" 的文章

同时在 title 和 content 字段中搜索 "Python"。这时可以使用 multi_match 查询。

GET /blog_index/_search
{
  "query": {
    "multi_match": {
      "query": "Python",
      "fields": ["title", "content"]
    }
  }
}

img

**结果分析:**这个查询会准确地返回第二篇文章,因为只有它的标题和内容中提到了 "Python"。

示例 3:精确匹配短语

如果我们想搜索一个完整的短语,比如 "全文搜索引擎",而不是包含“全文”和“搜索引擎”但分开的文档,可以使用 match_phrase。

GET /blog_index/_search
{
  "query": {
    "match_phrase": {
      "content": "全文搜索引擎"
    }
  }
}

img

**结果分析:**这个查询会返回第一篇文章,因为它精确地包含了 "全文搜索引擎" 这个短语。如果一篇文档里是“...一个全文的、强大的搜索引擎...”,它就不会被匹配到。

示例 4:使用 term 查询精确匹配 keyword 字段

GET /blog_index/_search
{
  "query": {
    "term": {
      "author.keyword": "张三"
    }
  }
}

img

**结果分析:**这个查询会精确地返回第一篇文章。注意,这里我们用的是 author.keyword 而不是 author。如果用 author,ES 会尝试对 "张三" 进行分词,可能得不到你想要的结果。

清理数据

# 直接删除索引
DELETE /blog_index

# 清理指定记录
DELETE /blog_index/_doc/1

更新值

# 更新单个字段
POST /blog_index/_update/1
{
  "doc": {
    "author": "张三丰",
    "views": 200
  }
}


# 更新并添加新字段
POST /blog_index/_update/2
{
  "doc": {
    "tags": ["Python", "数据分析", "编程"],
    "updated_at": "2024-05-26"
  }
}

说明更新单个字段值的时候,如果新增了字段也会更新进去,同时其他记录不会有这个字段:

img

查询值

根据id查询:

# 精确id查询
GET /blog_index/_doc/1

# 查询多个id
GET /blog_index/_search
{
  "query": {
    "ids": {
      "values": ["1", "2", "3"]
    }
  }
}

# 或者使用 terms 查询
GET /blog_index/_search
{
  "query": {
    "terms": {
      "_id": ["1", "2", "3"]
    }
  }
}

查询返回特定值:

# 特定只是返回title,author
GET /blog_index/_doc/1?_source_includes=title,author

入门案例2:

创建索引

PUT /books
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "analyzer": "ik_max_word",
        "search_analyzer": "ik_smart"
      },
      "author": {
        "type": "keyword"
      },
      "publish_date": {
        "type": "date"
      },
      "price": {
        "type": "float"
      },
      "category": {
        "type": "keyword"
      },
      "description": {
        "type": "text"
      },
      "stock": {
        "type": "integer"
      }
    }
  }
}

插入数据示例

POST /books/_bulk
{"index":{}}
{"title":"Elasticsearch权威指南","author":"张三","publish_date":"2023-01-15","price":89.5,"category":"技术","description":"全面介绍Elasticsearch的使用和原理","stock":50}
{"index":{}}
{"title":"Java编程思想","author":"李四","publish_date":"2022-05-20","price":108.0,"category":"编程","description":"Java编程的经典教程","stock":30}
{"index":{}}
{"title":"Python数据分析","author":"王五","publish_date":"2023-03-10","price":75.0,"category":"数据科学","description":"使用Python进行数据分析的实践指南","stock":25}
{"index":{}}
{"title":"机器学习实战","author":"赵六","publish_date":"2023-02-28","price":92.0,"category":"人工智能","description":"机器学习算法和实践案例","stock":40}
{"index":{}}
{"title":"深入理解Elasticsearch","author":"张三","publish_date":"2023-04-15","price":78.0,"category":"技术","description":"深入解析Elasticsearch内部机制","stock":35}

基础bool查询(组合查询)

场景: 查询作者是"张三" 且 价格低于80元 且 库存大于0的书籍

GET /books/_search
{
  "query": {
    "bool": {
      "must": [
        {"term": {"author": "张三"}}
      ],
      "filter": [
        {"range": {"price": {"lt": 80}}},
        {"range": {"stock": {"gt": 0}}}
      ]
    }
  }
}

说明:

  • bool 把多个条件组合在一起
  • must 里的条件必须满足
  • filter 里的条件也必须满足,但不影响评分

全文搜索 must + match/multi_match - 单独使用

场景: 在标题和描述中搜索"数据分析"相关内容

GET /books/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "multi_match": {
            "query": "数据分析",
            "fields": ["title", "description"]
          }
        }
      ]
    }
  }
}

或者只用 match:

GET /books/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "title": "机器学习实战"
          }
        }
      ]
    }
  }
}

说明:

  • must + match/multi_match 用于文本内容的模糊搜索
  • 会对搜索词进行分词处理
  • 适合搜索框输入的关键词搜索

精确过滤 filter + term/terms/range - 单独使用

场景: 精确筛选分类为"技术"或"编程",且价格在50-100元之间的书籍

GET /books/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "terms": {
            "category": ["技术", "编程"]
          }
        },
        {
          "range": {
            "price": {
              "gte": 50,
              "lte": 100
            }
          }
        }
      ]
    }
  }
}

说明:

  • filter 用于精确值过滤,不关心相关性评分
  • term - 精确匹配单个值
  • terms - 精确匹配多个值(类似SQL的IN)
  • range - 范围匹配

排序 sort - 单独使用

场景: 按价格从高到低排序,价格相同的按出版日期从新到旧排序

GET /books/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "price": {
        "order": "desc"
      }
    },
    {
      "publish_date": {
        "order": "desc"
      }
    }
  ]
}

说明:

  • sort 只影响结果的排序顺序
  • 可以多个字段组合排序
  • 不影响查询条件,只是对结果进行排序
  • "match_all": {} 是 Elasticsearch 中的一个特殊查询,含义非常简单,匹配所有文档 - 返回索引中的全部数据,不做任何条件过滤。如:SELECT * FROM table_name。

分页 from 和 size - 单独使用

场景: 查看第2页的数据,每页显示5条

GET /books/_search
{
  "query": {
    "match_all": {}
  },
  "from": 1,    // (第2页:2-1=1 × 5条=5)
  "size": 5     // 每页5条
}

说明:

  • from - 从第几条开始(偏移量)
  • size - 返回多少条
  • 计算公式:from = (页码 - 1) × size

完整组合使用示例

场景: 搜索包含"编程"的书籍,筛选技术类,价格50元以上,按价格降序排列,查看第1页每页10条

GET /books/_search
{
  "query": {
    "bool": {
      "must": [                    // 全文搜索
        {
          "match": {
            "title": "理解"
          }
        }
      ],
      "filter": [                  // 精确过滤
        {
          "term": {
            "category": "技术"
          }
        },
        {
          "range": {
            "price": {
              "gte": 50
            }
          }
        }
      ]
    }
  },
  "sort": [                        // 排序
    {
      "price": {
        "order": "desc"
      }
    }
  ],
  "from": 0,                       // 分页
  "size": 10
}

es一些特点

文档 ID 规则

Elasticsearch 文档 ID 规则:

  • 如果不指定 ID:Elasticsearch 会自动生成一个随机的 UUID 作为文档 ID
  • 如果指定 ID:使用你提供的 ID(如文件ID)
  • ID 不会自增:没有类似 MySQL 的 AUTO_INCREMENT 功能

实际可以根据业务中的id作为记录:

img

造数据我自己就不指定了

评论区请在客户端页面查看