组网完成后,路由器连接的子网 100.64.0.1/16 和 10.16.0.1/16 就可以完成通信了,同一子网的自然可以通信。
那么在看一下 k8s 的网络要求:
所有 POD 之间 无 NAT 直接访问
宿主机与 POD 之间无 NAT 直接访问
第一点前面已经可以满足!kube-ovn 的出网流量依然走宿主机 NAT 出去,集中式也就是出口流量导到某个宿主机,ovn 可以利用静态路由达到这点, 我们参看下静态路由
// ovn-nbctl lr-route-list ovn-cluster
IPv4 Routes
61.147.184.101 100.64.0.2 dst-ip
61.147.186.209 100.64.0.3 dst-ip
10.16.0.2 100.64.0.3 src-ip
10.16.0.3 100.64.0.2 src-ip
// 这里只显示了静态路由,实际上还有子网间的路由
10.16.0.0/16 10.16.0.1 dst-ip
100.64.0.0/16 100.64.0.1 dst-ip
复制代码
10.16.0.2 是容器的 IP 地址,100.64.0.3 是该容器所在物理机 61.147.186.209 ,在 switch join 里面得到的虚拟 IP 地址, 静态路由的匹配规则是 dst-ip 优先,所以当本地容器出访时,目的地址没有命中的路由,就会命中 10.16.0.2 这条源地址匹配的规则,将流量导到了对应宿主机上转发。
宿主机上有 NAT 的规则,出网
-A POSTROUTING -m set --match-set ovn40subnets-nat src -m set ! --match-set ovn40subnets dst -j MASQUERADE
-A POSTROUTING -m set --match-set ovn40local-pod-ip-nat src -m set ! --match-set ovn40subnets dst -j MASQUERADE
复制代码
回包时,在宿主机上,我们能看到对应路由表,经过次路由表数据到达虚拟路由器之后, 就可以转发进来了。
// 100.64.0.1 是 join 子网的网关地址
10.16.0.0/16 via 100.64.0.1 dev ovn0
复制代码
依据上面的数据出访过程,当访问非自己所在宿主机节点时,数据同样要 NAT 出去,这样就违背了第二条规则,宿主机同 POD 也要无 NAT 访问。所以在静态路由中添加了如下这种静态路由。
// 访问宿主机时,先路由到对应宿主机的虚拟网卡上,这样就不会经过NAT了
IPv4 Routes
61.147.184.101 100.64.0.2 dst-ip
61.147.186.209 100.64.0.3 dst-ip
复制代码
评论