You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker容器外访问ScyllaDB集群遇NoHostAvailable错误求助

问题描述

本地Docker容器运行ScyllaDB集群,容器外的FastAPI应用访问集群时触发错误:cassandra.cluster.NoHostAvailable: ('Unable to connect to any servers')

集群状态信息

Datacenter: datacenter1
=======================
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
--  Address     Load       Tokens       Owns    Host ID                               Rack
UN  172.17.0.2  776 KB     256          ?       ad698c75-a465-4deb-a92c-0b667e82a84f  rack1

Note: Non-system keyspaces don't have the same replication settings, effective ownership information is meaningless
Cluster Information:
    Name: Test Cluster
    Snitch: org.apache.cassandra.locator.SimpleSnitch
    DynamicEndPointSnitch: disabled
    Partitioner: org.apache.cassandra.dht.Murmur3Partitioner
    Schema versions:
        443048b2-c1fe-395e-accd-5ae9b6828464: [172.17.0.2]

可正常访问的场景

使用cqlsh通过9042端口连接集群无问题:

Connected to  at 172.17.0.2:9042.
[cqlsh 5.0.1 | Cassandra 3.0.8 | CQL spec 3.3.1 | Native protocol v4]

报错代码及信息

容器外FastAPI应用执行以下代码时报错:

from cassandra.cluster import Cluster

cluster = Cluster(['172.17.0.2'])

session = cluster.connect('Test Cluster')

错误信息:

raise NoHostAvailable("Unable to connect to any servers", errors)
cassandra.cluster.NoHostAvailable: ('Unable to connect to any servers', {'172.17.0.2:9042': OSError(51, "Tried connecting to [('172.17.0.2', 9042)]. Last error: Network is unreachable")})
解决方案

核心原因

172.17.0.2是Docker容器内部的桥接网络IP,容器外的主机无法直接访问这个内部IP,这是导致「网络不可达」错误的根本原因。你用cqlsh能正常连接,大概率是因为cqlsh运行在容器内部,或者你的主机网络与Docker桥接网络直接打通,但FastAPI所在环境不在这个网络范围内。

具体解决步骤

  • 步骤1:重新启动ScyllaDB容器,配置端口映射与监听地址
    启动容器时,必须将容器的9042端口映射到主机端口,同时让ScyllaDB监听所有地址(0.0.0.0),确保外部能访问。示例启动命令:

    docker run -d \
      --name scylla-node1 \
      -p 9042:9042 \
      -e SCYLLA_LISTEN_ADDRESS=0.0.0.0 \
      -e SCYLLA_RPC_ADDRESS=0.0.0.0 \
      scylladb/scylla
    

    其中-p 9042:9042实现端口映射,SCYLLA_LISTEN_ADDRESS和SCYLLA_RPC_ADDRESS设置为0.0.0.0,允许ScyllaDB接受外部连接请求。

  • 步骤2:修正FastAPI的连接代码
    将连接目标IP改为主机的IP(如果FastAPI在主机本地运行,用localhost即可),端口使用映射后的9042。另外注意:cluster.connect()的参数是keyspace名称,不是集群名称「Test Cluster」,这是常见误区。修正后的代码:

    from cassandra.cluster import Cluster
    
    # FastAPI在主机本地运行时用localhost
    cluster = Cluster(['localhost'], port=9042)
    # FastAPI在局域网其他机器时,替换为主机的局域网IP,比如192.168.1.100
    # cluster = Cluster(['192.168.1.100'], port=9042)
    
    # 替换为实际的keyspace名称,而非集群名称
    session = cluster.connect('your_keyspace_name')
    
  • 步骤3:验证网络连通性
    在FastAPI所在环境执行以下命令,确认端口连通:

    # 用telnet验证
    telnet localhost 9042
    # 或用nc验证
    nc -zv localhost 9042
    

    如果不通,检查Docker端口映射是否生效,以及主机防火墙是否放行9042端口。

内容的提问来源于stack exchange,提问作者john meiners

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 03:01:06