17

I've set up an application stack running on Google Kubernetes Engine + Google Cloud SQL. When developing locally, I would like my application to connect to a postgres database server running outside the cluster to simulate the production environment.

It seems that the way to do this is by defining an external endpoint as described here: Minikube expose MySQL running on localhost as service

Unfortunately, I am not able to specify "127.0.0.1" as the Endpoint IP address:

kubectl apply -f kubernetes/local/postgres-service.yaml
service "postgres-db" unchanged
The Endpoints "postgres-db" is invalid: subsets[0].addresses[0].ip: 
Invalid value: "127.0.0.1": may not be in the loopback range (127.0.0.0/8)

So I am forced to bind postgres to my actual machine address.

It seems like there MUST be a way to map a port from my localhost into the local kubernetes cluster, but so far I can't find a way to do it.

Anybody know the trick? Or alternatively, can someone suggest an alternative solution which doesn't involve running postgres inside the cluster?

lasersox
  • 171
  • 1
  • 1
  • 3

5 Answers5

20

May not be an answer for Minikube, but I ended up here so I share what I did for Kubernetes in Docker for Mac.

I added a service like this for PostgreSQL:

kind: Service
apiVersion: v1
metadata:
  name: postgres
  namespace: default
spec:
  type: ExternalName
  # https://docs.docker.com/docker-for-mac/networking/#use-cases-and-workarounds
  externalName: host.docker.internal
  ports:
    - name: port
      port: 5432

My application was able to connect to the locally running postgres server with this setup using the domain name postgres. The Postgres server can listen to 127.0.0.1 with this setup.

jfunez
  • 397
  • 6
  • 23
psmith
  • 2,292
  • 1
  • 19
  • 19
  • Thank you! This was really helpful. – digitaldreamer Jun 20 '18 at 20:19
  • Thank you! This was really helpful – F___ Apr 01 '20 at 10:00
  • This is great it works just perfectly but do know if there are some resources that can explain exactly how it's working? https://kubernetes.io/docs/concepts/services-networking/service/#externalname – zaf187 Oct 06 '20 at 10:45
  • I just had to remember to put this in the correct namespace and then it worked like a charm. – Kent Bull Jan 20 '22 at 03:52
  • 2
    I just passed `jdbc:postgresql://host.docker.internal:5432/postgres` in as an environment variable for my DB_URL and it connected. Didn't have to create an additional service – orpheus Mar 31 '22 at 20:47
3

There is a potential solution for this called Telepresence which allows to have a local workload to be proxied into the cluster as if it were actualy run within that kube cluster.

Radek 'Goblin' Pieczonka
  • 21,554
  • 7
  • 52
  • 48
1

K8s Native Approach

I had similar issues with developing cloud-native software directly inside Kubernetes. We took a look at tools like Telepresence and Skaffold, too but they are hard to configure and very time-consuming.

That's why I built the DevSpace CLI together with a colleague: https://github.com/covexo/devspace

Feel free to take a look and try it out. It will solve issues like yours by allowing you to easily run all your workloads directly inside Kubernetes while still being able to program with your desktop tools (local terminal, IDE, git etc).

Alternative: Minikube networking

As you are using minikube, you should take a look as the answers to this question: Routing an internal Kubernetes IP address to the host system

Alternative: Tunneling

You could also use local tunneling with tools like ngrok: https://ngrok.com/ (simply start it locally and connect to your ngrok address from anywhere)

Lukas Gentele
  • 949
  • 7
  • 13
0

Faced a similar situation on Mac . My Postgresdb is running locally. What I did was to pass the credentials of the db as environment variables. Pay special attention to the HOST variable that composes the string to connect to the db.



apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
  labels:
    app: myapp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: app-container
        image: <YOUR_IMAGE>
        ports:
        - containerPort: 8080
        env:
        - name: POSTGRES_USER
          value: <YOUR_USER>
        - name: POSTGRES_PASSWORD
          value: <YOUR_PASSWORD>
        - name: HOST
          value: docker.for.mac.host.internal
        - name: POSTGRES_DB
          value: <YOUR_DB_NAME>

DAVID LOBO
  • 11
  • 1
-1

Mysql server should connect to private IP, and that private IP can be used in application.

Prefer way is to create kubernetes service+endpoint pointing to Mysql Server IP.

Akash Sharma
  • 721
  • 3
  • 6
  • I think you're suggesting the same thing as this other answer I linked. Unfortunately, Kubernetes won't allow me to point the endpoint to the PostgreSQL server IP on the loopback address. The only way I can get that working is by exposing PostgreSQL on my primary network interface which I don't really want to do. – lasersox Mar 15 '18 at 21:49