欢迎光临
我们一直在努力

【DOCKER容器实战】-3 ElasticSearch + Kibana

文章目录

  • 容器化应用实战:ElasticSearch + Kibana
    • 一、ElasticSearch 部署
      • 1. 下载 ES 镜像
      • 2. 准备目录与配置文件
      • 3. 启动容器
    • 二、Kibana 部署
      • 1. 下载 Kibana 镜像
      • 2. 启动容器,指向 ES 位置
    • 三、自定义网络方案(推荐)
      • 1. 创建自定义网络
      • 2. 启动 ElasticSearch,加入自定义网络 es-net
      • 3. 启动 Kibana,同样加入 es-net 网络
      • 4. 两种方案对比
      • 5. 调试小技巧
    • 四、报错复盘:单文件挂载坑
      • 1. 现象
      • 2. 故障根因
      • 3. 本次排障里的错误操作
      • 4. 完整正确处理流程
      • 5. 经验教训
      • 6. 可选规避方案

容器化应用实战:ElasticSearch + Kibana

[!note] 核心摘要

  • ES 单节点:必须加 discovery.type=single-node,低配机器用 ES_JAVA_OPTS 限制 JVM 堆内存
  • 版本一致:ES 与 Kibana 版本必须完全一致(本例均为 7.17.0)
  • 容器互联:ES 与 Kibana 加入同一自定义网络,ELASTICSEARCH_HOSTS 直接写容器名,不依赖宿主机 IP
  • 高频坑:bind-mount 挂载单个文件前必须提前手动创建文件,否则 docker 会生成同名目录导致启动失败

一、ElasticSearch 部署

1. 下载 ES 镜像

[root@localhost ~]# docker pull elasticsearch:7.17.0
7.17.0: Pulling from library/elasticsearch
ea362f368469: Pull complete
49618e7bd315: Pull complete
ef2c6f195245: Pull complete
c32ac7edc3c3: Pull complete
85e392fc2cc0: Pull complete
4aff618a9264: Pull complete
795bd33f4eb3: Pull complete
ab1c10cef766: Pull complete
1cf47933dd34: Pull complete
Digest: sha256:332c6d416808f6e9a2cbcbe0170d9a9bb14bfe772180d37de5084c223dd8948b
Status: Downloaded newer image for elasticsearch:7.17.0
docker.io/library/elasticsearch:7.17.0

2. 准备目录与配置文件

创建配置文件目录、数据文件目录:

[root@localhost ~]# mkdir -p /opt/es/config
[root@localhost ~]# mkdir -p /opt/es/data

创建监听端口资源(写入 ES 配置文件):

[root@localhost ~]# echo "http.host: 0.0.0.0" >> /opt/es/config/elasticsearch.yml

开启权限(ES 容器内用户 uid=1000,防止权限拒绝):

[root@localhost ~]# chmod -R 777 /opt/es/

3. 启动容器

[root@localhost ~]# docker run –name elasticsearch -p 9200:9200 -p 9300:9300 \\
> -e "discovery.type=single-node" \\
> -e ES_JAVA_OPTS="-Xms512m -Xmx512m" \\
> -v /opt/es/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \\
> -v /opt/es/data:/usr/share/elasticsearch/data \\
> -v /opt/es/plugins:/usr/share/elasticsearch/plugins \\
> -d elasticsearch:7.17.0
e6d5b38f691861cc39c7ec944e29c01ff758aeb8e423e7a4936a2419f4ebb58a

查看容器:

[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e6d5b38f6918 elasticsearch:7.17.0 "/bin/tini — /usr/l…" 4 seconds ago Up 2 seconds 0.0.0.0:9200->9200/tcp, :::9200->9200/tcp, 0.0.0.0:9300->9300/tcp, :::9300->9300/tcp elasticsearch

参数简单说明

  • discovery.type=single-node:单节点模式,不需要集群,本地测试必加
  • ES_JAVA_OPTS="-Xms512m -Xmx512m":JVM 堆内存,最小最大都设 512M,低配机器防止占满内存
  • -v:挂载配置、数据、插件目录到宿主机
  • 9200:ES HTTP 访问端口;9300:ES 集群内部通信端口
  • 验证访问:curl http://127.0.0.1:9200,返回 json 代表启动成功。

    二、Kibana 部署

    1. 下载 Kibana 镜像

    [root@localhost ~]# docker pull kibana:7.17.0
    7.17.0: Pulling from library/kibana
    ea362f368469: Already exists
    94aca20bb05b: Pull complete
    65ae9e597e86: Pull complete
    d29743d928b1: Pull complete
    23891b890413: Pull complete
    8bf7af96af27: Pull complete
    014dfb291cad: Pull complete
    8bf3742fc390: Pull complete
    7b0e9c8dbcb7: Pull complete
    4dab17aa5385: Pull complete
    807090e8d21f: Pull complete
    87d0ac3cb26e: Pull complete
    ed92e0cf24d4: Pull complete
    Digest: sha256:a98b0797fd5357ba8a64c32df0e2e24dc7ad2df3320891b090a1f713124f1c95
    Status: Downloaded newer image for kibana:7.17.0
    docker.io/library/kibana:7.17.0

    2. 启动容器,指向 ES 位置

    [root@localhost ~]# docker run –name kibana -e ELASTICSEARCH_HOSTS=http://192.168.100.152:9200 -p 5601:5601 -d kibana:7.17.0
    8cd2108ffe49cd6dd7eac21b93b4204beb1ca0ab6b45a2bedd1a7d980e7ea4b1

    参数说明:

    • ELASTICSEARCH_HOSTS:指定 Kibana 连接 ES 的地址,这里要填宿主机真实 IP,不要写 127.0.0.1(容器内部 127.0.0.1 代表容器自己)
    • 5601:Kibana 网页访问端口,浏览器访问 http://宿主机IP:5601

    [!warning] 版本一致性 ES 和 Kibana 版本必须完全一致,这里都是 7.17.0。

    三、自定义网络方案(推荐)

    上面脚本里的方式 ELASTICSEARCH_HOSTS=http://192.168.100.152:9200,是 Kibana 容器走宿主机物理 IP 访问 ES。

    缺点:要写死宿主机 IP,换机器、IP 一变就要改启动命令;还要防火墙放行 9200 端口。

    [!note] 更推荐的方案 自定义 docker 网络:两个容器接入同一个自定义网络,直接用容器名字当域名互相访问,不用写宿主机 IP。

    1. 创建自定义网络

    # 创建 es-net 网络
    docker network create es-net

    2. 启动 ElasticSearch,加入自定义网络 es-net

    把原来的 run 命令加上 –network es-net:

    docker run –name elasticsearch \\
    –network es-net \\
    -p 9200:9200 -p 9300:9300 \\
    -e "discovery.type=single-node" \\
    -e ES_JAVA_OPTS="-Xms512m -Xmx512m" \\
    -v /opt/es/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \\
    -v /opt/es/data:/usr/share/elasticsearch/data \\
    -v /opt/es/plugins:/usr/share/elasticsearch/plugins \\
    -d elasticsearch:7.17.0

    3. 启动 Kibana,同样加入 es-net 网络

    ELASTICSEARCH_HOSTS 直接写容器名 elasticsearch 作为域名,docker 内部 DNS 自动解析,不用写宿主机 IP:

    docker run –name kibana \\
    –network es-net \\
    -e ELASTICSEARCH_HOSTS=http://elasticsearch:9200 \\
    -p 5601:5601 \\
    -d kibana:7.17.0

    关键点:

    • 同一个自定义网络内,容器名就是主机名,kibana 内部访问 http://elasticsearch:9200 就能连通 ES
    • 不再依赖宿主机局域网 IP,宿主机 IP 怎么变,容器之间通信不受影响
    • 不需要宿主机防火墙开放 9200 端口给外部,9200 只需要宿主机本地访问调试用,kibana 走 docker 内部网络

    4. 两种方案对比

    方式配置写法优点缺点
    宿主机 IP 访问 http://192.168.100.152:9200 简单,不用新建网络 IP 写死,IP 变更要改配置,需要防火墙放行 9200
    自定义 docker 网络 http://elasticsearch:9200 容器名做域名,不依赖宿主机 IP,网络隔离,生产推荐 需要提前创建网络

    5. 调试小技巧

    进入 kibana 容器内部测试连通性:

    docker exec -it kibana curl http://elasticsearch:9200

    能返回 ES 的 json 信息,代表网络通信正常。

    [!warning] 容易踩坑 bridge 默认网络不支持容器名 DNS 解析,必须自己 create 的自定义网络才支持容器名域名解析,这点很容易踩坑。

    四、报错复盘:单文件挂载坑

    1. 现象

    执行 docker run 启动 elasticsearch,命令返回一串 OCI runtime 报错,容器创建出来但启动失败,docker ps -a 看到状态为 Created,无法 up 运行。

    报错核心提示:

    Are you trying to mount a directory onto a file (or vice-versa)?
    not a directory

    2. 故障根因

    使用 bind-mount 挂载单个文件:

    -v /opt/es/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml

    宿主机上 /opt/es/config/elasticsearch.yml 文件没有提前手动创建。

    Docker bind-mount 底层限制:mount –bind 只能绑定已经存在的对象,不能凭空生成文件。 👉 宿主机该路径不存在时,Docker 会自动 mkdir,生成一个名字叫 elasticsearch.yml 的文件夹,并不是 yml 配置文件。

    于是冲突出现:

    • 宿主机:elasticsearch.yml → 文件夹(docker 自动创建)
    • 容器内部目标:elasticsearch.yml → 普通配置文件

    试图把宿主机目录挂载覆盖容器内文件,直接抛出挂载异常。

    [!warning] 迷惑点 ls /opt/es/config/ 能看到这个名字,肉眼分不清是文件还是文件夹,必须 ls -l 看第一位,d 代表目录,- 代表普通文件。

    3. 本次排障里的错误操作

    看到挂载报错后,去删除 /opt/es/data/nodes/ 数据目录。

    • 这个报错发生在容器初始化挂载阶段,ES 程序还没有启动,根本还没访问 data 数据目录
    • 删除 nodes 属于无效操作,解决不了本次挂载问题
    • 同时残留了状态为 Created 的失败容器,如果不删除,下次 run 会报容器名称已存在

    4. 完整正确处理流程

  • 校验对象真实类型:
  • ls -l /opt/es/config/elasticsearch.yml

  • 如果它是目录(d 开头),删除这个错误目录:
  • rm -rf /opt/es/config/elasticsearch.yml

  • 手动真正生成 yml 配置文件:
  • echo "http.host: 0.0.0.0" > /opt/es/config/elasticsearch.yml

  • 给目录权限(ES 内部用户 uid=1000,防止后续权限拒绝):
  • chmod -R 777 /opt/es

  • 清理残留的 Created 状态旧容器:
  • docker rm -f elasticsearch

  • 重新执行 docker run 启动容器。
  • 5. 经验教训

  • -v 绑定宿主机单个文件时,文件必须提前手动创建;宿主机不存在,docker 会错误生成目录,这是高频坑。
  • -v 绑定目录时,宿主机不存在,docker 自动创建目录,行为正常。
  • Created 容器状态:代表容器对象创建成功,但启动失败,不会自动删除,需要手动 rm 清理。
  • 看类型不要只看文件名,用 ls -l 分辨是文件还是文件夹。
  • 报错要看准报错栈:报错信息写哪个路径,问题就出在哪个路径,不要去操作无关目录。
  • 6. 可选规避方案

    学习环境,不挂载单个 yml,改为挂载整个 config 目录,规避该坑:

    -v /opt/es/config:/usr/share/elasticsearch/config

    [!warning] 注意 该方式要求宿主机 config 目录内要有 ES 完整配置文件,不能只放一个 yml。

    赞(0)
    未经允许不得转载:171主机测评 » 【DOCKER容器实战】-3 ElasticSearch + Kibana
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址