环境:
- 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