Traefik 转发到主机并覆盖 IP

Traefik forwarding to a host and overriding IP

前言:我明白这并不理想,我正在从旧的 Apache-based 服务器迁移,现在需要在那里留下一些站点。

我想让 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 header.

将请求转发到旧服务器

不幸的是,DNS 将 attie.co.uk 指向 这个 服务器,我们最终陷入循环(当然)。

我已经在容器的 /etc/hosts 中添加了条目,但这不起作用 - 我们仍然陷入循环 (see the log in this gist),大概是因为 Traefik 自己进行名称解析并且忽略主机文件。


我尝试使用 customRequestHeaders 无济于事 - 它出现在日志的配置 blob 中,但不起作用。

[frontends.attie.headers.customRequestHeaders]
Host = "attie.co.uk"

[backends.attie.servers._]
url = "http://10.42.0.4:80"

注意 this 页面上的警告:

If the custom header name is the same as one header name of the request or response, it will be replaced.


有什么方法可以做到其中之一吗?

我对 documentation 进行了相当广泛的了解,但可能遗漏了一些内容。


PS:我原以为这个问题更适合 ServerFault 或 SuperUser,但他们没有 标签,而且文档特别提到了 Whosebug。

如果您使用的是官方 traefik 图像,则此图像是从头开始构建的。最值得注意的是,不存在 /etc/nsswitch.conf 文件。在这种情况下,golang implemented the same fallback mechanism as 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 文件应该可以像预期的那样工作。 (您可能通过 --add-host docker 运行 标志修改)

另一种永久解决此问题的方法是创建您自己的 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 上 submit the change,但官方图片似乎隐藏在某处。