【问题标题】:K8s Spring Application cannot connect to Mysql DBK8s Spring Application无法连接到Mysql DB
【发布时间】:2021-09-16 22:37:30
【问题描述】:

我想尝试在 kubernetes 上部署我的 Spring Boot 应用程序。我使用 microk8s(启用了 dns、storage、ingress)设置了一个测试环境,该环境由一个运行应用程序本身的 pod 和一个带有 MySQL 数据库的 pod 组成。每个 pod 都有自己的服务,并在相同的默认命名空间上运行。 yaml 文件如下所示:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
        - name: test-app
          image: myImage
          ports:
            - containerPort: 8080
          imagePullPolicy: Always
          env:
            - name: SPRING_APPLICATION_JSON
              valueFrom:
                configMapKeyRef:
                  name: spring-config
                  key: app-config.json

应用服务:

apiVersion: v1
kind: Service
metadata:
  name: myapp-service
spec:
  selector:
    app: myapp
  ports:
    - port: 8080
      targetPort: 8080

Mysql 部署:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql-server
  labels:
    # app: mysql
    app: mysql
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      volumes:
        - name: mysql-persistent-volume-storage
          persistentVolumeClaim:
            claimName: mysql-pvc-claim
      containers:
        - name: mysql
          image: mysql
          volumeMounts:
            - name: mysql-persistent-volume-storage
              mountPath: /var/lib/mysql
              subPath: mysql-server
          env:
            - name: MYSQL_ROOT_PASSWORD
              value: pass_root
            - name: MYSQL_USER
              value: user
            - name: MYSQL_PASSWORD
              value: pass
            - name: MYSQL_DATABASE
              value: test
          ports:
            - containerPort: 3306

Mysql 服务:

apiVersion: v1
kind: Service
metadata:
  name: db-service
spec:
  selector:
    app: mysql
  ports:
    - port: 3306
      targetPort: 3306

由于某种原因,我的应用程序无法使用数据库。它抛出这个错误:

com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure

The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
    at com.mysql.cj.jdbc.exceptions.SQLError.createCommunicationsException(SQLError.java:174) ~[mysql-connector-java-8.0.25.jar!/:8.0.25]
    at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:64) ~[mysql-connector-java-8.0.25.jar!/:8.0.25]
    at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:833) ~[mysql-connector-java-8.0.25.jar!/:8.0.25]
    at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:453) ~[mysql-connector-java-8.0.25.jar!/:8.0.25]
    at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:246) ~[mysql-connector-java-8.0.25.jar!/:8.0.25]
    at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:198) ~[mysql-connector-java-8.0.25.jar!/:8.0.25]
    at com.zaxxer.hikari.util.DriverDataSource.getConnection(DriverDataSource.java:121) ~[HikariCP-4.0.3.jar!/:na]
    at com.zaxxer.hikari.pool.PoolBase.newConnection(PoolBase.java:364) ~[HikariCP-4.0.3.jar!/:na]
    at com.zaxxer.hikari.pool.PoolBase.newPoolEntry(PoolBase.java:206) ~[HikariCP-4.0.3.jar!/:na]
    at com.zaxxer.hikari.pool.HikariPool.createPoolEntry(HikariPool.java:476) ~[HikariCP-4.0.3.jar!/:na]
    at com.zaxxer.hikari.pool.HikariPool.checkFailFast(HikariPool.java:561) ~[HikariCP-4.0.3.jar!/:na]
    at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:115) ~[HikariCP-4.0.3.jar!/:na]
    at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) ~[HikariCP-4.0.3.jar!/:na]
.......

application.yml:

db:
  datasource:
    url: jdbc:mysql://ip/test
    user: user
    password: pass
---
spring:
  datasource:
    url: ${db.datasource.url}
    username: ${db.datasource.user}
    password: ${db.datasource.password}
    driver-class-name: com.mysql.cj.jdbc.Driver
  jpa:
    database-platform: org.hibernate.dialect.MySQLDialect
  mvc:
    view:
      suffix: .html
  thymeleaf:
    cache: false
allowPublicKeyRetrieval: true
hibernate:
  show_sql: true
logging:
  level:
    org:
      hibernate:
        SQL: debug

我尝试从运行 mysql 的命名空间上的另一个 pod 访问该服务,因为它预先安装了 mysql-client,并且从主机访问。两者都可以访问数据库。我还在运行应用程序的 pod 上尝试 ping。它发现服务没有任何问题。

然后我尝试使用 NodePort 而不是 ClusterIP。没有任何改变。

我确保凭据正确。

最后,我尝试在 application.yml 中删除和添加端口。

我完全被卡住了,我不知道出了什么问题。任何帮助将不胜感激。

【问题讨论】:

    标签: java mysql spring-boot kubernetes microk8s


    【解决方案1】:

    我在您的配置中发现了两个问题:您的 mysql 部署中的用户名/密码与您的 application.yaml 中的值不匹配。

    另一个是你使用了spring boot默认不使用的属性,我假设你没有特殊的逻辑来处理:“spring.data.url”应该是“spring.datasource.url”。

    注意它应该是 "spring.datasource.username" ,而不是 "user"。

    参考 YAML 中的“db”部分:一般来说,我不建议为数据库凭据设置单独的部分并使用变量来引用它。

    【讨论】:

    • 对不起,我的错。我相信我已经解决了。但是,问题仍然存在。
    • 您是否修复了您的属性,因为它们似乎未从您的编辑中删除。
    • 我将“用户”更改为“用户名”,并更改了值,使其与部署相匹配。如果您在 db 下引用“用户”,我相信这没有什么区别。我尝试在我的机器上进行更改,但并没有太大变化。
    • 我的意思是你仍然使用'spring.data'而不是'spring.datasource'和'.user'而不是'.username'
    • 看起来更好,现在使用 'db-service' 作为数据库主机名而不是 'mysql',因为它是您的服务的名称。
    猜你喜欢
    • 2021-12-11
    • 2023-01-20
    • 1970-01-01
    • 2018-02-10
    • 2019-06-08
    • 2016-06-05
    • 2019-08-02
    • 2015-11-20
    • 2021-10-27
    相关资源
    最近更新 更多