Zookeeper 合奏无法启动
Zookeeper ensemble won't start up
我已经设置了一个包含 3 个实例的 Zookeeper-ensemble(版本 3.4.9)。这在测试系统上就像一个魅力,但在实时系统上根本不会出现。错误信息如下:
2020-08-28 06:26:24,643 [myid:1] - WARN [WorkerSender[myid=1]:QuorumCnxManager@400] - Cannot open channel to 2 at election address /10.3.1.173:3888
java.net.NoRouteToHostException: Host is unreachable (Host unreachable)
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at org.apache.zookeeper.server.quorum.QuorumCnxManager.connectOne(QuorumCnxManager.java:381)
at org.apache.zookeeper.server.quorum.QuorumCnxManager.toSend(QuorumCnxManager.java:354)
at org.apache.zookeeper.server.quorum.FastLeaderElection$Messenger$WorkerSender.process(FastLeaderElection.java:452)
at org.apache.zookeeper.server.quorum.FastLeaderElection$Messenger$WorkerSender.run(FastLeaderElection.java:433)
at java.lang.Thread.run(Thread.java:745)
我已经在这里和其他地方搜索过,但唯一可以接受的问题解决方案是将每个节点的服务器地址设置为 0.0.0.0,这在此处不起作用。我的设置已完全 docker 化并应用了 ansible,因此它看起来可能与人们通常所做的有点不同。但是连接字符串例如对于 server.1 是这样的:
"server.1=0.0.0.0:2888:3888 server.2=10.3.1.173:2888:3888 server.3=10.3.1.175:2888:3888"
这也适用于 zookeepers 内部配置,如日志所示(同样适用于 server.1):
ZooKeeper JMX enabled by default
Using config: /conf/zoo.cfg
2020-08-28 06:26:23,549 [myid:] - INFO [main:QuorumPeerConfig@124] - Reading configuration from: /conf/zoo.cfg
2020-08-28 06:26:23,559 [myid:] - INFO [main:QuorumPeer$QuorumServer@149] - Resolved hostname: 10.3.1.175 to address: /10.3.1.175
2020-08-28 06:26:23,559 [myid:] - INFO [main:QuorumPeer$QuorumServer@149] - Resolved hostname: 10.3.1.173 to address: /10.3.1.173
2020-08-28 06:26:23,560 [myid:] - INFO [main:QuorumPeer$QuorumServer@149] - Resolved hostname: 0.0.0.0 to address: /0.0.0.0
2020-08-28 06:26:23,560 [myid:] - INFO [main:QuorumPeerConfig@352] - Defaulting to majority quorums
(...)
2020-08-28 06:26:23,570 [myid:1] - INFO [main:QuorumPeerMain@127] - Starting quorum peer
2020-08-28 06:26:23,577 [myid:1] - INFO [main:Login@294] - successfully logged in.
2020-08-28 06:26:23,579 [myid:1] - INFO [main:NIOServerCnxnFactory@89] - binding to port 0.0.0.0/0.0.0.0:2181
这适用于所有 3 个 zookeeper 实例,但其中 none 个可以与另一个实例通信。
附加信息:
- 除了服务器的 IP 地址外,配置与测试系统相同。 Ansible Docker 模块配置相同,JAAS-Config(带 DigestLoginModule)相同,所有 docker 容器内的环境变量也相同。
- live系统内的每台服务器都可以ping通其他服务器。我还可以从每个 Zookeeper 容器内 ping 这些服务器。此外,我可以从实时系统的任何其他容器内卷曲 JMX 端口上的每个 Zookeeper 容器。所以他们肯定可以通过网络连接。
请帮忙,谢谢:D
编辑:@Stefano 问我如何启动 docker 容器,所以我会尝试提供一些见解。如前所述,这是一个使用“docker_container”插件的任务中的 Ansible 设置,该插件在剧本中用于跨机器安装 3 个实例:
---
- name: Install Zookeeper
docker_container:
name: zookeeper
image: zookeeper:3.4.9
state: started
ports:
- "2181:2181" # Zookeeper Port
- "2888:2888"
- "3888:3888" # Election ports
- "9998:8080" # JMX metrics
env:
ZOO_MY_ID: "{{ ID }}" #this is 1 for server.1, etc.
ZOO_PORT: "2181"
ZOO_SERVERS: "{{ ZOO_SERVERS }}" #provided in host-vars
SERVER_JVMFLAGS: "-Djava.security.auth.login.config=/etc/kafka/zookeeper_jaas.conf -javaagent:/opt/jmx-exporter/jmx_prometheus_javaagent-0.12.0.jar=8080:/opt/jmx-exporter/zookeeper.yml"
volumes:
- /home/ansible/volumes/zoo1/data:/data
- /home/ansible/volumes/zoo1/datalog:/datalog
- /home/ansible/jmx-exporter:/opt/jmx-exporter
- /home/ansible/zookeeper_jaas.conf:/etc/kafka/zookeeper_jaas.conf
ZOO_SERVERS取自主机文件:
all:
(...)
children:
zookeeper:
hosts:
zoo1:
ID: "1"
ZOO_SERVERS: "server.1=0.0.0.0:2888:3888 server.2=10.3.1.173:2888:3888 server.3=10.3.1.175:2888:3888"
ansible_host: 10.3.1.171
zoo2:
ID: "2"
ZOO_SERVERS: "server.1=10.3.1.171:2888:3888 server.2=0.0.0.0:2888:3888 server.3=10.3.1.175:2888:3888"
ansible_host: 10.3.1.173
zoo3:
ID: "3"
ZOO_SERVERS: "server.1=10.3.1.171:2888:3888 server.2=10.3.1.173:2888:3888 server.3=0.0.0.0:2888:3888"
ansible_host: 10.3.1.175
所以当我回头看我上面的评论时,我注意到我 不是 实际上使用“confluentinc/cp-zookeeper” docker 图像,但是“动物园管理员”docker 图片。
一旦我从“zookeeper:3.4.9”更改为“confluentinc/cp-zookeeper:5.4.0”并将ZOO_PORT env-var的名称调整为ZOOKEEPER_CLIENT_PORT , 它以某种方式工作。
这并没有回答“为什么”,但也许这个解决方法可以帮助其他人。我暂时将此标记为已接受的答案,但请随时提供更多见解。
我已经设置了一个包含 3 个实例的 Zookeeper-ensemble(版本 3.4.9)。这在测试系统上就像一个魅力,但在实时系统上根本不会出现。错误信息如下:
2020-08-28 06:26:24,643 [myid:1] - WARN [WorkerSender[myid=1]:QuorumCnxManager@400] - Cannot open channel to 2 at election address /10.3.1.173:3888
java.net.NoRouteToHostException: Host is unreachable (Host unreachable)
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at org.apache.zookeeper.server.quorum.QuorumCnxManager.connectOne(QuorumCnxManager.java:381)
at org.apache.zookeeper.server.quorum.QuorumCnxManager.toSend(QuorumCnxManager.java:354)
at org.apache.zookeeper.server.quorum.FastLeaderElection$Messenger$WorkerSender.process(FastLeaderElection.java:452)
at org.apache.zookeeper.server.quorum.FastLeaderElection$Messenger$WorkerSender.run(FastLeaderElection.java:433)
at java.lang.Thread.run(Thread.java:745)
我已经在这里和其他地方搜索过,但唯一可以接受的问题解决方案是将每个节点的服务器地址设置为 0.0.0.0,这在此处不起作用。我的设置已完全 docker 化并应用了 ansible,因此它看起来可能与人们通常所做的有点不同。但是连接字符串例如对于 server.1 是这样的:
"server.1=0.0.0.0:2888:3888 server.2=10.3.1.173:2888:3888 server.3=10.3.1.175:2888:3888"
这也适用于 zookeepers 内部配置,如日志所示(同样适用于 server.1):
ZooKeeper JMX enabled by default
Using config: /conf/zoo.cfg
2020-08-28 06:26:23,549 [myid:] - INFO [main:QuorumPeerConfig@124] - Reading configuration from: /conf/zoo.cfg
2020-08-28 06:26:23,559 [myid:] - INFO [main:QuorumPeer$QuorumServer@149] - Resolved hostname: 10.3.1.175 to address: /10.3.1.175
2020-08-28 06:26:23,559 [myid:] - INFO [main:QuorumPeer$QuorumServer@149] - Resolved hostname: 10.3.1.173 to address: /10.3.1.173
2020-08-28 06:26:23,560 [myid:] - INFO [main:QuorumPeer$QuorumServer@149] - Resolved hostname: 0.0.0.0 to address: /0.0.0.0
2020-08-28 06:26:23,560 [myid:] - INFO [main:QuorumPeerConfig@352] - Defaulting to majority quorums
(...)
2020-08-28 06:26:23,570 [myid:1] - INFO [main:QuorumPeerMain@127] - Starting quorum peer
2020-08-28 06:26:23,577 [myid:1] - INFO [main:Login@294] - successfully logged in.
2020-08-28 06:26:23,579 [myid:1] - INFO [main:NIOServerCnxnFactory@89] - binding to port 0.0.0.0/0.0.0.0:2181
这适用于所有 3 个 zookeeper 实例,但其中 none 个可以与另一个实例通信。
附加信息:
- 除了服务器的 IP 地址外,配置与测试系统相同。 Ansible Docker 模块配置相同,JAAS-Config(带 DigestLoginModule)相同,所有 docker 容器内的环境变量也相同。
- live系统内的每台服务器都可以ping通其他服务器。我还可以从每个 Zookeeper 容器内 ping 这些服务器。此外,我可以从实时系统的任何其他容器内卷曲 JMX 端口上的每个 Zookeeper 容器。所以他们肯定可以通过网络连接。
请帮忙,谢谢:D
编辑:@Stefano 问我如何启动 docker 容器,所以我会尝试提供一些见解。如前所述,这是一个使用“docker_container”插件的任务中的 Ansible 设置,该插件在剧本中用于跨机器安装 3 个实例:
---
- name: Install Zookeeper
docker_container:
name: zookeeper
image: zookeeper:3.4.9
state: started
ports:
- "2181:2181" # Zookeeper Port
- "2888:2888"
- "3888:3888" # Election ports
- "9998:8080" # JMX metrics
env:
ZOO_MY_ID: "{{ ID }}" #this is 1 for server.1, etc.
ZOO_PORT: "2181"
ZOO_SERVERS: "{{ ZOO_SERVERS }}" #provided in host-vars
SERVER_JVMFLAGS: "-Djava.security.auth.login.config=/etc/kafka/zookeeper_jaas.conf -javaagent:/opt/jmx-exporter/jmx_prometheus_javaagent-0.12.0.jar=8080:/opt/jmx-exporter/zookeeper.yml"
volumes:
- /home/ansible/volumes/zoo1/data:/data
- /home/ansible/volumes/zoo1/datalog:/datalog
- /home/ansible/jmx-exporter:/opt/jmx-exporter
- /home/ansible/zookeeper_jaas.conf:/etc/kafka/zookeeper_jaas.conf
ZOO_SERVERS取自主机文件:
all:
(...)
children:
zookeeper:
hosts:
zoo1:
ID: "1"
ZOO_SERVERS: "server.1=0.0.0.0:2888:3888 server.2=10.3.1.173:2888:3888 server.3=10.3.1.175:2888:3888"
ansible_host: 10.3.1.171
zoo2:
ID: "2"
ZOO_SERVERS: "server.1=10.3.1.171:2888:3888 server.2=0.0.0.0:2888:3888 server.3=10.3.1.175:2888:3888"
ansible_host: 10.3.1.173
zoo3:
ID: "3"
ZOO_SERVERS: "server.1=10.3.1.171:2888:3888 server.2=10.3.1.173:2888:3888 server.3=0.0.0.0:2888:3888"
ansible_host: 10.3.1.175
所以当我回头看我上面的评论时,我注意到我 不是 实际上使用“confluentinc/cp-zookeeper” docker 图像,但是“动物园管理员”docker 图片。
一旦我从“zookeeper:3.4.9”更改为“confluentinc/cp-zookeeper:5.4.0”并将ZOO_PORT env-var的名称调整为ZOOKEEPER_CLIENT_PORT , 它以某种方式工作。
这并没有回答“为什么”,但也许这个解决方法可以帮助其他人。我暂时将此标记为已接受的答案,但请随时提供更多见解。