K8s环境下Java应用仍连接Cassandra旧Pod IP问题咨询
解决Kubernetes中Java客户端通过FQDN连接Cassandra动态IP的问题
核心原因
Cassandra Java 4.18版本驱动在初始连接服务FQDN后,会从Cassandra节点获取集群拓扑信息,但默认情况下Cassandra Pod广播的是自身Pod IP。当Pod重启IP变更后,驱动仍缓存旧的Pod IP,导致连接失败。
解决方案
1. 修改Cassandra配置,让节点广播服务FQDN
编辑Cassandra的cassandra.yaml配置文件,调整以下参数:
# 替换为你的Cassandra服务实际FQDN,格式为「服务名.命名空间.svc.cluster.local」 broadcast_address: cassandra-service.default.svc.cluster.local broadcast_rpc_address: cassandra-service.default.svc.cluster.local # 监听地址保持Pod内部可访问的配置 listen_address: 0.0.0.0 rpc_address: 0.0.0.0
这样驱动从Cassandra节点获取到的拓扑地址就是服务FQDN,而非易变的Pod IP。
2. 配置Java驱动禁用自动节点发现(固定节点场景可选)
如果不需要驱动自动感知集群节点,可强制驱动仅通过服务FQDN连接,关闭拓扑感知:
DriverConfigLoader loader = DriverConfigLoader.programmaticBuilder() .withString(DefaultDriverOption.CONTACT_POINTS, "cassandra-service.default.svc.cluster.local") .withBoolean(DefaultDriverOption.LOAD_BALANCING_POLICY_DC_AWARE_LOCAL_DC, false) .withClass(DefaultDriverOption.LOAD_BALANCING_POLICY_CLASS, RoundRobinPolicy.class) .build(); CqlSession session = CqlSession.builder() .withConfigLoader(loader) .build();
此方式下所有请求都会通过Kubernetes Service转发,无需关心Pod IP变化。
3. 开启驱动的DNS定期刷新
配置驱动定期重新解析服务FQDN,避免缓存旧IP:
DriverConfigLoader loader = DriverConfigLoader.programmaticBuilder() .withDuration(DefaultDriverOption.CONTACT_POINT_RESOLUTION_REFRESH_INTERVAL, Duration.ofMinutes(5)) .build();
可根据实际场景调整刷新间隔,确保能及时获取Pod的最新IP。
4. 校验Kubernetes Service配置
确保Cassandra Service的selector正确匹配Pod标签,若使用Headless Service,需让Cassandra节点广播Pod自身FQDN:
apiVersion: v1 kind: Service metadata: name: cassandra-service namespace: default spec: selector: app: cassandra ports: - port: 9042 targetPort: 9042 clusterIP: None # Headless Service场景使用
Headless Service下Pod的FQDN格式为「Pod名.服务名.命名空间.svc.cluster.local」,需同步修改Cassandra的
broadcast_address为该格式。
内容的提问来源于stack exchange,提问作者Avinash Shetty
相关产品推荐
相关产品推荐

