如何解决Kubernetes环境下Spring Boot与MySQL的通信连接失败问题?
核心错误分析
Caused by: com.mysql.cj.exceptions.CJCommunicationsException: Communications link failure.
该错误本质为网络连通性异常或MySQL服务未完全就绪,结合你提供的YAML配置,可从以下维度逐一排查:
一、先确认MySQL服务状态
检查MySQL Pod运行状态
kubectl get pods -n lost_island确保MySQL Pod处于
Running状态,若出现CrashLoopBackOff等异常,查看容器日志定位问题:kubectl logs <mysql-pod-name> -n lost_island重点排查初始化失败、存储目录权限不足等问题。
验证MySQL服务的可访问性
在同一命名空间启动临时测试Pod,直接连接MySQL服务:kubectl run -it --rm --image=mysql:latest mysql-test -n lost_island -- mysql -h mysql-service -u root -p1234若连接失败,说明服务发现或集群网络存在问题;若能成功连接,说明MySQL服务本身正常,问题出在Spring Boot配置或启动时机。
二、检查YAML配置中的关键问题
1. MySQL Deployment的冗余环境变量
你的MySQL配置同时设置了MYSQL_ROOT_PASSWORD和MYSQL_PASSWORD,但未定义MYSQL_USER,MYSQL_PASSWORD变量实际无效。由于Spring Boot使用root用户连接,此配置暂时不影响,但建议清理冗余参数。
2. Spring Boot数据库URL的转义错误
你配置的URL中使用了HTML转义字符&,在K8s环境变量中需直接使用&,转义字符会被当作URL的一部分导致解析失败:
错误配置:
jdbc:mysql://mysql-service.lost_island.svc.cluster.local:3306/lost_island?serverTimezone=UTC&sessionVariables=sql_mode='NO_ENGINE_SUBSTITUTION'&jdbcCompliantTruncation=false&useSSL=false
修正后配置:
jdbc:mysql://mysql-service.lost_island.svc.cluster.local:3306/lost_island?serverTimezone=UTC&sessionVariables=sql_mode='NO_ENGINE_SUBSTITUTION'&jdbcCompliantTruncation=false&useSSL=false
3. 启动顺序问题
Spring Boot可能在MySQL完全就绪前发起连接,导致失败。可给Spring Boot Deployment添加启动探针,等待MySQL服务就绪:
spec: containers: - name: springboot-app image: skull/lost_island_backend # 保留原有env、ports配置 readinessProbe: exec: command: ["mysql", "-h", "mysql-service", "-u", "root", "-p1234", "-e", "SELECT 1"] initialDelaySeconds: 30 periodSeconds: 10 livenessProbe: exec: command: ["mysql", "-h", "mysql-service", "-u", "root", "-p1234", "-e", "SELECT 1"] initialDelaySeconds: 60 periodSeconds: 20
4. PersistentVolume权限问题
MySQL使用hostPath /mnt/data作为存储目录,需确保节点上该目录权限为MySQL用户(UID 999)可读写:
# 在K8s节点执行 sudo chown -R 999:999 /mnt/data
权限错误会导致MySQL容器无法写入数据,进而启动失败。
三、其他排查点
- 确认Spring Boot镜像中的MySQL驱动版本与MySQL 8.x(你使用的
mysql:latest)兼容,8.x驱动需指定serverTimezone参数,你已配置但需确保驱动版本匹配。 - 检查Kubernetes集群网络插件(如Calico、Flannel)运行正常,同一命名空间内Pod与Service可正常通信。
内容的提问来源于stack exchange,提问作者sebastian kull

