在Traefik Docker Swarm模式下,Nginx后面的真实IP是什么?

6

我在Docker Swarm环境中使用Traefik作为Nginx服务的反向代理。这是我的docker-stack.yml文件:

traefik:
    image: traefik
    command: -c /dev/null --web --docker --docker.swarmmode --docker.watch --docker.domain=domain --logLevel=DEBUG
    ports:
      - "8080:8080"
      - "80:80"
      - "443:443"
    networks:
       - app
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    deploy:
      placement:
        constraints: [node.role == manager]

nginx:
    image: nginx
    networks:
      - app
    deploy:
      labels:
        traefik.port: 80
        traefik.docker.network: app
        traefik.frontend.rule: "Host:app.domain"

所有都正常工作,但我需要在Nginx访问日志中获得真实的客户端IP,而不是得到类似10.0.1.37这样的东西。

我该如何获取真实的客户端IP?

谢谢,

1个回答

10

此问题已在GitHub #614上进行了讨论。

当上游服务接收到从Traefik转发的请求时,X-Forwarded-For标头包含来自叠加网络的IP地址,而不是实际客户端地址。

为了解决这个问题,您可以使用新的方式在docker-compose >=3.2(长语法)中声明服务端口

然后,您需要确保Traefik连接到主机网络并将发送正确的X-Forwarded-For标头(请参见下面的80端口:mode: host):

version: "3.2"
services:
  traefik:
    ...
    ports:
      - "8080:8080"
      - target: 80
        published: 80
        protocol: tcp
        mode: host
      - "443:443"
    ...

最后,您需要更改 http {} section 中的 nginx log_format。可以通过卷绑定 nginx.conf 配置文件来完成:

最后,您需要在 http {} section 中更改nginx的log_format。 可以通过将 nginx.conf 配置文件与卷绑定来完成:

nginx:
  ..
  volumes:
    - /data/nginx/nginx.conf:/etc/nginx/nginx.conf

使用以下内容可以得到nginx.conf文件:

http {
  ...
  log_format main '$http_x_forwarded_for - $remote_user [$time_local] '
  '"$request" $status $body_bytes_sent "$http_referer" '
  '"$http_user_agent"' ;

在 AWS ec2 上进行测试时,traefik_nginx 服务(我将其称为我的堆栈 traefik)的日志如下所示:

$ docker service logs -f traefik_nginx
...
traefik_nginx.1.qpxyjheql5uk@xxx    | 82.253.xxx.xxx - - [20/Jun/2017:08:46:51 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.104 Safari/537.36"

谢谢你的回答,现在可以工作了。我认为模式“host”会阻止Swarm路由机制:如果我的Swarm中有2个节点,那么只有1个节点实际上会暴露Traefik,对吗? - ninja_dev
我认为你是对的(没有检查过),但由于路由网格使用入口网络(我们通过使用“主机”网络绕过的覆盖网络),因此Traefik只应该在部署它的主机上公开。如果您测试了它,如果您能更新我,我会很高兴的。 - François Maturel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接