Replacing HAProxy with Traefik: Health Checking w/ Data, One Router w/ Multiple Services

I'm currently using HAProxy to route requests from inside my kubernetes cluster to external servers.

Some of these upstream servers have health checks that parse the status code and body response returned...

Example HAProxy config:

          # Health check is a POST sent with JSON data
          http-check send meth POST uri /v3/"${MY_SECRET_ENV}" hdr Content-Type application/json body {\"jsonrpc\":\"2.0\",\"method\":\"eth_syncing\",\"params\":[],\"id\":99}
          # Status code 200 expected to be returned
          http-check expect status 200
          # Expected body response...
          http-check expect string {\"jsonrpc\":\"2.0\",\"id\":99,\"result\":false}

If the HTTP status is not 200 or the expected string is not returned, the upstream is considered unhealthy and requests are no longer sent there.

Does this functionality exist in Traefik?

Also, I'd like one router to balance between multiple services, but it seems that a router can only point to one service ... Some of my services require different middlewares due to their URIs containing auth or different paths.

Example:

        http:
          middlewares:
            worker-one-prefix:
              addPrefix:
                prefix: /v1
            worker-two-prefix:
              addPrefix:
                prefix: /v2
          routers:
            main:
              middlewares:
              - autodetect
              - worker-one-prefix # What is worker-two supposed to do here?
              entryPoints:
              - main
              rule: Host(`traefik.local`)
              service: one # main won't work here
          services:
            main:
              weighted:
                services:
                - name: one
                  weight: 200
                - name: two
                  weight: two
            one:
              loadBalancer:
                passHostHeader: false
                servers:
                # Worker One
                - url: https://worker-one.com
            two:
              loadBalancer:
                passHostHeader: false
                servers:
                # Worker Two
                - url: https://worker-two.com

Seems like this wouldn't work because the two services require two different middlewares, but the middlewares are applied to the router and not the service ... Am I missing anything?

Traefik will round-robin on target services, it’s an array, you can define multiple in file (doc):

## Dynamic configuration
http:
  services:
    my-service:
      loadBalancer:
        servers:
        - url: "http://private-ip-server-1/"
        - url: "http://private-ip-server-2/"

For health, you have multiple options:

  • Traefik will only forward to services that accept the connection, so are still listening
  • Traefik can do own healthcheck on targets (doc)
  • with Configuration Discovery and containers, it will only forward to healthy containers

Yes, but in your example, I can't use two different services that have different health checks or use different middleware...

In my use case, the URLs under a single service are actually different providers that require different healthchecks and different middlewares. I'd like to load balance between them.