Kubernetes ingress-nginx之後端Pod獲取客戶端真實IP

轉載自:https://www.codetd.com/article/1948828


使用externalTrafficPolicy: Local保留報文的源地址:

1.1 nodePort類型

kubernetes將在Pod所在Node上針對nodePort下發DNAT規則,而在其他節點上針對nodePort下發DROP規則。


        client
       ^ /   \
      / /     \
     / v       X
   node 1     node 2
    ^ |
    | |
    | v
 endpoint


以下使用nginx的例子。 

在svc的編排文件中增加externalTrafficPolicy後,重新創建nginx-service。 

kind: ServiceapiVersion: v1metadata:
  name: nginx-servicespec:
  type: NodePort
  externalTrafficPolicy: Local
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30080
  selector:
    component: nginx

externalTrafficPolicy的好處是,Pod內應用的確可以拿到真實的客戶端地址了,但壞處是: 客戶端只能使用pod所在的node的IP訪問,無法使用其他node的ip訪問以及使用vrrp之類的virtual IP來實現ha,對客戶端來說會麻煩一點。 

設置 service.spec.externalTrafficPolicy 的值爲 Local,請求就只會被代理到本地 endpoints 而不會被轉發到其它節點。這樣就保留了最初的源 IP 地址。

1.2如果使用ingress NodePort方式,並以DaemonSet方式安裝nginx-ingress-controller,可以實現客戶端從任何節點都可以訪問,並可獲取到客戶端的真實IP:

經過修改後的ingress:https://github.com/4220182/k8s/tree/master/ingress-nginx/0.15.0/daemonset

跟原版比較,改動比較少的:


$ diff ./ingress-nginx/0.15.0/deployment/mandatory.yaml ./ingress-nginx/0.15.0/daemonset/mandatory.yaml 225c225
< kind: Deployment
---> kind: DaemonSet230d229
<   replicas: 1
$ diff ./deployment/service-nodeport.yaml ./daemonset/service-nodeport.yaml 8d7>   externalTrafficPolicy: Local

測試樣例:https://github.com/4220182/k8s/tree/master/example/nginx

                client  
           ^ /          ^ \ 
          / /            \ \ 
         / v              \ v    
node 1 service-NodePort     node 2 serviceNodePort  
     ^ |                    ^ |
     | |                    | |
     | v                    | v
node1 ingress-controller  node2 ingress-controller 
    ^  \                  /  ^    
     \  \                /  /   
      \  \              /  /  
       \  v            v  /          
             endpoint

測試結果:

$ ab -n 100 -c 1  http://my.test.com/
$ kubectl logs po/nginx-5d758c4f46-p5r2j -f172.30.23.0 - - [06/Jul/2018:15:30:35 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.54.0" "192.168.5.101"172.30.23.0 - - [06/Jul/2018:15:33:20 +0000] "GET / HTTP/1.1" 200 612 "-" "ApacheBench/2.3" "192.168.5.101"172.30.23.0 - - [06/Jul/2018:15:33:20 +0000] "GET / HTTP/1.1" 200 612 "-" "ApacheBench/2.3" "192.168.5.101"172.30.23.0 - - [06/Jul/2018:15:33:20 +0000] "GET / HTTP/1.1" 200 612 "-" "ApacheBench/2.3" "192.168.5.101"...

可以看到,nginx的日誌($http_x_forwarded_for)已經記錄了客戶端的真實IP(192.168.5.101); 

2. LoadBalancer 類型 : 

參考 https://kubernetes.io/cn/docs/tutorials/services/source-ip/


ingress-nginx 安裝:https://blog.csdn.net/kozazyh/article/details/80580196


其他參考:

https://kubernetes.io/cn/docs/tutorials/services/source-ip/

https://kubernetes.io/docs/tutorials/services/source-ip/

https://ieevee.com/tech/2017/09/18/k8s-svc-src.html

https://blog.csdn.net/mailjoin/article/details/79686979

通過request獲取真實客戶端ip:http://wei5201.iteye.com/blog/735165


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章