Service Type NodePort
01 前提条件¶
查看 NodePort svc
root@hybirdnet-node1:~# kubectl get svc |grep NodePort
dempapp NodePort 10.109.78.218 <none> 80:32327/TCP 45h
wordpress NodePort 10.110.229.189 <none> 80:32047/TCP 41
02 Chain PREROUTING¶
对于node port类型的service来说,访问host的port就访问到了这个服务。所以从host网络角度来看,当host收到数据包的时候应该是进入host network namespace的PREROUTING chain中,我们查看这个chain:对于node port类型的service来说,访问host的port就访问到了这个服务。所以从host网络角度来看,当host收到数据包的时候应该是进入host network namespace的PREROUTING chain中,我们查看这个chain:
root@hybirdnet-node1:~# iptables -nL -t nat
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
cali-PREROUTING all -- 0.0.0.0/0 0.0.0.0/0 /* cali:6gwbT8clXdHdC1b1 */
KUBE-SERVICES all -- 0.0.0.0/0 0.0.0.0/0 /* kubernetes service portals */
03 Chain KUBE-SERVICES¶
查看KUBE-SERVICES这个target:
root@hybirdnet-node1:~# iptables -nL -t nat
Chain KUBE-SERVICES (2 references)
target prot opt source destination
RETURN all -- 127.0.0.0/8 0.0.0.0/0
KUBE-MARK-MASQ all -- !10.244.0.0/16 0.0.0.0/0 /* Kubernetes service cluster ip + port for masquerade purpose */ match-set KUBE-CLUSTER-IP dst,dst
KUBE-NODE-PORT all -- 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 match-set KUBE-CLUSTER-IP dst,dst
根据以前文章,在KUBE-SERVICES target,node port数据包不会匹配ipset KUBE-CLUSTER-IP。因为node port是host的ip地址和目标port,并不在ipset KUBE-CLUSTER-IP中,那么这样数据就进入了KUBE-NODE-PORT。
03 Chain KUBE-NODE-PORT¶
查看KUBE-NODE-PORT target:
root@hybirdnet-node1:~# iptables -nL -t nat
Chain KUBE-NODE-PORT (1 references)
target prot opt source destination
RETURN tcp -- 0.0.0.0/0 0.0.0.0/0 /* Kubernetes nodeport TCP port with externalTrafficPolicy=local */ match-set KUBE-NODE-PORT-LOCAL-TCP dst
KUBE-MARK-MASQ tcp -- 0.0.0.0/0 0.0.0.0/0 /* Kubernetes nodeport TCP port for masquerade purpose */ match-set KUBE-NODE-PORT-TCP dst
我们发现KUBE-NODE-PORT target来匹配KUBE-NODE-PORT-TCP这个ipset,然后进入到KUBE-MARK-MASQ这个target中,我们查看KUBE-NODE-PORT-TCP ipset。
04 ipset¶
查看KUBE-NODE-PORT-TCP ipset:
root@hybirdnet-node1:~# ipset list KUBE-NODE-PORT-TCP
Name: KUBE-NODE-PORT-TCP
Type: bitmap:port
Revision: 3
Header: range 0-65535
Size in memory: 8264
References: 1
Number of entries: 4
Members:
31253
31998
32047
32327
这里我们看到KUBE-NODE-PORT-TCP这个ipset里一共有3个entry,而且也匹配了集群中node port类型service的端口。我们继续查看KUBE-MARK-MASQ这个target。
05 Chain KUBE-MARK-MASQ¶
查看UBE-MARK-MASQ
root@hybirdnet-node1:~# iptables -nL -t nat
Chain KUBE-MARK-MASQ (3 references)
pkts bytes target prot opt in out source destination
0 0 MARK all -- * * 0.0.0.0/0 0.0.0.0/0 MARK or 0x4000
匹配KUBE-NODE-PORT-TCP这个ipset的items(也就是node port类型的service)会进入到KUBE-MARK-MASQ这个target中,这个target是对所有的items做了mark标记
06 ipvs¶
经过了PREROUTING chain以及相关的target之后数据会来到INPUT chain,这是因为数据包的目标ip地址为host的ip地址。对于k8s集群的ipvs负载均衡来说,其核心工作就是在INPUT chain,采用NAT模式(Virtual Server via NAT),linux操作系统网络内核会对目标ip来做转DNAT换,这里我们以测试svc dempapp 为例来观察
root@hybirdnet-node1:~# ipvsadm -Ln |grep 32327 -A 3
TCP 172.20.200.5:32327 rr
-> 10.244.48.9:80 Masq 1 1 21
TCP 10.96.0.1:443 rr
-> 172.20.200.4:6443 Masq 1 4 0
--
TCP 10.244.144.192:32327 rr
-> 10.244.48.9:80 Masq 1 0 0
UDP 10.96.0.10:53 rr
-> 10.244.31.1:53 Masq 1 0 0
Tpis:
1 原文链接:k8s集群网络(8)-service之ipvs node port实现原理-腾讯云开发者社区-腾讯云
2 K8S的1.24.0以上kube-proxy不监听nodeport端口问题: K8S的1.24.0以上kube-proxy不监听nodeport端口问题_nodeport端口无监听-CSDN博客
3 github FAQ: