V2 lb_policy testing

1. Caddy version (caddy version):

v2.1.1 h1:X9k1+ehZPYYrSqBvf/ocUgdLSRIuiNiMo7CvyGUQKeA=

2. How I run Caddy:

I have 3 folders that I have configured 3 different Caddy services to help me understand the load balancing policies.

Since I am on a Windows computer I have edited my hosts file to accommodate using multiple URIs.

Host file additions

127.0.0.1 t1.caddytest.com
127.0.0.1 t2.caddytest.com
127.0.0.1 t3.caddytest.com
127.0.0.1 one.caddytest.com
127.0.0.1 two.caddytest.com
127.0.0.1 three.caddytest.com

a. System environment:

Windows 10

b. Command:

caddy run

d. My complete Caddyfile or JSON config:

Load Balance Caddyfile

{
	admin off
}
http://*.caddytest.com:8000 {
        reverse_proxy localhost:8001 localhost:8002 {
		lb_policy header host
		health_path /healthcheck
	}
	log { 
		output stdout
		format console 
		level debug
	}
}

Server 1 Caddyfile

{
	admin off
}
http://:8001 {
	log { 
		output stdout
		format console 
		level info
	}
	respond /healthcheck 200
	respond 200 {
		body "From server on 8001"
		close
	}
}

Server 2 Caddyfile

{
	admin off
}
http://:8002 {
	log { 
		output stdout
		format console 
		level info
	}
	respond /healthcheck 200
	respond 200 {
		body "From server on 8002"
		close
	}
}

3. The problem I’m having:

I am attempting to determine the right load balance policy to use for my situation. The service I’m trying to balance needs the host to always go to a single server. I know I can do this with ip_hash, however that makes it difficult to verify the load balancing is working.

4. Error messages and/or full log output:

c:\caddy>curl http://t1.caddytest.com:8000
From server on 8001
c:\caddy>curl http://t1.caddytest.com:8000
From server on 8002
c:\caddy>curl http://t1.caddytest.com:8000
From server on 8001
c:\caddy>curl http://t1.caddytest.com:8000
From server on 8001
c:\caddy>curl http://t1.caddytest.com:8000
From server on 8001
c:\caddy>curl http://t1.caddytest.com:8000
From server on 8002
c:\caddy>curl http://t1.caddytest.com:8000
From server on 8002
c:\caddy>curl http://t1.caddytest.com:8000
From server on 8002
c:\caddy>curl http://t1.caddytest.com:8000
From server on 8002
c:\caddy>curl http://t1.caddytest.com:8000
From server on 8001

5. What I already tried:

I learned the uri_hash is only working with the point after the incoming. The service is using a subdomain to separate clients.

I have determined I will only be able to use one of two policies. header or ip_hash. The ip_hash policy works. I was considering using the header host however, that doesn’t appear to work.

If there was a host_hash, that would be exactly what I need for this situation.

Is there a way to properly configure the header policy to use the host header?

6. Links to relevant resources:

That’s an interesting usecase.

I think we can probably make lb_policy header Host work.

Host is implemented slightly differently because HTTP2 doesn’t use the Host header but instead a special :authority header instead, so the Go stdlib strips Host from the headers map and puts it on the request struct itself.

We’ll just need to add a little workaround for that specific header (we’ve done so in other places in the codebase so there’s precedent for it, it just wasn’t considered for load balancing).

I’ll write up a quick PR for this and link it here soon so you can give it a shot.

Okay, here it is.

https://github.com/caddyserver/caddy/pull/3653

To try it out, you can download the windows CI artifact from here (if it’s not there yet, the CI job might still be running - give it a couple minutes):

https://github.com/caddyserver/caddy/actions/runs/207590333

Note that you need to use Host with the uppercase H :smile:

1 Like

Thank you.
I will be able to focus on this again in a few hours.

Tracy

Thank you,
I have been able to do a test in the environment I built to present my question. This looks to be working as expected.

Tracy

2 Likes

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