traefik / traefik

The Cloud Native Application Proxy
https://traefik.io
MIT License
51.08k stars 5.08k forks source link

UDP support #5048

Closed juliens closed 4 years ago

juliens commented 5 years ago

Do you want to request a feature or report a bug?

Proposal

What did you expect to see?

The configuration for UDP could be the same as TCP/HTTP routers/services. As UDP doesn't support TLS and HostSNI yet, there will be no routing and so no Rule part. The only way to "route", will be to use a non-used entrypoint (only one UDP router per entrypoint)

[udp]
    [udp.routers]
         [udp.routers.test]
         service="my-udp-service"
         entryPoints = [ "udp-port-1" ]

     [udp.services]
         [udp.services.my-udp-service.loadbalancer]
         [[udp.services.my-udp-service.loadbalancer.servers]]
         address="192.168.1.1:10"
         [[udp.services.my-udp-service.loadbalancer.servers]]
         address="192.168.1.2:10"
alexisduque commented 5 years ago

We also would be interested in this feature and the UDP Support in Traefik v2. Below is a description of our needs.

Use Case

We have developed 15 years ago a smart photovoltaïc metering system (with GPRS) and have thousands of meters deployed in the world. Every night, in a 30' window, these meters connect to our server opening a UDP socket and send their data in UDP packets. Note that the server IP is hardcoded in the meter firmware and can't be upgraded. These data are collected and processed by a Java web app deployed in a Tomcat servlet container.

Our Issue

Today, we suffer a scalability problem. Our activity growth, the server is pretty old and suffer heavy load every night.

Our Expectation

We expect to deploy Traefik on our server to route the UDP traffic with load balancing to others VPS to support this seasonal load.

jacobblock commented 5 years ago

+1 would love to see this to support more protocol pass-through: dns, ipsec, openvpn, kerberos, radius, nfs, ntp, ftp,tftp.

ramsundhar20 commented 4 years ago

HTTP/3 (QUIC) applications would need UDP based load balancing solution, it would be good to consider this request on priority. HTTP/3 is going to fundamentally change how web is going to communicate and fecilitate low latency connection is limited bandwidth networks. If you would need community contribution, please make a architectural proposal and list the action items. So interested parties can drive individual action items.

NX211 commented 4 years ago

I too would love to see this feature added. I run a huge home lab with Docker and this gets me closer to having everything go through traefik so I wont need to expose anything else. Thanks for the awesome project.

TuKDoan commented 4 years ago

Running DNS filters and having a crazy hard time getting transparent proxy with nginx so the DNS servers are aware of the client.

moffatted commented 4 years ago

Definitely would like to see the UDP feature, another use case is sending UDP packets from Wazuh Agents for IDS events.

Popsiclestick commented 4 years ago

Glad to see others are also looking for this feature. I think this provides a good bit of value.

sharknoon commented 4 years ago

I would love to see UDP support. Currently I have a teamspeak voice-communication server and some parts of the application (filetransfer and serverquery) are running perfectly over TCP, while the main part, voice, needs UDP. This is sadly the one thing of my many docker containers, I cant route over traefik. Looking forward to UDP support on this very great edge router :)

jlegido commented 4 years ago

Hi there.

First of all many thanks to everybody involved in this project and your time.

I need this feature to being able to route DNS queries.

crameth commented 4 years ago

I would love to see UDP support. Currently I have a teamspeak voice-communication server and some parts of the application (filetransfer and serverquery) are running perfectly over TCP, while the main part, voice, needs UDP. This is sadly the one thing of my many docker containers, I cant route over traefik. Looking forward to UDP support on this very great edge router :)

unrelated but can i see how you defined the entrypoints for multi-port containers like teamspeak? seems like traefik doesn't support multiple port definitions for a single entrypoint yet.

sirlatrom commented 4 years ago

seems like traefik doesn't support multiple port definitions for a single entrypoint yet.

How I interpret the docs, you can just define multiple routers for the same container/service.

Something like:

services:
  foobar:
    labels:
      traefik.http.routers.foo.rule: Host(`foo.example.com`)
      traefik.http.services.foo.loadbalancer.server.port: 8080
      traefik.http.routers.foo.service: foo
      traefik.http.routers.bar.rule: Host(`bar.example.com`)
      traefik.http.services.bar.loadbalancer.server.port: 9090
      traefik.http.routers.bar.service: bar
    ports:
      - ":8080" # foo
      - ":9090" # bar

but that is just speculation on my part as I haven't tried it out.

ldez commented 4 years ago

Take a look to the PR https://github.com/containous/traefik/pull/6172, this case is explained.

sharknoon commented 4 years ago

I would love to see UDP support. Currently I have a teamspeak voice-communication server and some parts of the application (filetransfer and serverquery) are running perfectly over TCP, while the main part, voice, needs UDP. This is sadly the one thing of my many docker containers, I cant route over traefik. Looking forward to UDP support on this very great edge router :)

unrelated but can i see how you defined the entrypoints for multi-port containers like teamspeak? seems like traefik doesn't support multiple port definitions for a single entrypoint yet.

Hi crameth, I have used multiple Entrypoints, one for each port.

traefik.yml

entryPoints:
  teamspeak-filetransfer:
    address: ":30033"
  teamspeak-serverquery:
    address: ":10011"

For every Entrypoint I do have one corresponding Router, which points to the Service. The Service-Address is just the container-name and the port inside the container.

_dynamicconf.yml

tcp:
  routers:
    teamspeak-filetransfer:
      entryPoints:
        - "teamspeak-filetransfer"
      rule: HostSNI(`*`)
      service: teamspeak-filetransfer@file

    teamspeak-serverquery:
      entryPoints:
        - "teamspeak-serverquery"
      rule: HostSNI(`*`)
      service: teamspeak-serverquery@file

  services:
    teamspeak-filetransfer:
      loadBalancer:
        servers:
          - address: "teamspeak:30033"

    teamspeak-serverquery:
      loadBalancer:
        servers:
          - address: "teamspeak:10011"

I hope I can help you with that 😃 Kind regards Sharknoon

ldez commented 4 years ago

Closed by #6172, #6327, #6348

SvenC56 commented 4 years ago

unrelated to the issue but: @Sharknoon did you already tried to make use of the UDP support? For me it's working but the TeamSpeak Server is getting far more package loss.

version: "3.7"

services:
  traefik:
    image: traefik
    container_name: traefik
    restart: always
    command:
      #- "--log.level=DEBUG"
      - --entrypoints.web.address=:80
      - --entrypoints.websecure.address=:443
      - --entrypoints.teamspeak.address=:9987/udp
      - --entrypoints.teamspeak_serverquery_raw.address=:10011
      - --entrypoints.teamspeak_serverquery_ssh.address=:10022
      - --entrypoints.teamspeak_filetransfer.address=:30033
      - --providers.docker
      - --api
      - "--certificatesresolvers.mytlschallenge.acme.tlschallenge=true"
      - "--certificatesresolvers.mytlschallenge.acme.email=redacted"
      - "--certificatesresolvers.mytlschallenge.acme.storage=/letsencrypt/acme.json"
    labels:
      # Dashboard
      - "traefik.http.routers.traefik.rule=Host(`redacted`)"
      - "traefik.http.routers.traefik.service=api@internal"
      - "traefik.http.routers.traefik.tls.certresolver=mytlschallenge"
      - "traefik.http.routers.traefik.entrypoints=websecure"
      - "traefik.http.routers.traefik.middlewares=authtraefik"
      - "traefik.http.middlewares.authtraefik.basicauth.users=admin:redacted"
      # global redirect to https
      - "traefik.http.routers.redirs.rule=hostregexp(`{host:.+}`)"
      - "traefik.http.routers.redirs.entrypoints=web"
      - "traefik.http.routers.redirs.middlewares=redirect-to-https"
      # middleware redirect
      - "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
    ports:
      - 80:80
      - 443:443
      - 9987:9987/udp
      - 10011:10011
      - 10022:10022
      - 30033:30033
    networks:
      - web
      - internal
    volumes:
      - "/home/user/traefik/acme.json:/letsencrypt/acme.json"
      - "/var/run/docker.sock:/var/run/docker.sock:ro"

  teamspeak:
    image: teamspeak
    container_name: teamspeak
    restart: always
    networks:
      internal:
        aliases:
          - teamspeak.docker.local
    volumes:
      - teamspeak:/var/ts3server
    environment:
      - TS3SERVER_LICENSE=accept
      - TS3SERVER_QUERY_PROTOCOLS=ssh,raw
      - TS3SERVER_DB_PLUGIN=ts3db_mariadb
      - TS3SERVER_DB_SQLCREATEPATH=create_mariadb
      - TS3SERVER_DB_HOST=teamspeakdb
      - TS3SERVER_DB_USER=root
      - "TS3SERVER_DB_PASSWORD=redacted"
      - TS3SERVER_DB_NAME=teamspeak
      - TS3SERVER_DB_WAITUNTILREADY=30
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=traefik_web"
      - "traefik.http.routers.teamspeak.rule=Host(`ts.redacted`)"
      - "traefik.http.routers.teamspeak.entrypoints=websecure"
      - "traefik.http.routers.teamspeak.tls.certresolver=mytlschallenge"
      # UDP
      - "traefik.udp.routers.teamspeak.entrypoints=teamspeak"
      # Filetransfer
      - "traefik.tcp.routers.teamspeak-filetransfer.entrypoints=teamspeak_filetransfer"
      - "traefik.tcp.routers.teamspeak-filetransfer.rule=HostSNI(`*`)"
      - "traefik.tcp.routers.teamspeak-filetransfer.service=teamspeak-filetransfer@docker"
      # RAW Query
      - "traefik.tcp.routers.teamspeak-serverquery-raw.entrypoints=teamspeak_serverquery_raw"
      - "traefik.tcp.routers.teamspeak-serverquery-raw.rule=HostSNI(`*`)"
      - "traefik.tcp.routers.teamspeak-serverquery-raw.service=teamspeak-serverquery-raw@docker"
      # SSH Query
      - "traefik.tcp.routers.teamspeak-serverquery-ssh.entrypoints=teamspeak_serverquery_ssh"
      - "traefik.tcp.routers.teamspeak-serverquery-ssh.rule=HostSNI(`*`)"
      - "traefik.tcp.routers.teamspeak-serverquery-ssh.service=teamspeak-serverquery-ssh@docker"
      # Services
      - "traefik.udp.services.teamspeak.loadbalancer.server.port=9987"
      - "traefik.tcp.services.teamspeak-filetransfer.loadbalancer.server.port=30033"
      - "traefik.tcp.services.teamspeak-serverquery-raw.loadBalancer.server.port=10011"
      - "traefik.tcp.services.teamspeak-serverquery-ssh.loadBalancer.server.port=10022"
    depends_on:
      - teamspeakdb

  teamspeakdb:
    image: mariadb
    container_name: teamspeakdb
    restart: always
    volumes:
      - teamspeakdb:/var/lib/mysql
    labels:
      - "traefik.enable=false"
    networks:
      - internal
    environment:
      - "MYSQL_ROOT_PASSWORD=redacted"
      - MYSQL_DATABASE=teamspeak

networks:
  web:
    external: true
  internal:
    external: false

volumes:
  teamspeak:

  teamspeakdb:
sharknoon commented 4 years ago

Hi @SvenC56, yes, I have tried it immediatly but I cant use it, because the voice of some people is chopped off and the packet loss is gigantic, unfortunately :(