前言:我知道这并不理想,我正在从基于 Apache 的旧服务器迁移,现在需要在那里留下一些站点。
我想让 Traefik 将某些请求转发到另一台服务器,请考虑以下配置:
[file]
[frontends.attie]
backend = "attie"
[frontends.attie.routes._]
rule = "HostRegexp: {host:^(www\.)?attie.co.uk}"
[backends.attie.servers._]
url = "http://attie.co.uk:80"
在外部,DNS 指向此服务器attie.co.uk
。然后,Traefik 必须使用Host: attie.co.uk
标头将请求转发到旧服务器。
不幸的是,DNS 指向attie.co.uk
此服务器,我们最终陷入循环(当然)。
我已经在容器的/etc/hosts
中添加了条目,但这不起作用 - 我们仍然最终处于循环中(请参阅此要点中的日志),大概是因为 Traefik 正在自己进行名称解析并忽略主机文件。
我尝试使用该customRequestHeaders
无济于事 - 它出现在日志的配置 blob 中,但不起作用。
[frontends.attie.headers.customRequestHeaders]
Host = "attie.co.uk"
[backends.attie.servers._]
url = "http://10.42.0.4:80"
请注意此页面上的警告:
如果自定义标头名称与请求或响应的一个标头名称相同,则会替换它。
有什么方法可以做到其中之一吗?
- 配置名称解析以考虑
/etc/hosts
- 通过在
url
旁边提供 IP 来强制后端连接到主机 - 在 URL 中提供与 IP 配对的
Host:
标头
我已经对文档进行了相当广泛的研究,但可能遗漏了一些东西。
PS:我本以为这个问题更适合ServerFault或SuperUser,但是他们没有traefik标签,并且文档特别提到了StackOverflow。
如果您使用的是官方的 traefik 映像,那么此映像是从头开始构建的。最值得注意的是,没有/etc/nsswitch.conf
文件。在这种情况下,golang 实现了与 glibc 相同的回退机制,即忽略/etc/hosts
- 这正是您正在观察的问题。
配置中的重要一行是告诉解析程序首先查看本地/etc/hosts
文件,然后回退到 DNS 查询的行:
hosts: files dns
通过在容器中运行它创建的最小nsswitch.conf
文件将执行以下操作:
echo "hosts: files dns" > /etc/nsswitch.conf
但是,考虑到任何正常的主机系统上都存在适当的nsswitch.conf
文件,也许最简单的解决方案是在 docker 运行中添加额外的挂载。下面是来自 traefik docker hub repo 的改编示例:
docker run -d -p 8080:8080 -p 80:80
-v $PWD/traefik.toml:/etc/traefik/traefik.toml
-v /var/run/docker.sock:/var/run/docker.sock
-v /etc/nsswitch.conf:/etc/nsswitch.conf:ro
traefik
我相信如果你使用 docker compose 或其他东西,你可以适应它。完成此操作后,里面的/etc/hosts
文件应该可以按预期工作。(您可能通过 docker 运行标志修改--add-host
)
永久解决此问题的另一种方法是创建自己的Dockerfile
:
FROM traefik:v2.1
## Fix nssswitch not looking at hosts file (See https://github.com/containous/traefik/pull/6012)
RUN echo "hosts: files dns" > /etc/nsswitch.conf
我试图在 git 上提交更改,但官方图像似乎隐藏在某处。