我最近发现,您可以根据请求主机头dynamic匹配后端,如下所示:
use_backend %[req.hdr(host),lower]
然而,有没有人知道我可以使用请求hostheader的子域来匹配后端?
例如这样的话:
backend one backend two use_backend %[<SUBDOMAIN OF HOSTHEADER>,lower]
这将匹配像这样:
one.example.com -> backend one two.example.com -> backend two
通过添加和删除DNS条目,您可以将子域直接路由到各个后端,但是仍然需要定义这些后端,以便重新启动服务。 因此,我不完全确定这个configuration的有用性。
无论如何,这是你如何做的。
我们知道我们可以通过使用req.hdr ( req.hdr(host) )findhost头的内容,但是这给了我们请求的FQDN,而不是子域。
值得庆幸的是,还有一个regsub转换器,我们应该可以应用req.hdr示例来裁剪基本域和TLD。
regsub(<正则expression式>,<SUBST> [,<标记>])
将基于正则expression式的replace应用于inputstring。 它也是这样
用“s / <regex> / <subst> /”作为众所周知的“sed”工具运行。 通过
默认情况下它会在inputstring中replace第一个出现的
最大的部分与正则expression式<regex>匹配
string<subst>。 可以通过添加replace所有的事件
第三个参数<flags>中的标志“g”。 这也是可能的
通过在<flags>中添加标志“i”,正则expression式不区分大小写。 由于<flags>是一个
string,它由所有需要的标志连接组成。 因此,如果
“i”和“g”都是希望的,使用“gi”或“ig”将具有相同的效果。
重要的是要注意,由于目前的局限性
configurationparsing器,一些字符,如右括号或逗号
在参数中是不可能的。 这个转换器的第一个用途是
用其他字符replace某些字符或字符序列。
这个引用的重点是我的,目的是要显示在这种情况下,你需要的正则expression式是^(.*)(?:\..*){2}$ ,它不会工作,因为插入语。
因此,您需要使用字段转换器。
字段(<索引> <定界符>)
从给定的分隔符处提取给定索引处的子串
一个inputstring。 索引从1开始,分隔符是格式化的string
字符列表。
field(1,'.')
如果我们把整个样本pipe道放在一起,那么use_backend行看起来像:
use_backend BE:subs-%[req.hdr(host),lower,field(1,'.')]
现在,这打开了一个事实,即one.*.*会去到相同的后端,并可能导致一些非常奇怪的情况。
检查基本域名和顶级域名(TLD)以确保它们符合您的期望可能是有道理的。 假设你只有两个( example.com和foo.com ),你可以使用req.hdr_end(host)来检查它们,使得ACL如下所示:
acl is_valid_base_domain req.hdr_end(host) -i example.com foo.com
如果我们把它放在一起,整个configuration看起来就像这样:
frontend FE:subs ... acl is_valid_base_domain req.hdr_end(host) -i example.com foo.com use_backend BE:subs-%[req.hdr(host),lower,field(1,'.')] if is_valid_base_domain default_backend BE:subs:default backend BE:subs-one #matches one.example.com, one.foo.com ... backend BE:subs-two #matches two.example.com, two.foo.com ... backend BE:subs-three #matches three.example.com, three.foo.com ... backend BE:subs:default #matches *.example.com, *.foo.com ...
如果您希望通过为每个基本域的每个子域设置不同的“dynamic”后端,您甚至可以更加有趣; 你只需要使用上面的部分来解决这个问题。
据我所知,HAProxy没有正则expression式支持从Host头中提取子域的特定部分,然后将该值分配给一个variables,后者用于形成完整的后端名称。
但是,你解决你的问题的一种方法是使用映射:
frontend frontend_main ... use_backend %[req.hdr(host),lower,map(/etc/haproxy/subdomains.map,backend_main)]
/etc/haproxy/subdomains.map的内容如下所示:
#domainname backendname one.example.com backend_one two.example.com backend_two etc.domain1.com backend_etc
所有不匹配该文件中任何子域的请求都将转到backend_main后端。