昨天在Docker中配置ElasticSearcch8集群模式时,先初步配置了master主节点。然后主节点启动就报错,看日志,提示“Device or resource busy”。异常第一句大概这个样子:
Exception in thread "main" java.nio.file.FileSystemException:
/usr/share/elasticsearch/config/elasticsearch.yml.Dym72YkCRZ-GMAliqWE2IA.tmp ->
/usr/share/elasticsearch/config/elasticsearch.yml: Device or resource busy
直译过来就是“elasticsearch.yml”文件系统异常:设备或资源忙。
搜索了一下,大概就是因为Linux系统中挂载映射目录时,引起的文件占用问题。
然后从这个角度来搜索各种解决方案,然后国内的解决方案统一都是:先别使用Docker -v映射elasticsearch.yml到容器中。应当先创建容器,然后使用docker cp命令把elasticsearch.yml从宿主机中拷贝到容器中!
然而道理说不通啊,因为我单机模式节点启动是成功的,凭啥集群了这个“elasticsearch.yml”会被系统占用而不能读取呢?
最后我搜啊搜啊搜,搜到了github的elasticsearch官方项目的问题提交区(issues),里面也是一群大佬在各种分析底层源代码,各种debug、反汇编,神讨论,但还是不能解决问题。
最后,在这个问题页面的下面,有人写了一句话,就解决了这个问题!说明这个就是elasticsearch本身的bug呗!
解决方案如下:
关键点:
在“elasticsearch.yml”文件中,只要配置了xpack的安全选项,就能正常启动了!
也就是在配置文件中添加最关键的一句:
# 开启x-pack插件,用于添加账号密码、安全控制等配置
xpack.security.enabled: false #最关键的一句
xpack.security.transport.ssl.enabled: false
xpack.security.enrollment.enabled: true
原文网址(超链接):Elasticsearch fails to start in Docker, when `elasticsearch.yml` is bind mount · Issue #85463 · elastic/elasticsearch · GitHub
最后把我的master的“elasticsearch.yml”完整贴出来:
#集群名称
cluster.name: elasticsearch-cluster
#节点名称
node.name: masternode
#设置绑定的ip地址,可以使ipv4或者ipv6 绑定这台机器的任何一个ip
network.bind_host: 0.0.0.0
#设置其他节点和该节点交互的ip地址,如果不设置它会自动判断,值必须是个真实的ip地址
network.publish_host: 0.0.0.0
#设置对外服务的http端口,默认为9200
http.port: 9200
#设置节点之间的tcp端口,默认是9300(ElasticSearch8新配置)
transport.profiles.default.port: 9300
#开发环境,暂时关闭x-pack安全控制配置
xpack.security.enabled: false
#是否允许跨域REST请求
http.cors.enabled: true
#允许REST请求来自何处
http.cors.allow-origin: "*"
#初始master节点
cluster.initial_master_nodes: ['masternode']
#节点角色设置(ElasticSearch8新配置)
node.roles: [master]
#集群的节点列表(ElasticSearch8新配置)
discovery.seed_hosts: ["172.18.0.11:9300","172.18.0.12:9300","172.18.0.13:9300"]
#*****************下面elasticsearch8中不能设置!!!**********************
#集群中一直正常运行的,有成为master节点资格的最少节点数,默认为1
#discovery.zen.minimum_master_nodes: 1
注意:里面有几项是elasticsearch8中新的配置方式,这也是我排了好久的坑才配置对的!