Access external database from Kubernetes

8/10/2020

I have a kubernetes (v1.18.6) with 1 service (loadbalancer), 2 pods in a develoment:

apiVersion: v1
kind: Service
metadata:
  name: app-service
spec:
  selector:
    app: app
  ports:
  - protocol: "TCP"
    port: 6000
    targetPort: 5000
  type: LoadBalancer

A network policy to access Intenert (it is necesary for me):

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: internet-access
spec:
  podSelector:
    matchLabels:
      networking/allow-internet-access: "true"
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - {}

Deployment config file

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-deployment
spec:
  progressDeadlineSeconds: 120
  selector:
    matchLabels:
      app: app
  replicas: 2
  template:
    metadata:
      labels:
        app: app
    spec:
      imagePullSecrets:
        - name: myregistrykey
      containers:
      - name: app
        image: app
        imagePullPolicy: Always
        ports:
        - containerPort: 5000

It is working correctly. But now, I want to connect this imagen to an external database (in another network only access by internet). For this proposition I use this service:

apiVersion: v1
kind: Service
metadata:
  name: postgresql
spec:
  clusterIP: None
  ports:
  - port: 25060


---
apiVersion: v1
kind: Endpoints
metadata:
  name: postgresql
subsets:
  - addresses:
        - ip: 206............
    ports:
      - port: 25060
        name: postgresql

It is all the services:

NAME                TYPE           CLUSTER-IP       EXTERNAL-IP      PORT(S)          AGE
app-service         LoadBalancer   10.245.134.137   206...........   6000:31726/TCP   2d4h
kubernetes          ClusterIP      10.245.0.1       <none>           443/TCP          3d7h
postgresql          ClusterIP      None             <none>           25060/TCP        19h

But when I try to connect I receive a timeout error of the database, like can't connect to the database.

I have an internet connection in the image.

I find the solution, the problem was the rules of inbound of the database. I must add the IP of Kubernetes.

Thx.

-- Francisco Gonzalez
digital-ocean
kubernetes
postgresql

4 Answers

8/10/2020

The service definition should be corrected. Default service type is clusterIP which doesn't work for external database. You need to update the service type as given below

type: ExternalName

also ensure that service name and the endpoint name should match. it is different in your yaml. please check

-- P Ekambaram
Source: StackOverflow

8/18/2020

If I understand correctly, you have your cluster with application on Digital Ocean cloud and your PostgreSQL is outside this cluster.

In your Application Deployment <> application service you have used services with selectors so you didn't need to create Endpoints manually.

In your external database service you have used services without selectors so you had to create Endpoint manually.

As database is external service, using clusterIP: None is pointless as it will try to match pods inside the cluster. I guess you added it as you read in this docs.

Last thing is that in Endpoint you set ip: 206... which is the same as application service LoadBalancer ip?

NAME                TYPE           CLUSTER-IP       EXTERNAL-IP      PORT(S)          AGE
app-service         LoadBalancer   10.245.134.137   206...........   6000:31726/TCP   2d4h

subsets:
  - addresses:
      - ip: 206............
    

It is only a part of information so I am guessing. However in this part you should provide IP of desired database, not your application Loadbalancer IP.

Now based on scenario you can connect:

  • Database outside cluster with IP address
  • Remotely hosted database with URI
  • Remotely hosted database with URI and port remapping

Detailed information about above scenarios you can find in Kubernetes best practices: mapping external services

Based on your current config I assume you want to use scenario 1.

If this database and cluster are somewhere in cloud you could use internal Database IP. If not you should provide IP of machine where this Database is hosted.

You can also read Kubernetes Access External Services article.

Please let me know if you will still have issue after IP change

-- PjoterS
Source: StackOverflow

2/22/2021

For better visibility I am placing the answer OP mentioned in question:

I find the solution, the problem was the rules of inbound of the database. I must add the IP of Kubernetes

-- Matt
Source: StackOverflow

8/10/2020

Here is what worked for me:

Define a service , but set clusterIP: None , so no endpooint is created.

And then create an endpoint yourself with the SAME NAME as your service and set the IP and port of your db.

In your example , you have a type in your endpoint: the name of your endpoint is postgresql not postgresSql.

My example:

---
service.yaml
kind: Service
apiVersion: v1
metadata:
  name: backend-mobile-db-service
spec:
  clusterIP: None
  ports:
  - port: 5984
---
kind: Endpoints
apiVersion: v1
metadata:
  name: backend-mobile-db-service
subsets:
  - addresses:
        - ip: 192.168.1.50
    ports:
      - port: 5984
        name: backend-mobile-db-service
-- Popopame
Source: StackOverflow