Pod access outside cluster

Good day,

I have a database for a certain application. If i already have the application running on a Pod can I connect it to the database without including the database in the cluster. In other words, can my Pod have access to database, Redis, rabbitMQ from outside the cluster? I read something about clusterIP and nodePort and that I have to include them in my back-end Pod and connect them to the Pod using Service. Is it possible to connect them to the Pod without placing them in the cluster? I am receiving connection errors from the Pod due to incapability of connecting to my database.

You’ll have to say more about your environment. Is this on a cloud or on bare metal? Is your cluster running with IPs that are part of the larger network or in an overlay / island? In other words, is there direct IP reachability from your pod to your DB?

Hello thockin,

My apologies, yes I am working on local host. I am trying to connect my spring boot API application inside a Pod to an external database (a separate machine within my local network). There is direct IP reachability from my Pod to my database. According to my research, I assume I should make a service file of type ClusterIP for my application to connect to my external database. Unfortunately connection exception is still on my application due to incapability of connecting to my external database.

Cluster information:
Kubernetes version: v1.18.5
VM-Host: Ubuntu 18.04
two virtual machines for worker node and master node

service.yml:

apiVersion: v1
kind: Service
metadata:
   name: portgresql
spec:
 type: ClusterIP
 ports:
 - port: 5432
   targetPort: 5432

endpoint.yml:

apiVersion: v1
kind: Endpoints
metadata:
   name: postgresql
subsets:
 - addresses:
     - ip: {database ip}
   ports:
     - port: 5432

deployment.yml:

apiVersion: apps/v1
kind: Deployment
metadata:
   name: application
   labels:
     app: net
spec:
  replicas: 1
  selector:
    matchLabels:
      app: application
  template:
    metadata:
      labels:
        app: application
    spec:
       containers:
       - name: applicationapi
         image: {image name}
         ports:
         - containerPort: 80

My apologies, yes I am working on local host. I am trying to connect my spring boot API application inside a Pod to an external database (a separate machine within my local network).
There is direct IP reachability from my Pod to my database.

If there is IP reachability, what isn’t working?

According to my research, I assume I should make a service file for my application to connect to my external database.

Service is an abstraction. It doesn’t have any role in actual
reachability, just in discovery. It provides a “durable” IP for pods,
which have inherently ephemeral IPs. If you have an external database
that you know the IP for, you shouldn’t need a Service.

Sorry, I misinterpreted your question I guess by not having IP reachability I do not have connection to my external database from the Pod. According to previous asked questions, I have noticed that this scenario would need a service so I wanted to try my luck and apply it. I have also changed my application jdbc connection string to postgresql as mentioned in other forums. In addition, I also did a kubeadm reset and made sure the pod-network-cidr={IP would be compatible within my subnet} unfortunately there are still connection issues with my external database.

Logs from application Pod before using a service:

Unhandled Exception: Npgsql.NpgsqlException: Exception while connecting ---> System.TimeoutException: Timeout during connection attempt
   at Npgsql.NpgsqlConnector.Connect(NpgsqlTimeout timeout)
   --- End of inner exception stack trace ---
   at Npgsql.NpgsqlConnector.Connect(NpgsqlTimeout timeout)
   at Npgsql.NpgsqlConnector.RawOpen(NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken)
   at Npgsql.NpgsqlConnector.Open(NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken)
   at Npgsql.ConnectorPool.AllocateLong(NpgsqlConnection conn, NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken)
   at Npgsql.NpgsqlConnection.<>c__DisplayClass32_0.<<Open>g__OpenLong|0>d.MoveNext()

Logs after applying service and endpoint:

Unhandled Exception: System.Net.Internals.SocketExceptionFactory+ExtendedSocketException: Resource temporarily unavailable
   at System.Net.Dns.InternalGetHostByName(String hostName)
   at System.Net.Dns.GetHostAddresses(String hostNameOrAddress)
   at Npgsql.NpgsqlConnector.Connect(NpgsqlTimeout timeout)
   at Npgsql.NpgsqlConnector.RawOpen(NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken)
   at Npgsql.NpgsqlConnector.Open(NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken)
   at Npgsql.ConnectorPool.AllocateLong(NpgsqlConnection conn, NpgsqlTimeout timeout, Boolean async, CancellationToken cancellationToken)
   at Npgsql.NpgsqlConnection.<>c__DisplayClass32_0.<<Open>g__OpenLong|0>d.MoveNext()

Forget JDBC - can you ping or curl or telnet from the pod to the database IP? A kube service isn’t magic - if the bits don’t flow, there’s nothing it can do.

You have not said anything about your environment - is it a cloud? Bare metal? How did you set up the cluster? What network driver are you using?

Dear thockin,

My environment is not cloud, I am working local host while having two virtual machines using VMWare workstation for my master node and worker node on the same machine. And my database is on a different machine within the same network. I set up the cluster using kubeadm.

Below are the Pod IPs, one with service and the other is without.
When I ping the pods from my worker node VM these are the results:

workernode@workernode:~$ ping 192.168.190.198
PING 192.168.190.198 (192.168.190.198) 56(84) bytes of data.
64 bytes from 192.168.190.198: icmp_seq=1 ttl=64 time=0.074 ms
64 bytes from 192.168.190.198: icmp_seq=2 ttl=64 time=0.077 ms
64 bytes from 192.168.190.198: icmp_seq=3 ttl=64 time=0.082 ms
^C
— 192.168.190.198 ping statistics —
3 packets transmitted, 3 received, 0% packet loss, time 2030ms
rtt min/avg/max/mdev = 0.074/0.077/0.082/0.010 ms
workernode@workernode:~$ ping 192.168.190.199
PING 192.168.190.199 (192.168.190.199) 56(84) bytes of data.
64 bytes from 192.168.190.199: icmp_seq=1 ttl=64 time=0.083 ms
64 bytes from 192.168.190.199: icmp_seq=2 ttl=64 time=0.210 ms
64 bytes from 192.168.190.199: icmp_seq=3 ttl=64 time=0.147 ms
^C
— 192.168.190.199 ping statistics —
3 packets transmitted, 3 received, 0% packet loss, time 2026ms
rtt min/avg/max/mdev = 0.083/0.146/0.210/0.053 ms

But when I ping the Pods from my master node there is no response:

root@ubuntu:~/Kubernetes yml files# ping 192.168.190.198
PING 192.168.190.198 (192.168.190.198) 56(84) bytes of data.
^C
— 192.168.190.198 ping statistics —
3 packets transmitted, 0 received, 100% packet loss, time 2028ms
root@ubuntu:~/Kubernetes yml files# ping 192.168.190.199
PING 192.168.190.199 (192.168.190.199) 56(84) bytes of data.
^C
— 192.168.190.199 ping statistics —
3 packets transmitted, 0 received, 100% packet loss, time 2046ms

When i ping my database on both virtual machines there is connection.

Please, put Service out of your mind until you have the lower-level routing sorted. Service doesn’t work unless your pod can reach the database.

It sounds to me like you need to either ensure routability from your larger network into your worker node for the pod IPs on that node, or you need to masquerade all pod traffic when it leaves the node.

Only once your pods can actually reach the database at an IP level can we talk about whether Service is useful to you.

Dear thockin,
Thank you for your help, I adjusted my pods to reach the database as you have mentioned and the way I got it to work is by using hostNetwork = true
Although it is not recommended for production level in terms of security, It will be used for the meantime until I add my database to the cluster.

Knowing people struggle with it, I wrote this up: https://speakerdeck.com/thockin/kubernetes-and-networks-why-is-this-so-dang-hard

2 Likes