Postgresql Ingress using Traefik Kubernetes K3s

Jul 4, 2022

I found it rather tricky to set up a Traefik TCP ingress for connecting directly to a PostgreSQL server running inside Kubernetes. There are a few moving parts, and they all need to be right for the ingress to work, but most resources I found on the internet left out one (or more), so here they all are in one place. While I’ve only tried this with PostgreSQL, it’s likely that other database ingresses will work the same way.

Traefik values.yaml

Two additions are needed:

additionalArguments:
  - "--entryPoints.postgresql.address=:5432/tcp"
ports:
  postgresql:
    expose: true
    port: 5432
    exposedPort: 5432
    protocol: TCP

On k3s, Traefik is installed in the kube-system namespace via Helm, so if you use Helm to modify the values above, make sure you use the same namespace. I didn’t want to risk changing whatever values Rancher had used by default, so I specified the full set:

rbac:
  enabled: true
ports:
  websecure:
    tls:
      enabled: true
podAnnotations:
  prometheus.io/port: "8082"
  prometheus.io/scrape: "true"
providers:
  kubernetesIngress:
    publishedService:
      enabled: true
priorityClassName: "system-cluster-critical"
image:
  name: "rancher/mirrored-library-traefik"
  tag: "2.6.2"
tolerations:
- key: "CriticalAddonsOnly"
  operator: "Exists"
- key: "node-role.kubernetes.io/control-plane"
  operator: "Exists"
  effect: "NoSchedule"
- key: "node-role.kubernetes.io/master"
  operator: "Exists"
  effect: "NoSchedule"
service:
  ipFamilyPolicy: "PreferDualStack"

I used Terraform to install the Helm release, but if you use the CLI, run:

helm repo add traefik https://helm.traefik.io/traefik
helm repo update
helm upgrade --install traefik traefik/traefik \
  -n kube-system -f values.yaml

Traefik Ingress

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP
metadata:
  name: postgresql-ingress
  namespace: postgresql
spec:
  entryPoints:
    - postgresql
  routes:
    match: HostSNI(`*`)
    services:
      - name: postgresql
        port: 5432

With both sets of changes, you should be able to connect to the PostgreSQL instance on port 5432 of your control node’s IP, or any hostname that resolves to that IP. If you want to run other databases and expose them on the same host, they’ll need to listen on a different port.