traefik on k8s route to postgres over TCP

3/11/2020

We're running traefik on k8s, I'm able to build routes to http services but not TCP, e.g. I'm able to get the whoami service but not the postgres service.

Initial setups:

I installed postgres via standard helm chart

I installed traefik via it's helm chart as well.

This is working:

apiVersion: apps/v1
metadata:
  name: whoami
  namespace: shared
  labels:
    app: containous
    name: whoami

spec:
  replicas: 2
  selector:
    matchLabels:
      app: containous
      task: whoami
  template:
    metadata:
      labels:
        app: containous
        task: whoami
    spec:
      containers:
        - name: containouswhoami
          image: containous/whoami
          ports:
            - containerPort: 80

---
apiVersion: v1
kind: Service
metadata:
  name: whoami
  namespace: shared

spec:
  ports:
    - name: http
      port: 80
  selector:
    app: containous
    task: whoami

---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: whoami
  namespace: shared
  annotations:
    kubernetes.io/ingress.class: traefik
spec:
  rules:
  - host: example.com
    postgres:
      paths:
      - backend:
          serviceName: whoami
          servicePort: http

I'm able to open my browser, navigate to http://example.com and get the expected whomai page.

Since we deployed postgres via helm, and the service has type ClusterIP, how can I provide my developers access to the database? Again I went with the "k8s ingress" and not the CRD cuz I'm not an expert.

Here's where I think I'm missing something basic, what I know is they're trying to use a client to reach something like this:

jdbc:postgresql://example.com:5432/postgres (of course the client allows the input of user/pass/database)

  • Am I wrong in expecting to build a traefik TCP ingress that would allow such access?
  • Any examples of such access on k8s? cuz I found a few posts that deal with docker-compose
  • Any alternatives to traefik or generally a way to handle this challenge without opening a public IP (i.e. service type Loadbalancer).

Statefulset:

+ kubectl get statefulset -n shared
NAME                 READY   AGE
admindb-postgresql   1/1     23h

Service:

+ kubectl get service -n shared
NAME                          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
admindb-postgresql            ClusterIP   10.100.75.113   <none>        5432/TCP   23h
admindb-postgresql-headless   ClusterIP   None            <none>        5432/TCP   23h
whoami                        ClusterIP   10.100.25.131   <none>        80/TCP     44m

Statefulset description:

+ kubectl describe statefulset admindb-postgresql -n shared
Name:               admindb-postgresql
Namespace:          shared
CreationTimestamp:  Tue, 10 Mar 2020 11:05:43 +0200
Selector:           app=postgresql,release=admindb,role=master
Labels:             app=postgresql
                    chart=postgresql-8.3.3
                    heritage=Helm
                    release=admindb
Annotations:        <none>
Replicas:           1 desired | 1 total
Update Strategy:    RollingUpdate
Pods Status:        1 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:  app=postgresql
           chart=postgresql-8.3.3
           heritage=Helm
           release=admindb
           role=master
  Init Containers:
   init-chmod-data:
    Image:      docker.io/bitnami/minideb:buster
    Port:       <none>
    Host Port:  <none>
    Command:
      /bin/sh
      -cx
      echo "current user id: `id`"
      mkdir -p /bitnami/postgresql/data
      chmod 700 /bitnami/postgresql/data
      find /bitnami/postgresql -mindepth 1 -maxdepth 1 -not -name ".snapshot" -not -name "lost+found" | \
        xargs chown -R 1001:1001
      chmod -R 777 /dev/shm

    Requests:
      cpu:        250m
      memory:     256Mi
    Environment:  <none>
    Mounts:
      /bitnami/postgresql from data (rw)
      /dev/shm from dshm (rw)
  Containers:
   admindb-postgresql:
    Image:      docker.io/bitnami/postgresql:11.6.0-debian-10-r5
    Port:       5432/TCP
    Host Port:  0/TCP
    Requests:
      cpu:      250m
      memory:   256Mi
    Liveness:   exec [/bin/sh -c exec pg_isready -U "postgres" -h 127.0.0.1 -p 5432] delay=30s timeout=5s period=10s #success=1 #failure=6
    Readiness:  exec [/bin/sh -c -e exec pg_isready -U "postgres" -h 127.0.0.1 -p 5432
[ -f /opt/bitnami/postgresql/tmp/.initialized ] || [ -f /bitnami/postgresql/.initialized ]
] delay=5s timeout=5s period=10s #success=1 #failure=6
    Environment:
      BITNAMI_DEBUG:           false
      POSTGRESQL_PORT_NUMBER:  5432
      POSTGRESQL_VOLUME_DIR:   /bitnami/postgresql
      PGDATA:                  /bitnami/postgresql/data
      POSTGRES_USER:           postgres
      POSTGRES_PASSWORD:       <set to the key 'postgresql-password' in secret 'pg-default-password'>  Optional: false
      POSTGRESQL_ENABLE_LDAP:  no
    Mounts:
      /bitnami/postgresql from data (rw)
      /dev/shm from dshm (rw)
  Volumes:
   dshm:
    Type:       EmptyDir (a temporary directory that shares a pod's lifetime)
    Medium:     Memory
    SizeLimit:  1Gi
Volume Claims:
  Name:          data
  StorageClass:
  Labels:        <none>
  Annotations:   <none>
  Capacity:      30Gi
  Access Modes:  [ReadWriteOnce]
Events:          <none>

Service description:

+ kubectl describe svc -n shared admindb-postgresql
Name:              admindb-postgresql
Namespace:         shared
Labels:            app=postgresql
                   chart=postgresql-8.3.3
                   heritage=Helm
                   release=admindb
Annotations:       <none>
Selector:          app=postgresql,release=admindb,role=master
Type:              ClusterIP
IP:                10.100.75.113
Port:              tcp-postgresql  5432/TCP
TargetPort:        tcp-postgresql/TCP
Endpoints:         10.55.0.17:5432
Session Affinity:  None
Events:            <none>
-- Naim Salameh
kubernetes
postgresql
traefik
traefik-ingress

0 Answers