使用 Docker 安装 Elasticsearch
Docker 搭建 Elasticsearch + Kibana 环境,并在过程中标注常见问题和解决方案。
1. 准备工作
在开始之前,请确认你本地已经安装了:
工具 | 版本建议 | 检查方式 |
---|---|---|
Docker | ≥ 20.x | docker -v |
Docker Compose | ≥ 2.x | docker compose version |
常见问题:
- 版本过低:老版本 Docker 对内存管理、网络有兼容性问题,建议升级到最新。
- Windows 用户 :建议使用 WSL2 + Docker Desktop,不要用 Hyper-V。
2. 选择 Elasticsearch 版本
建议选择 8.x 稳定版本(例如 8.15.0),因为:
- 7.x 之后安全功能(TLS、认证)逐渐成为默认配置
- 新手学习时如果用最新版本,文档和功能对齐度更高
建议镜像:
docker.elastic.co/elasticsearch/elasticsearch:8.15.0
官方镜像在 Elastic 仓库,不在 DockerHub。
3. 创建 Docker Compose 配置
新建一个目录,例如 es-docker
,然后创建 docker-compose.yml
:
yaml
version: "3.8"
services:
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:8.15.0
container_name: es01
environment:
- node.name=es01
- cluster.name=es-docker-cluster
- discovery.type=single-node
- bootstrap.memory_lock=true
- ES_JAVA_OPTS=-Xms1g -Xmx1g
- xpack.security.enabled=false # 学习环境可以先关闭安全认证
ulimits:
memlock:
soft: -1
hard: -1
volumes:
- es_data:/usr/share/elasticsearch/data
# 将容器内分词器配置同步到宿主机,方便修改保存
- ./ik-config:/usr/share/elasticsearch/config/analysis-ik
ports:
- 9200:9200
- 9300:9300
kibana:
image: docker.elastic.co/kibana/kibana:8.15.0
container_name: kib01
environment:
- ELASTICSEARCH_HOSTS=http://es01:9200
ports:
- 5601:5601
depends_on:
- elasticsearch
volumes:
es_data:
driver: local
4. 配置详解
配置项 | 作用 | 注意事项 |
---|---|---|
discovery.type=single-node |
单节点模式 | 必须加,否则容器会一直等待集群发现 |
bootstrap.memory_lock=true |
锁定内存 | 避免 swap 导致性能下降 |
ES_JAVA_OPTS=-Xms1g -Xmx1g |
JVM 内存 | 初学者建议 1g ,不要设置超过 Docker 可用内存 |
xpack.security.enabled=false |
关闭安全认证 | 学习时可关掉,否则要处理证书和密码 |
常见问题:
内存不足容器无法启动
- 解决:在 Docker Desktop 设置里调大内存(至少 2GB 给 ES)
安全认证卡住 (出现
bootstrap check failure
)
- 解决:确认已加
xpack.security.enabled=false
Kibana 无法连上 ES
- 解决:确认
ELASTICSEARCH_HOSTS=http://es01:9200
配置正确
5. 启动服务
在 es-docker
目录执行:
bash
docker compose up -d
检查容器状态:
bash
docker ps
看到类似输出说明启动成功:
CONTAINER ID IMAGE COMMAND STATUS PORTS
abc123 docker.elastic.co/elasticsearch/elasticsearch:8.15.0 "/bin/tini -- /usr/l..." Up 2 minutes 0.0.0.0:9200->9200/tcp
def456 docker.elastic.co/kibana/kibana:8.15.0 "/bin/tini -- /usr/l..." Up 2 minutes 0.0.0.0:5601->5601/tcp
6. 验证 Elasticsearch
在浏览器访问:
-
Elasticsearch: http://localhost:9200
你应该看到类似:
json{ "name" : "es01", "cluster_name" : "es-docker-cluster", "cluster_uuid" : "xxxx", "version" : { "number" : "8.15.0" }, "tagline" : "You Know, for Search" }
-
Kibana: http://localhost:5601
如果 Kibana 页面空白或报错:等 1-2 分钟,它需要时间初始化。
7. 学习建议
安装好之后,你可以:
-
基础操作
bashcurl -X GET "localhost:9200/_cat/indices?v" curl -X PUT "localhost:9200/test_index" curl -X POST "localhost:9200/test_index/_doc/1" -H 'Content-Type: application/json' -d '{"name":"Alice"}' curl -X GET "localhost:9200/test_index/_search?q=name:Alice"
-
使用 Kibana Dev Tools
- 打开 http://localhost:5601/app/dev_tools#/console
- 在左侧输入 DSL 查询,右侧返回结果,体验比 curl 友好。
8. 常见问题汇总(FAQ)
问题 | 原因 | 解决办法 |
---|---|---|
容器一直重启 | 内存不足 | 调大 Docker 内存 |
max virtual memory areas vm.max_map_count [65530] is too low |
Linux 内核参数限制 | sudo sysctl -w vm.max_map_count=262144 |
Kibana 502 错误 | ES 未启动好 | 先等 1-2 分钟,确认 ES 9200 可访问 |
Windows 下访问不了 | WSL2 网络配置 | 访问 localhost 而不是虚拟机 IP |
Go 语言连接 Docker 中的 Elasticsearch
1. 安装依赖
Elastic 官方提供 Go 客户端:
github.com/elastic/go-elasticsearch/v8
执行:
bash
go get github.com/elastic/go-elasticsearch/v8
2. 编写示例代码
新建一个文件 main.go
:
go
package main
import (
"bytes"
"context"
"encoding/json"
"fmt"
"log"
"strings"
elasticsearch "github.com/elastic/go-elasticsearch/v8"
)
// 定义一个简单的文档结构
type User struct {
Name string `json:"name"`
Age int `json:"age"`
}
func main() {
// 1. 配置 ES 客户端
cfg := elasticsearch.Config{
Addresses: []string{
"http://192.168.132.131:9200", // 连接 Docker 里的 ES
},
// 如果你开启了 xpack.security.enabled=true,需要在这里配置用户名密码
// Username: "elastic",
// Password: "your_password",
}
es, err := elasticsearch.NewClient(cfg)
if err != nil {
log.Fatalf("创建客户端失败: %s", err)
}
// 2. Ping 一下,确认连接成功
res, err := es.Info()
if err != nil {
log.Fatalf("连接 ES 失败: %s", err)
}
defer res.Body.Close()
fmt.Println("已连接到 Elasticsearch:", res)
// 3. 插入一条文档
user := User{Name: "Alice", Age: 25}
doc, _ := json.Marshal(user)
res, err = es.Index(
"users", // 索引名(如果不存在会自动创建)
bytes.NewReader(doc), // 文档内容
es.Index.WithDocumentID("1"), // 指定 ID = 1
es.Index.WithContext(context.Background()),
)
if err != nil {
log.Fatalf("写入文档失败: %s", err)
}
defer res.Body.Close()
fmt.Println("文档写入成功")
// 4. 搜索文档
query := `{
"query": {
"match": {
"name": "Alice"
}
}
}`
res, err = es.Search(
es.Search.WithContext(context.Background()),
es.Search.WithIndex("users"), // 查询的索引
es.Search.WithBody(strings.NewReader(query)),
es.Search.WithPretty(),
)
if err != nil {
log.Fatalf("搜索失败: %s", err)
}
defer res.Body.Close()
var result map[string]interface{}
if err := json.NewDecoder(res.Body).Decode(&result); err != nil {
log.Fatalf("解析响应失败: %s", err)
}
// 打印搜索结果
fmt.Println("搜索结果:")
hits := result["hits"].(map[string]interface{})["hits"].([]interface{})
for _, hit := range hits {
doc := hit.(map[string]interface{})
source := doc["_source"].(map[string]interface{})
fmt.Printf("ID=%s, Name=%s, Age=%.0f\n", doc["_id"], source["name"], source["age"])
}
}
3. 运行测试
确保 Docker 里的 Elasticsearch 已经启动 (9200
端口可访问)。
然后运行:
bash
go run main.go
你应该能看到类似输出:
已连接到 Elasticsearch: ...
文档写入成功
搜索结果:
ID=1, Name=Alice, Age=25
4. 常见问题(Go 端)
问题 | 原因 | 解决方法 |
---|---|---|
connection refused |
Docker 里的 ES 没启动 / 端口没映射 | 检查 docker ps ,确认 9200 端口暴露出来 |
security_exception |
你没关闭安全认证 | 在 docker-compose 里加 xpack.security.enabled=false 或配置用户名密码 |
index_not_found_exception |
查询的索引不存在 | 先写入文档,ES 会自动创建索引 |