前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >k8s集群网络(8)-service之ipvs node port实现原理

k8s集群网络(8)-service之ipvs node port实现原理

作者头像
TA码字
发布2020-04-01 15:18:39
2.8K0
发布2020-04-01 15:18:39
举报
文章被收录于专栏:TA码字TA码字

上一篇文章中我们介绍了基于ipvs的cluster ip类型service的实现原理,本质上是在iptable的PREROUTING chain以及相关target中利用ipset来匹配cluster ip,完成对即将做MASQUERADE伪装的items的mark标记,同时结合ipset也减少了iptable中的entry数量。另外在host network namespace里创建kube-ipvs0网络设备,绑定所有cluster ip,保证网络数据包可以进入INPUT chain。在INPUT chain中ipvs利用映射规则(可由ipvsadm查看该规则)完成对cluster ip的DNAT和目标pod endpoints选择的负载均衡,然后直接把数据送入POSTROUTING chain。当数据包进入POSTROUTING chain,经过相关的iptable target,匹配在PREROUTING chain中的mark标记,完成MASQUERADE伪装(SNAT host的ip地址)。最后数据包根据host network namespace的路由表做下一跳路由选择。在这里我们主要介绍基于ipvs的node port类型service的实现原理,如果对上一篇文章内容有所理解,那么这里也比较简单。

我们这里是介绍node port类型的service,所以我们基于以前文章里安装的应用,显示k8s集群中的node port service:

代码语言:javascript
复制
kubectl get service --all-namespaces

对于node port类型的service来说,访问host的port就访问到了这个服务。所以从host网络角度来看,当host收到数据包的时候应该是进入host network namespace的PREROUTING chain中,我们查看这个chain:

代码语言:javascript
复制
iptables -nL -t nat

查看KUBE-SERVICES这个target:

代码语言:javascript
复制
iptables -nL -t nat

根据以前文章,在KUBE-SERVICES target,node port数据包不会匹配ipset KUBE-CLUSTER-IP。因为node port是host的ip地址和目标port,并不在ipset KUBE-CLUSTER-IP中,那么这样数据就进入了KUBE-NODE-PORT。

查看KUBE-NODE-PORT target:

代码语言:javascript
复制
iptables -nL -t nat

我们发现KUBE-NODE-PORT target来匹配KUBE-NODE-PORT-TCP这个ipset,然后进入到KUBE-MARK-MASQ这个target中,我们查看KUBE-NODE-PORT-TCP ipset。

查看KUBE-NODE-PORT-TCP ipset:

代码语言:javascript
复制
kubectl get service --all-namespaces
ipset list KUBE-NODE-PORT-TCP

这里我们看到KUBE-NODE-PORT-TCP这个ipset里一共有3个entry,而且也匹配了集群中node port类型service的端口。我们继续查看KUBE-MARK-MASQ这个target。

查看KUBE-MARK-MASQ target:

代码语言:javascript
复制
iptables -nL -t nat

匹配KUBE-NODE-PORT-TCP这个ipset的items(也就是node port类型的service)会进入到KUBE-MARK-MASQ这个target中,这个target是对所有的items做了mark标记。

经过了PREROUTING chain以及相关的target之后数据会来到INPUT chain,这是因为数据包的目标ip地址为host的ip地址。对于k8s集群的ipvs负载均衡来说,其核心工作就是在INPUT chain,采用NAT模式(http://www.linuxvirtualserver.org/VS-NAT.html),linux操作系统网络内核会对目标ip来做转DNAT换。这里我们以service-kube-dashboard做为例子,它的node port为9092,cluster ip是10.254.32.107,我们查看ipvs如何做DNAT

代码语言:javascript
复制
kubectl describe service service-kube-dashboard --namespace kube-system
ipvsadm -L

我们看到service-kube-dashboard node port为9092,对应一个endpoint10.1.86.5:8443。然后通过ipvsadm工具查看确实是ipvs将host ip(172.20.11.43)的9092端口其映射成这个endpoint。

ipvs在INPUT chain完成上述DNAT操作,然后将数据送入POSTROUTING chain,我们查看这个chain。

代码语言:javascript
复制
iptables -nL -t nat

这里我们发现数据在POSTROUTING chain会进入KUBE-POSTROUTING这个target中。

查看KUBE-POSTROUTING target:

代码语言:javascript
复制
iptables -nL -t nat

这里我们发现是对数据包做了MASQUERADE伪装,并且匹配的就是在KUBE-MARK-MASQ target中做的标记,也就是用下一跳路由所使用网路设备的ip做了SNAT操作。所以到这里我们的数据包源ip为下一跳路由所使用网路设备的ip,目标ip为10.1.86.5,然后根据host network namespace的路由表做下一跳路由选择。

总结对于ipvs下的cluster ip的通讯方式为:

  • 数据包从host外部访问node port service的host端口,进入host的network namespace,源ip为外部 ip,源端口为随机端口,目标ip为host ip,目标port为node port。
  • 数据包在host network namespace中进入PREROUTING chain。
  • 在PREROUTING chain中经过匹配ipset KUBE-NODE-PORT-TCP做mask标记操作。
  • 因为数据包的目标ip是host的ip地址,所以进入host network namespace的INPUT chain中。
  • 数据在INPUT chain中被ipvs的内核规则修改(可由ipvsadm查看规则),完成负载均衡和DNAT,然后将数据直接送入POSTROUTING chain。这时源ip为外部ip,源端口为随机端口,目标ip为映射选择的pod ip,目标port为映射选择的port。
  • 数据在POSTROUTING chain中,经过KUBE-POSTROUTING target完成MASQUERADE SNAT。这时源ip为下一跳路由所使用网路设备的ip,源端口为随机端口,目标ip为映射选择的pod ip,目标port为映射选择的port。
  • 数据包根据host network namespace的路由表做下一跳路由选择。
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-01-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 TA码字 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
NAT 网关
NAT 网关(NAT Gateway)提供 IP 地址转换服务,为腾讯云内资源提供高性能的 Internet 访问服务。通过 NAT 网关,在腾讯云上的资源可以更安全的访问 Internet,保护私有网络信息不直接暴露公网;您也可以通过 NAT 网关实现海量的公网访问,最大支持1000万以上的并发连接数;NAT 网关还支持 IP 级流量管控,可实时查看流量数据,帮助您快速定位异常流量,排查网络故障。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档