k8s 中有关 service 的 iptables 的疑问

2021-10-09 13:08:43 +08:00
 Nitroethane

k8s 版本:v1.19.14
网络插件:cilium

kubernetes 服务的 IP 为 10.96.0.1,对应后端 pod 的 IP 为 10.225.4.247。查看 nat 表中 KUBE-SERVICES 链的规则:

......
Chain KUBE-SERVICES (2 references)
 pkts bytes target     prot opt in     out     source               destination
    3   180 KUBE-MARK-MASQ  tcp  --  *      *      !10.244.0.0/16        10.96.0.1            /* default/kubernetes:https cluster IP */ tcp dpt:443
    3   180 KUBE-SVC-NPX46M4PTMTKRN6Y  tcp  --  *      *       0.0.0.0/0            10.96.0.1            /* default/kubernetes:https cluster IP */ tcp dpt:443
......

根据上面的规则,当使用 10.96.0.1 访问 api server 时, 根据第一条规则,数据包会跳到 KUBE-MARK-MASQ 做标记。由于用户自定义的链的默认策略是 RETURN,因此打完标记后数据包会返回到 KUBE-SERVICES 链中继续做处理,因此数据包会执行第二条规则,即跳转到 KUBE-SVC-NPX46M4PTMTKRN6Y 链。
查看 KUBE-SVC-NPX46M4PTMTKRN6Y 链的规则:

Chain KUBE-SVC-NPX46M4PTMTKRN6Y (1 references)
 pkts bytes target     prot opt in     out     source               destination
    4   240 KUBE-SEP-CTNR2LSYMQN7HLKM  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/kubernetes:https */

可知数据包继续跳转到 KUBE-SEP-CTNR2LSYMQN7HLK 链。
继续查看此链的规则:

    0     0 KUBE-MARK-MASQ  all  --  *      *       10.225.4.247         0.0.0.0/0            /* default/kubernetes:https */
    4   240 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/kubernetes:https */ tcp to::0 persistent:0 persistent0.0.0.0 persistent

第一条规则应该也是给数据包打标记,但是第二条 DNAT 的规则好奇怪,不理解是怎样把数据包转到后端 pod 里的。有懂的 v 有解释一下吗?如果上面描述有问题也请指出

1890 次点击
所在节点    Kubernetes
8 条回复
tubaflute
2021-10-09 14:14:51 +08:00
hello,楼主把规则 写成 iptables -t nat -S 吧,这么看,确实有点眼花缭乱
tubaflute
2021-10-09 14:17:28 +08:00
另外我这边看到的`KUBE-SEP-<HASH>`的规则,最后的 DNAT 是有明确的 pod 的 ip 和端口的
```shell
iptables -t nat -S KUBE-SEP-XWLQUYERTFMNWPFB
-N KUBE-SEP-XWLQUYERTFMNWPFB
-A KUBE-SEP-XWLQUYERTFMNWPFB -s 10.244.4.8/32 -m comment --comment "default/node-test-svc:http" -j KUBE-MARK-MASQ
-A KUBE-SEP-XWLQUYERTFMNWPFB -p tcp -m comment --comment "default/node-test-svc:http" -m tcp -j DNAT --to-destination 10.244.4.8:80
```
Nitroethane
2021-10-09 14:21:52 +08:00
@tubaflute #1 已更新。你的这个 k8s 的版本是多少呢?因为我看一本书里讲的和你这个一样,但是书里用的版本比较旧
tubaflute
2021-10-09 15:13:29 +08:00
@Nitroethane 我是这么理解的,不知道对不对,它通过 KUBE-SEP-<HASH>规则匹配肯定是能匹配到最后一条 -j DNAT --to-destination 10.244.4.8:80 这 rule 的,iptables 将数据包做了 DNAT(ip 换成 pod 的 ip 地址),然后它还是会从 POSTROUTING 出去吧(如果报文的源 ip 地址不是 pod ip 的网段的话)可以参考 POSTROUTING 的这条规则(-A POSTROUTING -s 10.244.0.0/18 -d 10.244.0.0/18 -j RETURN),应该是这个网络接口离开,由于宿主机上肯定有对应 pod ip 的路由表,因而数据包最终是会被送到 pod 方的
Nitroethane
2021-10-09 16:57:25 +08:00
@tubaflute 这个我知道。关键问题是我列出来的 DNAT 的那条规则很奇怪,跟你的完全不一样,从没见过 dnat 那样用的
tubaflute
2021-10-11 10:23:55 +08:00
@Nitroethane 会不会是你的网络插件的策略呢?我不懂 cilium,是不是 cilium 有修改网络策略的功能呢?
Nitroethane
2021-10-11 10:33:49 +08:00
@tubaflute #6 应该不是 cilium 的问题。当时为了排除网络插件的原因,使用 flannel 也是这样的规则
Nitroethane
2021-10-11 16:37:24 +08:00
@tubaflute 你部署 k8s 集群的内核版本是多少呢?我是安装的 elrepo 里 5.4 的内核

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/806653

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX