Port based dynamic services possible?

Hi folks,

I’m investigating an upgrade of our port based HAProxy service routing to either linkerd or envoy.
Something like this works:

admin:
  port: 9990

namers:
  - kind: io.l5d.fs
    rootDir: /disco

routers:
  - label: service1
    protocol: http
    dtab: "/svc => /#/io.l5d.fs"
    identifier:
      kind: io.l5d.static
      path: /service1
    servers:
      - port: 3000
        ip: 0.0.0.0

  - label: service2
    protocol: http
    dtab: "/svc => /#/io.l5d.fs"
    identifier:
      kind: io.l5d.static
      path: /service2
    servers:
      - port: 4000
        ip: 0.0.0.0

Is there a way to add new services to this without a linkerd restart? Ideally we need to make our transition transparent and not all services respect HTTP_PROXY (hence replicating the port based routing). We currently use HAProxy + consul-template on every machine. Services connect to <docker_ip>:<service_port>.

Thanks in advance for any guidance you can give.

Actually, is there a way to use the requested port in the dtab or as an identifier?
Preallocating some spare ports would not be a problem.

There is no way to change which ports Linkerd is listening on without a restart. However, if you’re using the HTTP_PROXY variable, you should be able to have Linkerd listen on a single port and redirect all requests to that. You can then use a dtab to route traffic based on the request port in the host header.

Something like this:

routers:
  - protocol: http
    dtab: |
      /port/4000 => /#/io.l5d.fs/service2;
      /port/3000 => /#/io.l5d.fs/service1;
      /hostport/* => /port;
      /svc => /$/io.buoyant.hostportPfx/hostport; 
    servers:
      - port: 4140
        ip: 0.0.0.0

You could then use namerd or the fs interpreter to make the dtab dynamically updatable without a restart.

If http_proxy is not an option for you, you may be able to use iptables rules to direct these requests to Linkerd. Alex’s config (which routes on the port in the HTTP request itself, rather than e.g. the source port) should still work.

Aha, thanks Alex. By listening on all service ports and then some extra ones for future services we can use /$/io.buoyant.hostportPfx/hostport as per your example to map services in the dtab and use namerd to handle the updates.

Final config looks like:

admin:
  port: 9990

namers:
- kind: io.l5d.fs
  rootDir: /disco

routers:
- label: services
  protocol: http
  dtab: |
    /port/3002 => /#/io.l5d.fs/service2;
    /port/3000 => /#/io.l5d.fs/service1;
    /hostport/* => /port;
    /svc => /$/io.buoyant.hostportPfx/hostport;
  servers:
    - port: 3000
      ip: 0.0.0.0
    - port: 3002
      ip: 0.0.0.0

@Alex Thanks for the pointer.
@william Thanks; any idea if that needs to be inside each container or would iptables rules on the host work?

Setting iptables rules on the host should be enough.

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