使用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: Service
apiVersion: v1
metadata:
name: nginx-service
spec:
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: DaemonSet
230d229
< 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 -f
172.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