postgresql - 无法通过 Spring Boot 将 Docker Desktop Kubernetes (Windows) 服务连接到本地 Postgres 数据库

标签 postgresql spring-boot docker kubernetes

我无法通过 Docker Desktop (Windows) 将 Kubernetes 管理的 Dockerized Spring Boot API 连接到 Postgres 的本地实例。错误如下:

org.postgresql.util.PSQLException: Connection to postgres-db-svc.default.svc.cluster.local:5432 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections.

在尝试连接到本地数据库之前,一切都工作正常(外部客户端可以通过 Ingress 连接到 Pod,Pod 可以相互通信等)。

我认为我的配置在某个地方出现了问题。

配置映射

apiVersion: v1
kind: ConfigMap
metadata:
  creationTimestamp: 2017-12-27T18:38:34Z
  name: test-docker-config
  namespace: default
  resourceVersion: "810136"
  uid: 352c4572-eb35-11e7-887b-42010a8002b8
data:
  spring_datasource_platform: postgres
  spring_datasource_url: jdbc:postgresql://postgres-db-svc.default.svc.cluster.local/sandbox
  spring_datasource_username: postgres
  spring_datasource_password: password
  spring_jpa_properties_hibernate_dialect: org.hibernate.dialect.PostgreSQLDialect

服务

kind: Service
apiVersion: v1
metadata:
  name: postgres-db-svc
spec: 
  type: ExternalName
  externalName: kubernetes.docker.internal
  ports:
  - port: 5432

在我的主机文件中,“kubernetes.docker.internal”映射到 127.0.0.1

部署

apiVersion: apps/v1
kind: Deployment
metadata:
  name: tester
spec:
  selector:
    matchLabels:
      app: tester
  template:
    metadata:
      labels:
        app: tester
    spec:
      containers:
      - name: tester
        imagePullPolicy: IfNotPresent
        image: test-spring-boot
        resources:
          limits:
            memory: "128Mi"
            cpu: "500m"
        ports:
        - containerPort: 8080
        env:
        - name: SPRING_DATASOURCE_PLATFORM
          valueFrom:
            configMapKeyRef:
              name: test-docker-config
              key: spring_datasource_platform
        - name: SPRING_DATASOURCE_URL
          valueFrom:
            configMapKeyRef:
              name: test-docker-config
              key: spring_datasource_url
        - name: SPRING_DATASOURCE_USERNAME
          valueFrom:
            configMapKeyRef:
              name: test-docker-config
              key: spring_datasource_username
        - name: SPRING_DATASOURCE_PASSWORD
          valueFrom:
            configMapKeyRef:
              name: test-docker-config
              key: spring_datasource_password
        - name: SPRING_JPA_PROPERTIES_HIBERNATE_DIALECT
          valueFrom:
            configMapKeyRef:
              name: test-docker-config
              key: spring_jpa_properties_hibernate_dialect

Spring Boot application.properties

spring.datasource.platform=${SPRING_DATASOURCE_PLATFORM:postgres}
spring.datasource.url=${SPRING_DATASOURCE_URL:jdbc:postgresql://localhost:5432/sandbox}
spring.datasource.username=${SPRING_DATASOURCE_USERNAME:postgres}
spring.datasource.password=${SPRING_DATASOURCE_PASSWORD:password}
spring.jpa.properties.hibernate.dialect=${SPRING_JPA_PROPERTIES_HIBERNATE_DIALECT:org.hibernate.dialect.PostgreSQLDialect}

最佳答案

带有 Docker 的 Kubernetes 在同一个 Docker 虚拟机中运行,因此我假设您引用的 /etc/hosts 文件是 Windows 计算机上的文件。

我还假设您运行 Postgres 并使用如下内容公开 5432:

docker run --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword -d -p 5432:5432 postgres

首先,127.0.0.1 不起作用,因为如果是虚拟机,docker 只会公开 IP 地址上的端口。

其次,Kubernetes 将无法找到 kubernetes.docker.internal,因为 Pod 使用 CoreDNS来解析,但它不知道该域。

我建议你这样做:

  • 不要使用kubernetes.docker.internal,因为它已被 docker 用于其自身目的。使用类似 mypostgres.local

  • 获取 Docker 虚拟机的 IP 地址。运行 ping docker.local 或在 `C:\Windows\System32\drivers\etc\hosts 下查找类似的内容:

    Added by Docker Desktop
    10.xx.xx.xx host.docker.internal
    

    或者查看 ipconfig/all 的输出并找到 Docker 桌面虚拟机的 IP。

  • 使用hostAliases在你的 podSpec 中,这样 /etc/hosts 文件实际上是在你的 pod 中修改的。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: tester
    spec:
      selector:
        matchLabels:
          app: tester
      template:
        metadata:
          labels:
            app: tester
        spec:
          hostAliases:
          - ip: "10.xx.xx.xx" # The IP of your VM
            hostnames:
            - "mypostgres.local"
          containers:
          - name: tester
            imagePullPolicy: IfNotPresent
            image: test-spring-boot
            resources:
              limits:
                memory: "128Mi"
                cpu: "500m"
    
  • 请勿使用 ExternalName 服务,因为这些服务仅适用于 CoreDNS。如果您希望 ExternalName 服务正常工作,您必须修改您的 CoreDNS配置,以便对 mypostgres.local

    的条目进行硬编码

注意:另一种选择是在 Kubernetes 中运行 Postgresql 并使用常规 ClusterIP 公开它。服务。

关于postgresql - 无法通过 Spring Boot 将 Docker Desktop Kubernetes (Windows) 服务连接到本地 Postgres 数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62746410/

相关文章:

Python psycopg2 postgres 选择包含字段名称的列

sql - 简化嵌套的 case when 语句

java - 如何动态调整列表类型变量的输入?

java - 如何在 Spring Boot 中为 Controller 编写单元测试

docker-compose 主机和容器上的持久数据

docker - 如何将文件从服务器复制到Docker容器

django - postgreSQL.app : create database

java - 如何使用 Spring Boot 2.1.1 从外部文件夹获取 "display"文件

docker - 无法使用Dockerfile中的参数执行Shell脚本

sql - 选择一张信用卡的最新余额大于另一张信用卡的人