Traefik Docker Swarm 模式背后的 Nginx 真实 ip [英] Nginx behind Traefik Docker Swarm mode real ip
问题描述
我在 docker swarm 环境中使用 Traefik 作为 nginx 服务前的反向代理.这是我的 docker-stack.yml:
I'm using Traefik as a reverse proxy in front of nginx service on a docker swarm environment. Here's my 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
Everything works fine but I need the real client IP in my Nginx access log, instead I get something like 10.0.1.37
如何获取真实的客户端ip?
How get I can the real client ip?
谢谢,
推荐答案
此问题已在 github 上讨论#614.
当上游服务收到从 Traefik 转发的请求时,X-Forwarded-For
标头包含来自覆盖网络的 IP 地址,而不是实际的客户端地址.
When the upstream service receives requests forwarded from Traefik, the
X-Forwarded-For
header contains an IP address from the overlay network, not the actual client address.
为了克服这个,你可以使用新的方式在docker中声明服务端口-撰写 >=3.2(长句法).
To overcome this, you can use the new way of declaring service ports in docker-compose >=3.2 (LONG SYNTAX).
然后确保 traefik 连接到主机网络,并将发送正确的 X-Forwarded-For
标头(参见下面的 mode: host
80 端口):
Then you ensure that traefik is attached to host network and will send the right X-Forwarded-For
header (see below mode: host
for the 80 port):
version: "3.2"
services:
traefik:
...
ports:
- "8080:8080"
- target: 80
published: 80
protocol: tcp
mode: host
- "443:443"
...
最后,您必须更改 http {} 部分
中的 nginx log_format.这可以通过 nginx.conf
配置文件的卷绑定来完成:
Finally, you have to change the nginx log_format in the http {} section
. That can be done through volume binding of a nginx.conf
configuration file:
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
)日志如下:
Tested on an AWS ec2, the traefik_nginx
service (I called my stack traefik
) logs like this:
$ 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"
这篇关于Traefik Docker Swarm 模式背后的 Nginx 真实 ip的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!