无法从Scala连接Kubernetes中运行的ScyllaDB集群求助
我在Kubernetes中部署了ScyllaDB集群,尝试用Scala的Phantom库连接时遇到连接失败的问题,错误提示All host(s) tried for query failed (tried: /10.98.139.252 (com.datastax.driver.core.exceptions.TransportException: [/10.98.139.252] Cannot connect)),替换Pod IP、Service IP、Service名称都无效。
我的部署与代码情况
Kubernetes部署步骤
按照官方文档执行以下命令部署集群:
$ minikube start --cpus=6 $ eval $(minikube docker-env) $ git clone https://github.com/scylladb/scylla-operator.git $ cd scylla-operator $ kubectl apply -f examples/common/cert-manager.yaml $ kubectl wait --for condition=established crd/certificates.cert-manager.io crd/issuers.cert-manager.io $ kubectl -n cert-manager rollout status deployment.apps/cert-manager-webhook $ kubectl apply -f deploy/operator.yaml $ kubectl wait --for condition=established crd/scyllaclusters.scylla.scylladb.com $ kubectl -n scylla-operator rollout status deployment.apps/scylla-operator $ kubectl create -f examples/generic/cluster.yaml
集群状态验证结果:
$ kubectl -n scylla get pods NAME READY STATUS RESTARTS AGE simple-cluster-us-east-1-us-east-1a-0 2/2 Running 0 90m simple-cluster-us-east-1-us-east-1a-1 2/2 Running 0 80m simple-cluster-us-east-1-us-east-1a-2 0/2 Pending 0 77m $ kubectl -n scylla get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE simple-cluster-client ClusterIP 10.98.139.252 <none> 7000/TCP,7001/TCP,9042/TCP,9142/TCP,19042/TCP,19142/TCP,7199/TCP,10001/TCP,9180/TCP,5090/TCP,9100/TCP,9160/TCP 90m simple-cluster-us-east-1-us-east-1a-0 ClusterIP 10.98.37.120 <none> 7000/TCP,7001/TCP,9042/TCP,9142/TCP,19042/TCP,19142/TCP,7199/TCP,10001/TCP,9180/TCP,5090/TCP,9100/TCP,9160/TCP 90m simple-cluster-us-east-1-us-east-1a-1 ClusterIP 10.105.171.34 <none> 7000/TCP,7001/TCP,9042/TCP,9142/TCP,19042/TCP,19142/TCP,7199/TCP,10001/TCP,9180/TCP,5090/TCP,9100/TCP,9160/TCP 90m simple-cluster-us-east-1-us-east-1a-2 ClusterIP 10.110.32.166 <none> 7000/TCP,7001/TCP,9042/TCP,9142/TCP,19042/TCP,19142/TCP,7199/TCP,10001/TCP,9180/TCP,5090/TCP,9100/TCP,9160/TCP 90m $ kubectl exec -n scylla -it simple-cluster-us-east-1-us-east-1a-0 -- nodetool status Defaulted container "scylla" out of: scylla, scylla-manager-agent, sidecar-injection (init) Datacenter: us-east-1 ===================== Status=Up/Down |/ State=Normal/Leaving/Joining/Moving -- Address Load Tokens Owns Host ID Rack UN 10.98.37.120 108.99 KB 256 ? a1d76285-964f-48b1-b87d-2e2fafa96877 us-east-1a UN 10.105.171.34 201.48 KB 256 ? c2204fec-b713-4fd5-ba47-d8b72505ac12 us-east-1a Note: Non-system keyspaces don't have the same replication settings, effective ownership information is meaningless
Scala代码连接尝试
使用Phantom库编写的连接代码:
schema.scala
abstract class MyDataSchema extends Table[MyDataSchema, MyData] { override def tableName: String = "mydata" object myColumn extends OptionalStringColumn with PartitionKey { override def name: String = "myColumn" } }
connection.scala
class ScyllaDBConnection extends ScyllaDBConnectionTrait { override def connectionProvider: CassandraConnection = { val applicationConf: Config = ConfigFactory.load("application.conf") val keyspace: String = applicationConf.getString("keyspace.keyspaceName") val connection: CassandraConnection = ContactPoints(List("10.98.139.252")) //10.98.139.252 is IP of Service .keySpace(keyspace) connection } }
database.scala
class MyDB(override val connector: CassandraConnection) extends Database[MyDB](connector) { object MyData extends MyDataSchema with Connector }
运行后出现错误:
All host(s) tried for query failed (tried: /10.98.139.252 (com.datastax.driver.core.exceptions.TransportException: [/10.98.139.252] Cannot connect))
解决方法
1. 本地运行Scala代码的网络配置
如果Scala代码在minikube集群外部(本地机器)运行,ClusterIP类型的Service无法直接访问,需要先做端口转发:
kubectl port-forward -n scylla svc/simple-cluster-client 9042:9042
然后修改Scala代码中的连接地址为localhost:
ContactPoints(List("localhost")) .keySpace(keyspace)
2. 同集群内部署Scala服务的网络配置
如果Scala服务部署在同一个K8s集群中,直接使用Service的DNS名称即可,无需IP:
ContactPoints(List("simple-cluster-client.scylla.svc.cluster.local")) .keySpace(keyspace)
DNS格式为[service-name].[namespace].svc.cluster.local,若Scala服务与ScyllaDB不在同一命名空间,必须使用完整DNS地址。
3. 检查ScyllaDB端口状态
确认ScyllaDB的CQL端口(9042)是否正常监听,可进入Pod验证:
kubectl exec -n scylla simple-cluster-us-east-1-us-east-1a-0 -- nc -zv localhost 9042
另外,第三个Pod处于Pending状态,可能是minikube资源不足导致,可调整minikube资源配置或删除该Pending Pod,避免影响集群状态。
4. 优化Phantom库连接配置
Phantom基于Datastax Java Driver,可添加超时配置提升连接稳定性:
val connection: CassandraConnection = ContactPoints(List("localhost")) .withClusterBuilder(_.withPort(9042) .withSocketOptions(SocketOptions.builder().setConnectTimeoutMillis(10000).build())) .keySpace(keyspace)
内容的提问来源于stack exchange,提问作者Zaryab Ali

