项目场景:
工作中遇到的这个问题,需要获取源地址ip,结果百度找到的基本都是给nginx.conf改配置像这样的:proxy_set_header X-Real-IP $remote_addr;等都试过,都不行。问题出在入口nginx那里获取到的ip就不对,10.244.0.0。
问题描述
入口nginx获取到的源地址ip不对,不管哪个ip访问显示的都是10.244.0.0,开发环境docker-compose部署的却能获取到真实ip地址,k8s部署的nginx就是不行。
我的nginx入口地址是:http://192.168.5.12:30080/login,我登录到192.168.5.3机器进行访问看看,得到的nginx日志如图所示
[root@test3 opt]# curl -i http://192.168.5.12:30080/login
结果得到的ip不是192.168.5.3,而是10.244.0.0
原因分析:
提示:这里填写问题的分析:
首先我的k8s集群有3台机器,分别是:
192.168.5.12 (master)
192.168.5.13 (node)
192.168.5.14 (node)
查看一下nginx在哪台node结点上
[root@test12 opt]#kubectl get pod -o wide|grep nginx
nginx-6435d5d554-ly78d 1/1 Running 0 3d1h 10.244.1.230 test13
那他网络是怎么走的呢?
1.首先192.168.5.3访问192.168.5.12
2.192.168.5.12通过flanel,kube-proxy将来自192.168.5.3的请求转发给192.168.5.13,192.168.5.14,所以我们能通过任意的node结点进行访问k8s集群服务例如这样,也是可以访问的:
[root@test3 opt]# curl -i http://192.168.5.13:30080/login
[root@test3 opt]# curl -i http://192.168.5.14:30080/login
3.但是这里,k8s会把源ip的数据包在转发过程中,伪装掉了源地址ip。所以我们最终看到的是10.244.0.0这样的ip
4.这个10.244.0.0到底是谁的ip呢,我们看一下
[root@test12 opt]# ip a|grep 10.244.0.0 -C 3
43: flannel.1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN group default
link/ether 9e:c6:73:5d:7d:07 brd ff:ff:ff:ff:ff:ff
inet 10.244.0.0/32 brd 10.244.0.0 scope global flannel.1
valid_lft forever preferred_lft forever
inet6 fe80::9cc6:73ff:fe5d:7d07/64 scope link
valid_lft forever preferred_lft forever
5.由此我们知道实际上就是flannel.1的ip
6.验证我们的猜想,进到192.168.5.13,看一下这台机器的falnnel.1的ip地址是多少
[root@test13 opt]# ip a|grep 10.244.0.0 -C 3
8: flannel.1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN group default
link/ether d6:1f:f9:cf:98:36 brd ff:ff:ff:ff:ff:ff
inet 10.244.1.0/32 brd 10.244.1.0 scope global flannel.1
valid_lft forever preferred_lft forever
inet6 fe80::d41f:f9ff:fecf:9836/64 scope link
valid_lft forever preferred_lft forever
7.在3机器上curl访问 5.13的30080端口,查看日志获取到的是不是10.244.1.0
[root@test3 opt]# curl -i http://192.168.5.13:30080/login
#进到5.12机器看nginx日志
[root@test12 opt]#tail -40f access.log
10.244.1.0 - - [08/Jul/2023:10:42:21 +0000] "POST /login HTTP/1.1" 200 91 "http://192.168.5.13:30080/login" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
10.244.1.0 - - [08/Jul/2023:10:42:21 +0000] "POST /login HTTP/1.1" 200 91 "http://192.168.5.13:30080/login" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
10.244.1.0 - - [08/Jul/2023:10:42:21 +0000] "POST /login" 200 91 "http://192.168.5.13:30080/login" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
10.244.1.0 - - [08/Jul/2023:10:42:21 +0000] "POST /login HTTP/1.1" 200 91 "http://192.168.5.13:30080/login" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
10.244.1.0 - - [08/Jul/2023:10:42:21 +0000] "POST /login HTTP/1.1" 200 91 "http://192.168.5.13:30080/login" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
10.244.1.0 - - [08/Jul/2023:10:42:21 +0000] "POST /login" 200 91 "http://192.168.5.13:30080/login" "Mozilla/5.0 (Macintosh; Int
8.由此验证我们的猜想正确,那么分析到原因是k8s网络转发导致的,如何解决呢。
解决方案:
1.允许pod可以调度到master节点(node-master更改为你的master节点主机名)
[root@test12 opt]# kubectl taint node node-master node-role.kubernetes.io/master-
2.将nginx绑定在master节点,修改deployment添加nodeselector
spec:
imagePullSecret:
- name: harborsecret
nodeSelector:
kubernetes.io/hostname: test12
containers:
- name: nginx
image: nginx:1.20.2
3.deoloyment添加 externalTrafficPolicy: Local,添加只会只能通过master节点访问了。若要通过每个节点都能访问,你可以考虑将nginx的资源类型改为daemonset类型,我这里不做演示
...
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
selector:
app: nginx
type: NodePort
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30080
externalTrafficPolicy: Local
4.以此deployment重启nginx
[root@test12 opt]#kubectl delete -f nginx-deployment.yaml
[root@test12 opt]#kubectl create -f nginx-deployment.yaml
5.验证:进入192.168.5.3节点,访问192.168.5.12首页
[root@test3 opt]# curl -i http://192.168.5.12:30080/login
6.查看nginx日志,不再是10.244.0.0而是真实的ip
[root@test12 opt]#tail -40f access.log
192.168.5.3 - - [08/Jul/2023:10:42:21 +0000] "POST /login HTTP/1.1" 200 91 "http://192.168.5.12:30080/login" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
到此就已经解决