Reputation: 141
I am not able to connect a dockerized Spring Boot API managed by Kubernetes via Docker Desktop (Windows) to a local instance of Postgres. Error is as follows:
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.
Up until trying to connect to a local DB, everything has been working fine (external clients can connect to pods via Ingress, pods can communicate with each other, etc).
I think somewhere my configuration is off here.
ConfigMap
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
Service
kind: Service
apiVersion: v1
metadata:
name: postgres-db-svc
spec:
type: ExternalName
externalName: kubernetes.docker.internal
ports:
- port: 5432
In my hosts file, "kubernetes.docker.internal" is mapped to 127.0.0.1
Deployment
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}
Upvotes: 2
Views: 1420
Reputation: 61551
Kubernetes with Docker runs in the same docker VM, so I'm assuming the /etc/hosts
file that you are referring to is the one on your Windows machine.
I'm also assuming that you ran Postgres exposing 5432
with something like this:
docker run --name some-postgres -e POSTGRES_PASSWORD=mysecretpassword -d -p 5432:5432 postgres
First, 127.0.0.1
is not going to work because docker just exposes the ports on the IP address if the VM.
Secondly, Kubernetes will not able able to find kubernetes.docker.internal
because the pods use CoreDNS
to resolve and it has no idea about that domain.
I suggest you do this:
Don't use kubernetes.docker.internal
as it's already used by docker for its own purpose. Use something like mypostgres.local
Get the IP address of your docker VM. Run ping docker.local
or look under `C:\Windows\System32\drivers\etc\hosts for something like this:
Added by Docker Desktop
10.xx.xx.xx host.docker.internal
or look at the output from ipconfig /all
and find the IP from the docker desktop VM.
Use hostAliases
in your podSpec, so that the /etc/hosts
file is actually modified in your 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"
Don't use an ExternalName
service as those work only with CoreDNS. If you want the ExternalName
service to work you will have to modify your CoreDNS
config so that it hardcodes the entry for mypostgres.local
Note: Another option is just to run Postgresql in Kubernetes and expose it using a regular ClusterIP service.
Upvotes: 2