如何使用一个IP搭建ES集群——Docker如你所愿

本文介绍如何使用Docker在一台服务器上部署Elasticsearch集群,包括配置多播和单播集群的方法,以及如何通过Logstash收集日志。

转载请注明出处:http://blog.youkuaiyun.com/gamer_gyt
博主微博:http://weibo.com/234654758
Github:https://github.com/thinkgamer


写在前边的话

随着业务的发展,elasticsearch部署在一台机子上显然会不够用,那么我们该如何处理呢,幸运的elasticsearch支持横向扩展,即集群模式,这样无论数据量增长多大,我们只需要扩展我们的es集群即可。

本文永久地址 http://blog.youkuaiyun.com/gamer_gyt/article/details/53648983


背景说明

Ubuntu16.04
Docker 1.9
Elasticsearch 2.4
假设现在就一台服务器,我们要用这台服务器来部署一个ES的集群,那么最好的解决办法便是Docker了,我们可以利用Docker启动两个容器,在两个容器内各部署一个ElasticSearch,总而组成一个2个节点的ES集群

linux下Docker的部署:http://blog.youkuaiyun.com/gamer_gyt/article/details/52769294
终端安装Docker:http://bbs.youkuaiyun.com/topics/392063910
我的Docker专栏:http://blog.youkuaiyun.com/column/details/13159.html


Docker网络模式解释

1:host模式

众所周知,Docker使用了Linux的Namespaces技术来进行资源隔离,如PID Namespace隔离进程,Mount Namespace隔离文件系统,Network Namespace隔离网络等。一个Network Namespace提供了一份独立的网络环境,包括网卡、路由、Iptable规则等都与其他的Network Namespace隔离。一个Docker容器一般会分配一个独立的Network Namespace。但如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。

例如,我们在10.10.101.105/24的机器上用host模式启动一个含有web应用的Docker容器,监听tcp80端口。当我们在容器中执行任何类似ifconfig命令查看网络环境时,看到的都是宿主机上的信息。而外界访问容器中的应用,则直接使用10.10.101.105:80即可,不用任何NAT转换,就如直接跑在宿主机中一样。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。

2:container模式

在理解了host模式后,这个模式也就好理解了。这个模式指定新创建的容器和已经存在的一个容器共享一个Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过lo网卡设备通信。

3:none模式

这个模式和前两个不同。在这种模式下,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。

4:bridge模式

bridge模式是Docker默认的网络设置,此模式会为每一个容器分配Network Namespace、设置IP等,并将一个主机上的Docker容器连接到一个虚拟网桥上


两个容器以组播方式创建ES集群

组播配置示例如下,单播配置在最下边,使用时只需替换加几行配置即可

1:下载Ubuntu最近版镜像

sudo docker pull ubuntu

2:配置基本环境

启动容器,进入容器内安装基本环境vim,java,和elasticsearch

sudo docker run -it -d --name esc1 ubuntu:latest
sudo docker exec -it esc1 /bin/bash
apt-get install vim
apt install openjdk-8-jre

然后安装es,下载安装包 点击下载
将其拷贝到docker内,安装

dpkg -i elasticsearch-2.4.0.deb

至此基本环境已经准备的差不多了,然后便是退出容器,stop 容器,然后进行commit 保存成两个容器

sudo docker commit esc1 es1:1.0
sudo docker commit esc1 es2:1.0

最后查看镜像如图所示:
这里写图片描述

3:es环境配置

分别启动两个容器

sudo docker run -it -d -p 9201:9201 -p 9301:9301 -p 5001:5001 -p 5602:5602 --name esc1 es1:1.0
sudo docker run -it -d -p 9200:9200 -p 9300:9300 -p 5000:5000 -p 5601:5601 --name esc2 es2:1.0

进入两个容器进行配置elasticsearch.ymal文件
esc1:

cluster.name: xdstar
node.name: node-1
node.master: false
node.data: true
network.host: 0.0.0.0
http.port: 9201
transport.tcp.port: 9301

esc2:

cluster.name: xdstar
node.name: node-2
node.master: true
node.data: true
network.host: 0.0.0.0
http.port: 9200
transport.tcp.port: 9300

cluster.name:集群名字,配置必须一样
node.name:每个节点的名字,不能一样
node.master: true 代表可以被选举为主节点,false代表不能被选举为主节点(这里我们设置esc2为主节点)
ndoe.data:代表是否可以存储数据
network.host:表示访问的ip,0.0.0.0表示可以以IP访问或者localhost,127.0.0.1
network.port:访问的端口

启动Elasticsearch

service elasticsearch start

细心的朋友会发现容器的启动端口转发端口不一致,这是因为,这里启动Docker容器默认采用的桥接,和主机共享端口了,所以两者端口不能一致,要不然会重复

启动完es集群,浏览器输入 https:192.168.1.250:9200/_plugin/head
(这里我安装了head插件,插件安装,参考之前的一篇文章,里边有讲到:http://blog.youkuaiyun.com/gamer_gyt/article/details/52654263)

这里写图片描述

4:安装logstash配置rsyslog解析文件

logstash 2.4版本 点击下载
更多版本:https://www.elastic.co/downloads/past-releases

dpkg -i logstash-all-plugins-2.4.0_all.deb

然后进入配置文件目录

cd /etc/logstash/conf.d
vim rsyscon.conf

添加以下内容

input {
   syslog{
    port => 5000
    type => syslog
  }
}
output {
  stdout {
    codec=> rubydebug
  }
  elasticsearch {
    hosts => ["localhost:9200"]
  }
}

启动logstash

service logstash start

5:本地配置,产生syslog日志

编辑rsyslog的配置文件:

vim /etc/rsyslog.conf

最后添加

 *.*  @localhost:5000
 *.*  @@localhost:5000

重启rsyslog服务

service rsyslog restart

ssh 本地,产生日志

ssh localhost

这个时候观察elasticsearch界面:
这里写图片描述


ES集群的多播与单播

    以上的集群是采用组播的方式来构建的,组播就是通过在你的网络中发送UDP的ping请求以发现节点,其它Elasticsearch会收到这些ping请求并且进行响应,这样随后就会形成一个集群。
    多播对于开发环境是很好的,你不需要做什么事情,打开一些节点,他们自然的会发现对方形成一个集群。
    正是因为这种易用性,你在生产环境中必须禁掉它。否在你得到的结果就是一个节点意外的加入到了你的生产环境,因为他们收到了一个错误的组播信号。对于组播本身并没有错。组播会导致一些愚蠢的问题,并且导致集群变的脆弱(例如:一个网络工程师正在捣鼓网络,而没有告诉你,你会发现所有的节点突然发现不了对方了)。
    在生产环境中,建议使用单播代替组播,也就是说为Elasticsearch提供一些它应该去尝试连接的节点列表。一旦这个节点联系到组播列表中的一员,它就会得到整个集群所有节点的状态,然后它会联系master节点,并加入集群。
    这意味着你的单播列表不需要包含你的集群中的所有节点,它只需要包含足够一个新节点联系上其中一个并且说上话就ok了。

    ES 是一个 P2P 类型(使用 gossip 协议)的分布式系统,除了集群状态管理以外,其他所有的请求都可以发送到集群内任意一台节点上,这个节点可以自己找到需要转发给哪些节点,并且直接跟这些节点通信。
    所以,从网络架构及服务配置上来说,构建集群所需要的配置极其简单。在 Elasticsearch 2.0 之前,无阻碍的网络下,所有配置了相同 cluster.name 的节点都自动归属到一个集群中。
    2.0 版本之后,基于安全的考虑,Elasticsearch 稍作了调整,避免开发环境过于随便造成的麻烦。

    ES 从 2.0 版本开始,默认的自动发现方式改为了单播(unicast)方式。配置里提供几台节点的地址,ES 将其视作 gossip router 角色,借以完成集群的发现。由于这只是 ES 内一个很小的功能,所以 gossip router 角色并不需要单独配置,每个 ES 节点都可以担任。所以,采用单播方式的集群,各节点都配置相同的几个节点列表作为 router 即可。
    此外,考虑到节点有时候因为高负载,慢 GC 等原因可能会有偶尔没及时响应 ping 包的可能,一般建议稍微加大 Fault Detection 的超时时间。
    同样基于安全考虑做的变更还有监听的主机名。现在默认只监听本地 lo 网卡上。所以正式环境上需要修改配置为监听具体的网卡。

network.host: "0.0.0.0" 
discovery.zen.minimum_master_nodes: 3
discovery.zen.ping.timeout: 100s
discovery.zen.fd.ping_timeout: 100s
discovery.zen.ping.unicast.hosts: ["10.19.0.97","10.19.0.98","10.19.0.99","10.19.0.100"]

    上面的配置中,两个 timeout 可能会让人有所迷惑。这里的 fd 是 fault detection 的缩写。也就是说:
    discovery.zen.ping.timeout 参数仅在加入或者选举 master 主节点的时候才起作用;
    discovery.zen.fd.ping_timeout 参数则在稳定运行的集群中,master 检测所有节点,以及节点检测 master 是否畅通时长期有用。
    既然是长期有用,自然还有运行间隔和重试的配置,也可以根据实际情况调整:

discovery.zen.fd.ping_interval: 10s
discovery.zen.fd.ping_retries: 10

单播配置

以上展示为组播方式,单播配置相对来说只需要在配置文件里加几行即可
esc1:

discovery.zen.ping.unicast.hosts: ["localhost:9300","localhost:9301"]

esc2:

discovery.zen.ping.unicast.hosts: ["localhost:9300","localhost:9301"]

PS:我这里尝试了很多次,增加了

discovery.zen.minimum_master_nodes: 3
discovery.zen.ping.timeout: 100s
discovery.zen.fd.ping_timeout: 100s

这三个属性之后集群并不能启动,所以这里只设置了discovery.zen.ping.unicast.hosts属性


【技术服务】,详情点击查看: https://mp.weixin.qq.com/s/PtX9ukKRBmazAWARprGIAg

扫一扫 关注微信公众号!号主 专注于搜索和推荐系统,尝试使用算法去更好的服务于用户,包括但不局限于机器学习,深度学习,强化学习,自然语言理解,知识图谱,还不定时分享技术,资料,思考等文章!


<think> 嗯,用户这次的问题很明确:elasticsearch 8.13.2集群搭建后本地无法访问。结合历史记录看,用户应该是个开发者,正在搭建ES环境用于电商项目,但遇到了网络连通性问题。ta之前尝试过docker部署单节点(8.13.3),现在搭建集群版可能遇到了类似问题。 用户引用的两条信息其实很有价值: 第一条docker命令暴露了关键点——单节点模式需要特殊配置discovery.type,而集群部署时这个参数可能没设置对。第二条提到电商项目需求,说明用户的生产环境要求较高,集群配置不能出错。 需要重点排查五个层面: 1 网络配置:docker网络模式是否隔离?用户用--net elastic说明创建了自定义网络,但本地访问可能需用host模式或端口映射 2 安全机制:8.x默认开启安全认证,用户之前用xpack.security.enabled=false跳过了,但集群环境可能更复杂 3 绑定地址:默认绑定127.0.0.1会导致容器外无法访问,需检查network.host 4 节点发现:集群发现配置不当会导致节点孤立,参考历史中discovery.type的配置差异 5 日志分析:ES启动日志会明确提示绑定失败原因,这是最直接的证据 尤其要注意8.x版本的安全策略升级——首次启动会自动生成密码和证书,如果用户没保存这些凭证也会导致访问被拒。在docker部署时还可能存在文件权限问题,需要chown -R 1000:0 /usr/share/elasticsearch/data 用户上次询问过8.13.2版本特性,这次搭建应该比较新,可以排除版本兼容性问题。ta的诉求很技术向,回复要聚焦解决方案而非概念解释,最好用步骤化的检查清单。另外ta明显参考了官方文档,可以提示查看特定章节(比如《Troubleshooting clustering》)来建立知识关联。 </think> 以下是Elasticsearch 8.13.2集群搭建后本地无法访问的**根本原因排查指南**,按优先级排序排查步骤: --- ### 🔍 一、核心原因排查(按频率排序) 1. **网络绑定错误**(最常见) - **现象**:ES默认绑定`127.0.0.1`,仅允许本机访问 - **修复**:在`elasticsearch.yml`中修改: ```yaml network.host: 0.0.0.0 # 允许所有IP访问 http.port: 9200 # 确认端口 ``` 📌 *重启集群生效* [^2] 2. **安全认证未关闭**(8.x默认开启) - **现象**:访问返回`401 Unauthorized` - **修复**(测试环境): ```yaml xpack.security.enabled: false # 关闭安全模块 ``` 3. **Docker网络配置问题** - **现象**:容器运行但宿主机无法访问 - **关键检查**: ```bash # 确认端口映射正确(-p 9200:9200) docker ps --format "table {{.Names}}\t{{.Ports}}" # 检查防火墙规则 sudo ufw status # Ubuntu sudo firewall-cmd --list-ports # CentOS ``` 4. **集群发现配置错误** - **现象**:节点日志报`master_not_found_exception` - **修复**(单机伪集群示例): ```yaml discovery.type: single-node # 单节点模式 # 或多节点集群: discovery.seed_hosts: ["host1:9300", "host2:9300"] cluster.initial_master_nodes: ["node1", "node2"] ``` --- ### ⚙️ 二、进阶诊断步骤 1. **检查节点日志** ```bash docker logs es-node1 # 容器部署 tail -f /var/log/elasticsearch/<cluster-name>.log # 物理机部署 ``` - 关键错误:`BindTransportException`(端口冲突)、`CertificateException`(SSL配置错误) 2. **验证集群健康状态** ```bash curl -XGET http://localhost:9200/_cluster/health?pretty ``` - 若返回`curl: (7) Failed to connect` → 网络层故障 - 若返回401 → 安全认证问题 3. **防火墙/安全组规则** - 开放端口:**9200**(HTTP API)、**9300**(节点通信) - 云服务器需额外检查安全组(AWS安全组、阿里云安全组等) --- ### ️ 三、Docker特有问题解决 若通过Docker部署,增加以下检查: ```bash # 1. 确认容器网络模式 docker inspect es-node1 | grep NetworkMode # 2. 测试容器内部连通性 docker exec -it es-node1 curl http://localhost:9200 # 3. 检查端口映射 docker port es-node1 9200 # 应输出 0.0.0.0:9200->9200/tcp ``` - **典型问题**: - 使用`bridge`网络但未映射端口(缺少`-p 9200:9200`) - 跨主机集群未配置`network.publish_host` --- ### ✅ 四、快速验证方案 ```bash # 临时关闭防火墙(测试用) sudo systemctl stop firewalld # CentOS sudo ufw disable # Ubuntu # 简化配置启动单节点(排除集群干扰) docker run -d --name es-test \ -p 9200:9200 -e "discovery.type=single-node" \ -e "xpack.security.enabled=false" \ docker.elastic.co/elasticsearch/elasticsearch:8.13.2 # 访问测试 curl http://localhost:9200 ``` 若返回JSON信息 → 证明基础功能正常,问题在集群配置[^1]。 --- ### 📌 总结排查路径 ```mermaid graph TD A[本地无法访问] --> B{检查端口9200响应} B -->|无响应| C[查看ES日志] B -->|401错误| D[关闭xpack.security] C --> E[检查network.host配置] E --> F[确认防火墙/SELinux状态] F --> G[检查Docker端口映射] ``` --- ### 🧩 相关问题 1. Elasticsearch 8.13.2 集群节点间通信失败的可能原因有哪些? 2. 如何在开启安全认证的情况下通过CURL访问Elasticsearch 8.x? 3. Docker部署Elasticsearch集群时如何正确配置跨主机网络? 4. Elasticsearch日志中出现`master_not_discovered_exception`应如何解决? 5. 云服务器部署Elasticsearch集群需要哪些额外的安全组配置?
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值