Minikube中Spring Boot应用连接外部数据库失败求助
问题描述
Spring Boot构建的应用部署在Minikube(v1.26.0,使用hyperkit驱动)中,无法连接通过VPN访问的外部PostgreSQL数据库(IP:172.16.0.180)。本地终端能正常ping通该数据库IP,但Minikube内的Pod执行ping命令时100%丢包,应用连接数据库时出现超时错误,错误堆栈如下:
22:40:56.393 [main] INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting... 22:41:07.480 [main] ERROR com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Exception during pool initialization. org.postgresql.util.PSQLException: The connection attempt failed. at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:331) at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:49) at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:223) at org.postgresql.Driver.makeConnection(Driver.java:402) at org.postgresql.Driver.connect(Driver.java:261) at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:138) ... ... Caused by: java.net.SocketTimeoutException: connect timed out at java.base/java.net.PlainSocketImpl.socketConnect(Native Method) at java.base/java.net.AbstractPlainSocketImpl.doConnect(Unknown Source) at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source) 22:41:07.482 [main] WARN o.h.e.j.e.i.JdbcEnvironmentInitiator - HHH000342: Could not obtain connection to query metadata org.postgresql.util.PSQLException: The connection attempt failed. at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:331) at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:49) at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:223) at org.postgresql.Driver.makeConnection(Driver.java:402)
环境配置信息
- Minikube启动命令:
minikube start --driver=hyperkit
- Deployment配置文件:
apiVersion: v1 kind: Service metadata: name: web-application spec: selector: role: webapp ports: - protocol: TCP port: 8080 targetPort: 80 --- apiVersion: apps/v1 kind: Deployment metadata: name: webapp-gastronomia spec: selector: matchLabels: role: webapp replicas: 1 template: metadata: labels: role: webapp env: production spec: containers: - name: app-gastronomia image: localhost:5000/app-gastronomia:1.0 imagePullPolicy: IfNotPresent ports: - containerPort: 80
- Dockerfile内容:
FROM openjdk:11.0.7-jre-slim COPY build/libs/register-0.0.1-SNAPSHOT.jar app.jar EXPOSE 8001 ENTRYPOINT ["java","-jar","app.jar"]
网络测试结果:
- Ubuntu Pod内ping数据库IP:
root@ubuntu:/# ping -c 3 172.16.0.180 PING 172.16.0.180 (172.16.0.180) 56(84) bytes of data. --- 172.16.0.180 ping statistics --- 3 packets transmitted, 0 received, 100% packet loss, time 2072ms- 本地终端ping数据库IP:
ping -c 3 172.16.0.180 PING 172.16.0.180 (172.16.0.180): 56 data bytes 64 bytes from 172.16.0.180: icmp_seq=0 ttl=63 time=78.136 ms 64 bytes from 172.16.0.180: icmp_seq=1 ttl=63 time=74.404 ms 64 bytes from 172.16.0.180: icmp_seq=2 ttl=63 time=74.904 ms --- 172.16.0.180 ping statistics --- 3 packets transmitted, 3 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 74.404/75.815/78.136/1.654 ms已尝试的外部Service和Endpoint配置:
apiVersion: v1 kind: Service metadata: name: database spec: clusterIP: None ports: - port: 5432 targetPort: 5432 protocol: TCP --- kind: Endpoints apiVersion: v1 metadata: name: database subsets: - addresses: - ip: 172.16.0.180 ports: - port: 5432
Pod内ping该Service仍丢包:
root@ubuntu:/# ping -c 3 database PING database.default.svc.cluster.local (172.16.0.180) 56(84) bytes of data. --- database.default.svc.cluster.local ping statistics --- 3 packets transmitted, 0 received, 100% packet loss, time 2032ms
补充:在家办公,通过VPN访问该数据库。
解决方案
使用主机网络模式启动Minikube
让Minikube虚拟机直接使用宿主机的网络栈,共享宿主机的VPN连接,这样Pod就能直接访问数据库IP:minikube stop minikube delete minikube start --driver=hyperkit --network=host注意:此模式下Pod的端口会直接占用宿主机端口,需避免端口冲突。
添加路由规则打通Minikube与VPN网络
- 获取Minikube集群的网关地址:
minikube ssh "ip route show" | grep default | awk '{print $3}' - 在宿主机添加路由,将数据库所在IP段指向Minikube网关:
sudo route add -net 172.16.0.0/24 $(minikube ip) - 检查VPN客户端设置,确保开启“允许局域网设备访问”或类似选项,允许Minikube虚拟机的流量通过VPN。
- 获取Minikube集群的网关地址:
宿主机端口转发
在宿主机上配置端口转发,将数据库端口映射到本地,然后让Pod连接Minikube IP对应的端口:# 宿主机将本地5432端口转发到数据库IP的5432端口 sudo socat TCP-LISTEN:5432,fork TCP:172.16.0.180:5432之后在应用的数据库配置中使用
$(minikube ip):5432作为连接地址。检查防火墙与网络策略
- 宿主机防火墙放行数据库端口的出站流量:
sudo ufw allow out to 172.16.0.180 port 5432 - 检查Minikube内是否存在NetworkPolicy限制Pod出站流量,若有则添加允许访问172.16.0.180:5432的规则。
- 宿主机防火墙放行数据库端口的出站流量:
内容的提问来源于stack exchange,提问作者hector alvarez perez
相关产品推荐
相关产品推荐

