When running Kubernetes workflows, most people tend to keep the stateless applications like applications on the cluster, and the stateful applications like databases outside of the cluster, on the same VPC. This is a good practice, but it makes debugging a bit more complicated.
Note: I use AWS as an example, but this can be applied to any cloud provider with managed database & K8s using private networks
I assume your database is private and only accessible from a VPC. Maybe for some obscure reasons, you still need to access this database to debug something (Staging database of course cough cough). Well, it might be a bit annoying.
One way would be to spawn an EC2 instance inside the same VPC, install a bunch of tools like netcat
, mysql
, postgres
and debug from the VM. Not very convenient, you might left resources running and it's not very reproducible.
What I would advise, is to use a "reverse-proxy" container inside your cluster. Being on the same VPC as your managed database, you will be able to access it, and this container port can be port-forwarded to your machine. Of course, all the following expect you to have enough privileges to create a pod inside your cluster.
---------- ------- ------------
| Laptop | <--> | Pod | <--> | Database |
---------- ------- ------------
You will need 2 terminal windows:
DB_PORT=5432
DB_HOST=64eddd8e4b61-postgresql.993191f72591.eu-central-1.rds.amazonaws.com
kubectl run psql-tunnel -it --image=alpine/socat --tty --rm --expose=true --port=$DB_PORT tcp-listen:$DB_PORT,fork,reuseaddr tcp-connect:$DB_HOST:$DB_PORT
Here is an explanation of each argument that might be useful to understand what is happening:
socat
: This image allows to establish two bidirectional byte streams and transfers data between them, perfect for our use case!--rm
: Removes the container automatically once it exits. (It helps in cleanup and avoids leaving unused containers.)tcp-listen:$DB_PORT,fork,reuseaddr
: Configures socat
to listen on TCP port 5432
inside the container. The fork
option allows handling multiple connections, and reuseaddr
allows reusing the address.tcp-connect:$DB_HOST:$DB_PORT
: Specifies the destination address and port where the incoming connections to 5432
inside the container will be forwarded. It connects to the host 64eddd8e4b61-postgresql.993191f72591.eu-central-1.rds.amazonaws.com
on port 5432
.and the second command to port-forward the container port to localhost:
kubectl port-forward psql-tunnel 54323:5432
You can now use any GUI to connect to the DB and visualize what is happening (TablePlus, DBeaver, PhpMyAdmin, etc)!