Traefik 转发到主机并覆盖 IP



前言:我知道这并不理想,我正在从基于 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 上提交更改,但官方图像似乎隐藏在某处。

最新更新