K8s Spring 应用程序无法连接到 Mysql 数据库

K8s Spring Application cannot connect to Mysql DB

我想尝试在 kubernetes 上部署我的 spring 启动应用程序。我用 microk8s(启用了 dns、存储、入口)设置了一个测试环境,它由一个 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-客户端,并且从主机访问。两者都可以访问数据库。我还在 pod 运行 应用程序上尝试 ping。发现服务没有问题

然后我尝试使用 NodePort 而不是 ClusterIP。什么都没有改变。

我确定凭据是正确的。

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

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

我发现您的配置存在两个问题:mysql 部署中的 username/password 与 application.yaml 中的值不匹配。

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

请注意,它应该是“spring.datasource.username”,而不是“用户”。

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