Docker环境下DSE节点无法全部连接的问题排查请求
我正尝试用Docker部署包含5个节点的Cassandra集群(使用dse-server和dse-studio)。Docker容器运行正常,能访问Cassandra并执行CRUD操作,但无法连接所有节点。怀疑是Docker Compose网络配置问题或其他原因。
当我通过192.168.3.19:9042连接时,能正常执行CRUD,但只能连接第一个节点。操作能完成,但其他节点的IP会报错:
"Connection[/172.30.0.4:9042-1, inFlight=0, closed=false] Error connecting to /172.30.0.4:9042 (connection timed out: /172.30.0.4:9042)"
我尝试把所有节点IP作为Contact Points创建连接器,结果报错:
Exception in thread "main" java.lang.IllegalArgumentException: Failed to add contact point: "127.0.0.1";"172.30.0.2";"172.30.0.3";"172.30.0.4";"172.30.0.5";"172.30.0.6" at com.datastax.driver.core.Cluster$Builder.addContactPoint(Cluster.java:943) at cassandra.java.client.CassandraConnector.connectNodes(CassandraConnector.java:30) at cassandra.java.client.Main.main(Main.java:13) Caused by: java.net.UnknownHostException: Host desconocido ("127.0.0.1";"172.30.0.2";"172.30.0.3";"172.30.0.4";"172.30.0.5";"172.30.0.6") at java.base/java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method) at java.base/java.net.InetAddress$PlatformNameService.lookupAllHostAddr(InetAddress.java:933) at java.base/java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1529) at java.base/java.net.InetAddress$NameServiceAddresses.get(InetAddress.java:852) at java.base/java.net.InetAddress.getAllByName0(InetAddress.java:1519) at java.base/java.net.InetAddress.getAllByName(InetAddress.java:1377) at java.base/java.net.InetAddress.getAllByName(InetAddress.java:1305) at com.datastax.driver.core.Cluster$Builder.addContactPoint(Cluster.java:939)
请问需要修改哪些配置?
1. 修复Contact Points添加方式
你报错的直接原因是调用addContactPoint时传入了分号拼接的多个IP,但这个方法一次只能传一个IP。正确做法是循环调用逐个添加,或用addContactPoints方法传入IP集合:
// 方式一:逐个添加节点IP Cluster.Builder builder = Cluster.builder(); builder.addContactPoint("192.168.3.19"); builder.addContactPoint("192.168.3.19").withPort(9043); // ... 依次添加其他节点的宿主机IP和映射端口 // 方式二:用集合批量添加 List<String> contactPoints = Arrays.asList("192.168.3.19:9042", "192.168.3.19:9043", ...); Cluster.Builder builder = Cluster.builder().addContactPoints(contactPoints);
注意:不要混用容器内网IP(172.30.x.x)和宿主机IP(192.168.3.19),统一用宿主机IP+映射端口。
2. 调整Docker Compose网络配置
无法连接其他节点的核心原因是:Cassandra会把容器内网IP返回给客户端,但这个IP在宿主机/外部无法访问。需要修改每个节点的广播地址和端口映射:
修改docker-compose.yml中dse-server节点配置:
services: dse-node1: image: datastax/dse-server:6.8.22 ports: - "9042:9042" # 宿主机唯一端口映射 environment: - DS_LICENSE=accept - CASSANDRA_LISTEN_ADDRESS=0.0.0.0 # 允许监听所有地址 - CASSANDRA_BROADCAST_ADDRESS=192.168.3.19 # 广播宿主机IP给客户端 - CASSANDRA_SEEDS=dse-node1,dse-node2,dse-node3,dse-node4,dse-node5 # 集群种子节点 # 其他配置... dse-node2: image: datastax/dse-server:6.8.22 ports: - "9043:9042" # 不同节点用不同宿主机端口 environment: - DS_LICENSE=accept - CASSANDRA_LISTEN_ADDRESS=0.0.0.0 - CASSANDRA_BROADCAST_ADDRESS=192.168.3.19 - CASSANDRA_SEEDS=dse-node1,dse-node2,dse-node3,dse-node4,dse-node5 # 其他配置...
- 每个节点的宿主机映射端口必须唯一(比如9042、9043、9044等)
CASSANDRA_BROADCAST_ADDRESS必须设置为宿主机可访问的IP,确保客户端收到的是能直接连接的地址。
3. 验证集群状态
进入任意容器执行命令,确认所有节点状态为UN(Up/Normal):
docker exec -it dse-node1 nodetool status
内容的提问来源于stack exchange,提问作者John Martin Curtin

