【问题标题】:Nginx behind Traefik Docker Swarm mode real ipTraefik Docker Swarm 模式真实 ip 背后的 Nginx
【发布时间】:2017-06-19 21:04:45
【问题描述】:

我在 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?

谢谢,

【问题讨论】:

    标签: nginx docker docker-swarm docker-swarm-mode traefik


    【解决方案1】:

    这个问题在github #614讨论过。

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

    要克服这个问题,您可以使用declaring service ports in docker-compose >=3.2 (LONG SYNTAX) 的新方式。

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

    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 配置文件的卷绑定来完成:

    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"
    

    【讨论】:

    • 感谢您的回答,目前可以使用。我认为模式“主机”会阻止 Swarm 路由机制:如果我的 swarm 中有 2 个节点,那么实际上只有 1 个节点会暴露 traefik,对吗?
    • 我认为你是对的(没有检查它),但是由于路由网格使用入口网络(我们使用 host 网络绕过的覆盖网络),因此 traefik 应该只暴露在将其部署到的主机。如果你测试它,如果你能更新我,我会很高兴。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多