在Docker Swarm Mode中获得真实的客户IP

By | 2019/04/16

如果您曾经使用过 Docker Swarm Mode,一定会被它简单到爆炸的创建和操作方式些微震撼过,他还不能和K8s这么强力的工具对抗,但是对于一些小型的集群,这个自带的集群模式实在太有诱惑力了。

因为他自带了负载均衡等一系列功能,客户访问集群服务时,程序是无法获得用户的真实IP的(只能获得一系列的overlay网络ip),如果仅仅是做内部系统的微服务,那是一点问题都没有,但是如果直接提供API给外网访问,很多时候程序中获得客户端IP对于限流、日志都是有好处的。

如果您曾经研究过这个事情,一定看过docker的github上一些巨长的issue讨论,比如这个 https://github.com/moby/moby/issues/25526,历时数年,还没有可以close的迹象。

不过总是有一些围魏救赵的方法的,host模式是个可以借鉴的方法:

version: '3.4'
services:
nginx:
ports:
- mode: host
protocol: tcp
published: 80
target: 80
- mode: host
protocol: tcp
published: 443
target: 81

我们把nginx上对外绑定的端口使用host模式,这样相当于使用了真实的网卡,就可以把客户ip传递到后面的程序中去了。

如果使用了类似Traefik之类的网关,那么我们可以让Traefik连入host网络,如下:

version: "3.3"
services:
traefik:
image: traefik
command: --docker \
--docker.swarmMode \
--docker.watch
networks:
- traefik-net
ports:
- target: 80
published: 80
protocol: tcp
mode: host

这样我们就可以从 ‘X_REAL_IP’的Header中获取真实ip了,虽然略麻烦了一点,但总是可以用了。

期待docker可以提供更直观的方式来做这个事情

发表评论

您的电子邮箱地址不会被公开。