k8s的ipvs模式下,访问一次NodePort的过程
一个外部客户端的请求, 访问nodeport流程:pod ip --> 192.168.97.10nodeport --> 10.246.198.17:30080clientip --> 10.242.72.50ipset:-m set --match-set KUBE-LOOP-BACK dst,dst,src表示匹配目的地址,目的端口,源地址与KUBE-LOOP-BACK中所
一个外部客户端的请求, 访问nodeport流程:
pod ip --> 192.168.97.10
nodeport --> 10.246.198.17:30080
clientip --> 10.242.72.50
ipset:
-m set --match-set KUBE-LOOP-BACK dst,dst,src
表示匹配目的地址,目的端口,源地址与KUBE-LOOP-BACK中所存储的数据相匹配的条目
比如要匹配 目的地址192.168.97.5, 目的tcp端口9153, 源地址192.168.97.5
KUBE-CLUSTER-IP
Name: KUBE-CLUSTER-IP
Type: hash:ip,port
Members:
192.168.96.3,tcp:9153
192.168.96.1,tcp:443
192.168.96.165,tcp:80
192.168.96.3,tcp:53
192.168.96.69,tcp:80
192.168.96.3,udp:53
192.168.96.126,tcp:80
KUBE-LOOP-BACK
Name: KUBE-LOOP-BACK
Type: hash:ip,port,ip
Members:
192.168.97.5,tcp:9153,192.168.97.5
192.168.97.5,udp:53,192.168.97.5
192.168.97.5,tcp:53,192.168.97.5
数据包: 源地址
| src | dst |
|10.242.72.50|10.246.198.17:30080|
先进入到了PREROUTING链—>
-A PREROUTING -m comment --comment "kubernetes service portals" -j KUBE-SERVICES
// -A KUBE-SERVICES ! -s 192.168.97.0/24 -m comment --comment "Kubernetes service cluster ip + port for masquerade purpose" -m set --match-set KUBE-CLUSTER-IP dst,dst -j KUBE-MARK-MASQ
-A KUBE-SERVICES -m addrtype --dst-type LOCAL -j KUBE-NODE-PORT # 匹配这一条
-A KUBE-NODE-PORT -p tcp -m comment --comment "Kubernetes nodeport TCP port for masquerade purpose" -m set --match-set KUBE-NODE-PORT-TCP dst -j KUBE-MARK-MASQ
-A KUBE-MARK-MASQ -j MARK --set-xmark 0x4000/0x4000 // 打上标签
-A KUBE-SERVICES -m set --match-set KUBE-CLUSTER-IP dst,dst -j ACCEPT // 放行
进入INPUT链–>
在这里会被ipvs规则处理:
TCP 10.246.198.17:30080 rr
-> 192.168.97.10:80 Masq 1 0 0
此时数据报的目的地址会变成 192.168.97.10:80,并且会被发送到POSTROUTING
目标地址转换
| src | dst |
|10.242.72.50|192.168.97.10:80|
POSTROUTING链–>
-A POSTROUTING -m comment --comment “kubernetes postrouting rules” -j KUBE-POSTROUTING
-A KUBE-POSTROUTING -m comment --comment “Kubernetes endpoints dst ip:port, source ip for solving hairpin purpose” -m set --match-set KUBE-LOOP-BACK dst,dst,src -j MASQUERADE
-A KUBE-POSTROUTING -m mark ! --mark 0x4000/0x4000 -j RETURN // 对于没有 0x4000/0x4000标记的包 RETURN, 客户端访问的数据包在PREROUTING处已打上了标记
-A KUBE-POSTROUTING -j MARK --set-xmark 0x4000/0x0 // 打上标记
-A KUBE-POSTROUTING -m comment --comment “kubernetes service traffic requiring SNAT” -j MASQUERADE --random-fully //进行源地址转换
–random-fully 端口选择策略,可以通过更加随机的方式选择端口,降低冲突率。
进行地址伪装时,由于网段是192.168.87.0/24 , 所以更具路由,数据包会从tunl0网卡发出, 所以 源地址会被修改为当前主机的 tunl0网卡的地址 192.168.97.1
源地址转换
| src | dst |
|192.168.97.1|192.168.97.10:80|
可以在容器内抓包-->
07:17:21.061555 IP 192.168.97.1.29138 > 192.168.97.10.80: Flags [S], seq 2217615960, win 64240, options [mss 1460,sackOK,TS val 3264197292 ecr 0,nop,wscale 7], length 0
...
此时请求数据包到达了容器内的应用程序:
处理:
回复报文:
容器有独立的名称空间,容器会将报文直接发送给192.168.97.1
| src | dst |
|192.168.97.10:80|192.168.97.1|
real server发送回到 virtual server主机之后, 会更具conntrack 表中的记录将源地址和目标地址才一次转换
| src | dst |
|10.246.198.17:30080|10.240.72.50|
到此, 一次完整的nodeport访问就完成了
更多推荐
所有评论(0)