23

In this application, nodejs pods are running inside kubernetes, and mongodb itself sitting outside at host as localhost.

This indeed not good design, but its only for dev environment. In production a separte mongodb server will be there, as such option to have a non loopback ip in endpoint, so will not be a problem in Production.

Have considered following options for dev environment

  1. Use localhost connect string to connect to mongodb, but it will refer to pod's own localhost not host's localhost

  2. Use headless service and provide localhost ip and port in endpoint. However endpoint doesn't allow loopback

Suggest if there is a way to access mongodb database at host's localhost from inside cluster (pod / nodejs application).

Datz
  • 3,156
  • 3
  • 22
  • 50
GLK
  • 875
  • 2
  • 9
  • 25
  • Can you specify on which environment are you working on ? Also did you check: https://stackoverflow.com/questions/55164223/access-mysql-running-on-localhost-from-minikube https://stackoverflow.com/questions/60882006/how-to-connect-to-mongodb-running-on-localhost-from-minikube ? – Malgorzata Dec 03 '20 at 15:11
  • @Malgorzata Am usnig Ubuntu 20.04, and on that created kubernetes node using multipass. Though scenario is different but what I can use from your link is to configure mongo to listen on another ip i.e. `172.17.0.1:27017` , and with this I can create a headless service, and mention `172.17.0.1:27017` in endpoint. It should work as it not seems to be loopback ip. let me update you tomorrow how it works. – GLK Dec 03 '20 at 16:18
  • @Malgorzata Its working, instead of using 172.17.0.1 I had to use 10.62.176.1 because multipass interface use this port. Thanks for hint, if you wish, you can send it as answer for my acceptance. – GLK Dec 04 '20 at 08:21
  • Glad to hear that, I have posted it as an answer. – Malgorzata Dec 04 '20 at 10:16
  • It worked for me just by using a my local ip(192.168...) instead of the loop-back address(127.0....) – megalucio Nov 30 '22 at 09:26

4 Answers4

17

I'm running on docker for windows, and for me just using host.docker.internal instead of localhost seems to work fine.

For example, my mongodb connection string looks like this:

mongodb://host.docker.internal:27017/mydb

As an aside, my hosts file includes the following lines (which I didn't add, I guess the docker desktop installation did that):

# Added by Docker Desktop
192.168.1.164 host.docker.internal
192.168.1.164 gateway.docker.internal
joniba
  • 3,339
  • 4
  • 35
  • 49
  • Yeah it worked for me just the same by using a my local ip(192.168...) instead of the loop-back address(127.0....) – megalucio Nov 30 '22 at 09:26
16

127.0.0.1 is a localhost(lo0) interface IP address. Hosts, nodes and pods have their own localhost interfaces and they are not connected to each other.

Your mongodb is running on the Host machine and cannot be accessible using the localhost (or it's IP range) from inside a cluster pod or from inside vm.

In your case, create a headless service and Endpoint for it inside the cluster:

Your mongodb-service.yaml file should look like this:

apiVersion: v1
kind: Service
metadata:
   name: mongodb-service
spec:
   clusterIP: None
   ports:
   - protocol: TCP
     port: <multipass-port-you-are-using>
     targetPort: <multipass-port-you-are-using>
   selector:  
     name:  example
   type: ClusterIP
---
apiVersion: v1
kind: Endpoints
metadata:
  name: mongodb-service
subsets:
  - addresses:
    - ip: 10.62.176.1
    ports:
      - port: <multipass-port-you-are-using>

I have add IP you've mentioned in comment section.

After creating service and endpoint you can use mongodb-service name and port <multipass-port-you-are-using> inside any pod of this cluster as a destination point.

Take a look: mysql-localhost, mongodb-localhost.

Malgorzata
  • 6,409
  • 1
  • 10
  • 27
  • I tried your solution and it worked, thanks. But I notices something that bothers me now. In my host's cni0 netns it has ip 10.244.0.1. I tried connecting it without a service and it worked. So, service seems a bit overcomlicated now. It's my first time setting up kubernetes and it's running on a single node yet. Am I missing something? – dareka Jan 20 '22 at 14:03
3

If you are using minikube to deploy a local kubernetes, you can reach your local environment using the variable host.minikube.internal.

d3vpasha
  • 459
  • 7
  • 24
0

I can add one more solution with Ingress and external-service, which may help some of you.

I deploy my complete system locally with a special Kustomize overlay.

When I want to replace one of the deployments with a service running locally in my IDE, I do the following:

I add an ExternalName service which forwards to host.docker.internal:

kind: Service
apiVersion: v1
metadata:
  name: backend-ide
spec:
  type: ExternalName
  externalName: host.docker.internal

and reconfigured my ingress to forward certain request from my web-app to this external-service:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: backend-ingress
spec:
  ingressClassName: nginx
  rules:
    - host: url.used.by.webapp.com
      http:
        paths:
          - path: /customerportal/api(/|$)(.*)
            pathType: Prefix
            backend:
              service:
                name: backend-ide
                port:
                  number: 8080

The same way, I can access all other ports on my host.

Datz
  • 3,156
  • 3
  • 22
  • 50