【问题标题】:Database access problems from Kubernetes pod来自 Kubernetes pod 的数据库访问问题
【发布时间】:2021-12-13 09:18:53
【问题描述】:

我正在尝试将我的第二个项目 (prm) 放到云端。 两个项目(pyp 和 prm)都使用相同的凭据访问相同的数据库。 第一个项目成功,第二个项目拒绝用户 root 访问。

摘自我的定义:

apiVersion: v1
kind: Secret
metadata:
name: pyp-secret
data:
mysql_password: "<password>"

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

apiVersion: apps/v1
kind: Deployment
metadata:
  name: pyp-db
spec:
  replicas: 1
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: pyp
      service: mysql
  template:
    metadata:
      labels:
        app: pyp
        service: mysql
    spec:
      containers:
      - image: mysql:8
        name: pyp-db
        env:
        - name: MYSQL_ROOT_PASSWORD
          valueFrom:
            secretKeyRef:
              name: pyp-secret
              key: mysql_password
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: prm
spec:
  replicas: 1
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: prm
      service: cron
  template:
    metadata:
      labels:
        app: prm
        service: cron
    spec:
      containers:
      - image: prm-image-name
        imagePullPolicy: Always
        name: prm
        env:
        - name: MYSQL_HOST
          value: pyp-db
        - name: MYSQL_USER
          value: root
        - name: MYSQL_PASSWORD
          valueFrom:
            secretKeyRef:
              name: pyp-secret
              key: mysql_password

这是日志的摘录,您可以在其中看到连接数据库的 url,以及我得到的错误:

这是来自我的 java 应用程序:

static Connection  init(String host,String user, String password){
        Connection con = null;
        try {
            if (con == null) {
                Class.forName("com.mysql.cj.jdbc.Driver").newInstance();
                    String url = "jdbc:mysql://" + host + ":3306/PP_Master?user=" + user + "&password=" + password;
                logger.trace("DB url:" + url);
                con = DriverManager.getConnection(url);
            }

        } catch (Exception ex) {
            logger.error("init: "  ,  ex);
        }

        return con;
    }

我的云托管在 Minikube 上,数据库是 Mysql 8.0.27。当我提供相同的凭据时,可以从我的本地主机访问它。我的另一个项目(pyp)在 Tomcat 中运行,并使用 context.xml 中定义的连接池中的凭据进行连接。他们使用相同的驱动程序来连接数据库。该项目可以正常访问数据库。

这是在数据库中定义的用户:

我还通过 url.length() 计算了 url 中的字符数。这给出了与实际大小匹配的 72 个字符。所以密码中没有多余的不可见字符。

关于成功访问数据库的项目(pyp)。几天前,我从针对数据库的第一条语句中得到了一个 SqlSyntaxError,即使它只是“USE PP_Master”,并且它之前已经工作过。日志上没有错误。 我不得不删除 Minikube 容器,然后启动一个新容器。 这让我可以从 pyp-project 访问数据库。 我想知道一个使用 DataConnectionPool 的项目是否可以保留对数据库的访问权限,所以没有其他项目可以访问它? 我现在尝试在 pyp-project 中从连接池更改为只有一个连接。但这并没有解决 prm-project 的问题。我还尝试简单地删除部署和 pyp-pod,但这对 prm-project 没有帮助。所以这种假设似乎是错误的。 我查看了 pyp-db 日志。此 pod 包含数据库。 我不知道其中一些信息是否会对我的问题产生影响? 我也尝试过再次删除 minikube。这次我只部署了 pyp-db 和 prm pod,以避免可能与 pyp pod 发生冲突。但无济于事。连接到 prm pod 的错误消息仍然存在。 所以,prm和pyp-db之间一定有问题,与pyp-pod无关。所以我已经证明这不是因为与pyp-pod冲突。

我真的希望有人能够帮助我。我被这个问题困扰了好几天。如果有更多信息可以提供帮助,请询问。

【问题讨论】:

  • kubernetes 中的 secret 默认是 base64 编码的。你能尝试用 new String(Base64.getDecoder().decode(password)) 解码它
  • 我把它放到了我的初始化方法中,并跟踪到了日志。输入参数得到的密码被解码,再次解码的时候,出现了很多奇怪的符号。
  • 我也尝试了编码和解码,但结果相同。我已经使用 password.length 计算了密码中的字母数。那给了我 18,这是密码中正确的字母数。我什至尝试在 url 中的密码周围加上撇号,但我想撇号被视为密码的一部分。当然,这是不合逻辑的,因为 url 战争一开始看起来就对了。
  • 如果这篇文章在被编辑为&lt;password&gt;之前曾经包含一个真实密码,请务必更改它!

标签: java mysql kubernetes


【解决方案1】:

最终,我设法摆脱了“拒绝访问”问题。 我只是将java代码中的内容更改为:

String url = "jdbc:mysql://" + host + ":3306/PP_Master";
con = DriverManager.getConnection(url, user, password);

之前是:

String url = "jdbc:mysql://" + host + ":3306/PP_Master?user=" + user + "&password=" + password;
con = DriverManager.getConnection(url);

【讨论】:

    猜你喜欢
    • 2020-03-23
    • 2020-01-09
    • 2021-07-01
    • 2018-05-07
    • 2020-07-06
    • 1970-01-01
    • 1970-01-01
    • 2016-07-21
    • 2017-07-15
    相关资源
    最近更新 更多