Skip to content

feat: Resolve internal port to host ports - #101

Open
Johannes7k75 wants to merge 9 commits into
jittering:mainfrom
Johannes7k75:feature/internal-port-resolving
Open

feat: Resolve internal port to host ports#101
Johannes7k75 wants to merge 9 commits into
jittering:mainfrom
Johannes7k75:feature/internal-port-resolving

Conversation

@Johannes7k75

Copy link
Copy Markdown

Problem

When having multiple ports exposed traefik-kop can't auto resolve the label port to the host port.

Fix

This PR allow the user to directly tell traefik-kop what internal port should get resolved to an host port
using docker label kop.<svcType>.services.<svcName>.resolve-port=<port>

This looks first at container.HostConfig.PortBindings and after that at container.NetworkSettings.Ports
For both it matches the protocol (so that an tcp port doesnt get an udp port) and the port:

ports:
  - 5000:50/tcp
labels:
  - kop.tcp.services.nginx.resolve-port=50

wil resolve internal port 50 to host port 5000 (Also works with random port 0)

Also When the user does not want to use the special port assigment he can also use this:

labels:
 - kop.<svcType>.services.<svcName>.resolve-internal-ports = <true|false>
 - kop.resolve-internal-ports = <true|false>

or the new traefik-kop environemnt variable RESOLVE_INTERNAL_PORTS=<true|false>
to allow direct auto resolving of the internal port to the host port.

These 3 options use the vanilla
traefik.<svcType>.services.<svcName>.loadbalancer.server.port=<port> label
as the internal port then it resolves the port same as with resolve-port (HostConfig.PortBindings then NetworkSettings.Ports)

These options also have precedence

  1. kop.<svcType>.services.<svcName>.resolve-port=<port> label
  2. kop.<svcType>.services.<svcName>.resolve-internal-ports = <true|false> label
  3. kop.resolve-internal-ports = <true|false> label
  4. RESOLVE_INTERNAL_PORTS=<true|false> env var

When using the 3 labels the <svcName> should be the declared traefik service name. When no service label use Traefik generates the service name. So to make it a little easier i have it made so that if the router name and service name mismatch (Mostly when traefik autogenerated the service name) it falls back to the router name.

Tests

I added new tests for this new feature.

Other Fixes

When splitting the tcp and udp address into host and port. I implemented the net.SplitHostPort method. Because if this is not used There could be complications with ipv6 addresses as they have : in the ip. Before the host and port where just split on :.

@Johannes7k75

Copy link
Copy Markdown
Author

Completet docker-compose.yml for testing

services:
  traefik-kop:
    image: "ghcr.io/jittering/traefik-kop:latest"
    restart: unless-stopped
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - REDIS_ADDR=192.168.178.34:6379
      - BIND_IP=192.168.178.34
      #- DEBUG=1
      #- RESOLVE_INTERNAL_PORTS=true

  redis:
    image: redis:alpine
    ports:
      - 6379:6379

  nginx:
    image: nginx:latest
    container_name: traefik-kop-nginx
    ports:
      - 127.0.0.1:1000:10/udp
      - 127.0.0.1::80
      - 127.0.0.1:2222:22
      - 127.0.0.1:9000:90/udp
    labels:
      #- "kop.resolve-internal-ports=true"
      - "traefik.enable=true"
      - "traefik.http.routers.nginx.rule=Host(`localhost`)"
      - "traefik.http.services.nginx.loadbalancer.server.port=80"

      - "traefik.tcp.routers.nginx-tcp.rule=HostSNI(`localhost`)"
      - "traefik.tcp.routers.nginx-tcp.tls=true"
      - "traefik.tcp.routers.nginx-tcp.entrypoints=ssh"
      - "traefik.tcp.services.nginx-tcp.loadbalancer.server.port=22"

      - "traefik.udp.routers.nginx-udp.entrypoints=udp"
      - "traefik.udp.services.nginx-udp.loadbalancer.server.port=10"
      # - "kop.udp.services.nginx-udp.resolve-port=90"
      # - "kop.udp.services.nginx-udp.resolve-internal-ports=true"

  traefik:
    image: traefik:3.7
    ports:
      - 8080:8080
    command: |
        --api.insecure=true
        --api.dashboard=true
        --providers.redis.endpoints=192.168.178.34:6379
        --entrypoints.ssh.address=:2222/tcp
        --entrypoints.udp.address=:9000/udp

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant