Connecting to a Postgres DB running in K8s (Docker Desktop)

8/29/2021

Is the host needed when connecting to a Postgres container behind a K8s service?

I was able to connect via the sql driver using just the username, password and dbname. When using the postgres driver with GORM it fails without the host in the url.

The issue is that the service IP address routing to the Postgres container is only known once creating and applying the service to the cluster. The container running code to connect to the Postgres container doesn't have access to this host variable, without hardcoding or adding the host to the secrets and reapplying the secrets file.

What is the correct way to dynamically connect to the Postgres container via the K8s service from another container?

-- some_id
docker
kubernetes
postgresql

1 Answer

8/30/2021

The idiomatic way to achieve this is to use the service name as hostname and the port the service is exposing.

When in the same namespace, the service name alone is enough. I.E.

my-service-name:8080

When in different namespaces, you can append the namespace to the service name as its part of the container's fully qualified domain name. I.E.

my-service.my-namespace:8080

Additionally, many tools and even the browser is using default ports. So if you were to expose your service on port 80 and wanted to reach it over HTTP with let's say curl, you could omit the port since curl would use port 80 by default.

curl my-service

Note that in this instance even the protocol is left out, as curl uses HTTP by default. If you wanted to connect over HTTPS on port 8080 to a service, then you would need to provide both protocol and port.

curl https://my-service:8080

This is because, Kubernetes runs its own DNS resolver. To learn more about this, you can maybe look at this question.

https://stackoverflow.com/questions/50668124/why-dig-does-not-resolve-k8s-service-by-dns-name-while-nslookup-has-no-problems/68130684#68130684

Furthermore, it is a common pattern to use environment variables for your container to set the URI to connect to other services. That has the benefit of being able to deploy your service everywhere without having to know how the other service may be reachable upfront. Otherwise, you would potentially need to rebuild the container, if something outside such as service name or port has changed.

-- The Fool
Source: StackOverflow