环境:
- kubernetes版本: 阿里云v1.11.5
- 节点系统 CentOS Linux 7 (Core)
- 节点容器版本 docker://17.6.2
概念介绍
X-Forwarded-For
1
X-Forwarded-For: <client>, <proxy1>, <proxy2>
remote_addr
remote_addr代表客户端的IP,但它的值不是由客户端提供的,而是服务端根据客户端的ip指定的,当你的浏览器访问某个网站时,假设中间没有任何代理,那么网站的web服务器(Nginx,Apache等)就会把remote_addr设为你的机器IP,如果你用了某个代理,那么你的浏览器会先访问这个代理,然后再由这个代理转发到网站,这样web服务器就会把remote_addr设为这台代理机器的IP。
内部请求(Pod对Pod请求)
1
podA-->podB
这时只有getRemoteAddr
能够获取IP,其余header全空.podB获得的clientIP为podA的podIP(虚拟IP)
The client_address is always the client pod’s IP address, whether the client pod and server pod are in the same node or in different nodes.
外部请求
Nodeport svc
1
client-->svc-->pod
externalTrafficPolicy: Cluster
svc.spec设置externalTrafficPolicy: Cluster
,意思是所有节点都会启动kube-proxy
,外部流量可能转发多1次.
1
2
3
4
5
6
7
8
9
client
\ ^
\ \
v \
node 1 <--- node 2
| ^ SNAT
| | --->
v |
endpoint
这时流量通过node2的转发,app 获得的clientIP不定,有可能是node 2
的IP,也有可能是客户端的IP
externalTrafficPolicy: Local
svc.spec设置externalTrafficPolicy: Local
,在运行pod的节点上启动kube-proxy
,外部流量直达节点.
1
2
3
4
5
6
7
8
9
client
^ / \
/ / \
/ v X
node 1 node 2
^ |
| |
| v
endpoint
这时,只有运行了pod的节点才会有对应的proxy,避免了中间商(node 2)挣差价
clientIP
为remote_addr
LoadBalancer svc
svc.spec设置externalTrafficPolicy: Local
.
1
2
3
4
5
6
7
8
9
client
|
lb VIP
/ ^
v /
health check ---> node 1 node 2 <--- health check
200 <--- ^ | ---> 500
| V
endpoint
SLB监听HTTP:取X-Forwarded-For
即可(从SLB获得客户端IP).
SLB监听TCP,则取remote_addr
externalTrafficPolicy: Cluster
的情况就不用说了,没有意义.
ingress
1
client-->slb-->ingress svc-->ingress pod-->app svc-->pod
首先需要设置ingress
的svc类型为Nodeport
/LoadBalancer
,并且externalTrafficPolicy: Local
app svc type为ClusterIP
/NodePort
/LoadBalancer
都无所谓.
这个时候,X-Forwarded-For
的值即为clientIP
remote_addr
为ingress pod
Virtual IP