How to create an ingress for TCP router?

I am using Traefik v2 on a kubernetes cluster which is working absolutely fine.

Now, I am trying to create a TCP router so that pg.cli-api.fun can load balance between the backend external (outside Kubernetes) application on tcp port 80

I have created this in my config file which seems to be working fine

[tcp]
  [tcp.routers]
    [tcp.routers.router-1-cluster]
      entryPoints = ["websecure"]
      rule = "Host(`pg.cli-api.fun`)"
      service = "router-1-service"
      [tcp.routers.router-1-cluster.tls]
        passthrough = true
  [tcp.services]
    [tcp.services.router-1-service.loadBalancer]
       [[tcp.services.router-1-service.loadBalancer.servers]]
        address = "192.168.0.75:80"
       [[tcp.services.router-1-service.loadBalancer.servers]]
        address = "192.168.0.76:80"

But on the UI (https:///dashboard/#/tcp/routers), when I click on the tcp router, I see this in red color. Any ideas what I could be missing?

unknown rule Host(`pg.cli-api.fun`)

For a TCP router you need to use HostSNI

1 Like

Thanks, I have changed the above to "HostSNI(something.example.com)". Now, I don't have that error, but facing a 404 error now :frowning:

Well if you're doing http like your error suggests you should be using a http router.

Your question is for TCP though, which are you doing ?

yeah, you are right. I am just trying to see how TCP routing works with Traefik. To test things out, I have installed a postgres service now at port 5432 and have updated my config to this.

[tcp]
  [tcp.routers]
    [tcp.routers.pg-ha-cluster]
      rule = "HostSNI(`pg.cli-api.fun`)"
      service = "pg-service"
      # will route TLS requests (and ignore non tls requests)
      #[tcp.routers.pg-ha-cluster.tls]
      #  passthrough = true
  [tcp.services]
    [tcp.services.pg-service.loadBalancer]
       [[tcp.services.pg-service.loadBalancer.servers]]
        address = "192.168.0.75:5432"

I am not sure if this should be the correct config and maybe I need to add another entry point for just this TCP router? As of now, I have below entry points.

[entryPoints]
  [entryPoints.web]
    address = ":80"
    #compress = true
  [entryPoints.websecure]
    address = ":443"
    [entryPoints.websecure.forwardedHeaders]
      insecure = true
  [entryPoints.ping]
    address = ":8082"
  [entryPoints.metrics]
    address = ":8083"

My end goal is to be able to connect at pg.cli-api.fun with something like below, not sure which port will work here.

PGPASSWORD=docker psql -h pg.cli-api.fun -p <some_port> -U postgres -w

Sorry to tell you this. But postgres does not do tls in a compatible fashion. Postgres upgrades to TLS within its own protocol.

You could to postgres with HostSNI(`*`)

Oops, I picked up the wrong thing to test TCP out.

Hmm. What hostname will I use to connect to the service in this case?
Is there any example, I can follow to have a working TCP router? I have Googled and looked at the Traefik docs but could not find any.

@vikas027

I've left the certificate resolver out but here is a basic example.

version: "3.8"

services:
  traefik:
    image: traefik:v2.2
    command:
      # entrypoint web is port 80
      - --entrypoints.web.address=:80
      # entrypoint websecure is port 443
      - --entrypoints.websecure.address=:443
      # entrypoint echo is port 1234
      - --entrypoints.echo.address=:1234
      - --providers.docker=true
      # insecure dashboard
      - --api.insecure
    ports:
      - "80:80"
      - "443:443"
      - "1234:1234"
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock:ro"

  echo:
    # echo back what is received after EOL
    image: alpine/socat
    command: -v tcp-l:2000,fork exec:'/bin/cat'
    labels:
      traefik.enable: true
      traefik.tcp.services.echo.loadbalancer.server.port: 2000
      # not TLS on port 1234, router HostSNI(`*`) must be used
      # nc -v localhost 1234
      traefik.tcp.routers.echo-insecure.rule: HostSNI(`*`)
      traefik.tcp.routers.echo-insecure.entrypoints: echo
      # contrived example with tls tcp router on the same port.
      # openssl s_client -connect 127.0.0.1:1234 -servername echo.local
      traefik.tcp.routers.echo-secure.rule: HostSNI(`echo.local`)
      traefik.tcp.routers.echo-secure.tls: true
      traefik.tcp.routers.echo-secure.entrypoints: echo
      # tcp router on port 443 
      # openssl s_client -connect 127.0.0.1:443 -servername echo.local
      traefik.tcp.routers.echo-websecure.rule: HostSNI(`echo.local`)
      traefik.tcp.routers.echo-websecure.tls: true
      traefik.tcp.routers.echo-websecure.entrypoints: websecure
  whoami:
    image: containous/whoami
    labels:
      # curl -ik https://whoami.local --resolve whoami.local:443:127.0.0.1
      traefik.http.routers.whoami.rule: Host(`whoami.local`)
      traefik.http.routers.whoami.tls: true
      traefik.http.routers.whoami.entrypoints: websecure


2 Likes

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.