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 有解释一下吗?如果上面描述有问题也请指出
nat 表中 KUBE-SERVICES
链的内容:
......
-A KUBE-SERVICES ! -s 10.244.0.0/16 -d 10.96.0.1/32 -p tcp -m comment --comment "default/kubernetes:https cluster IP" -m tcp --dport 443 -j KUBE-MARK-MASQ
-A KUBE-SERVICES -d 10.96.0.1/32 -p tcp -m comment --comment "default/kubernetes:https cluster IP" -m tcp --dport 443 -j KUBE-SVC-NPX46M4PTMTKRN6Y
......
KUBE-SVC-NPX46M4PTMTKRN6Y
链的内容:
-N KUBE-SVC-NPX46M4PTMTKRN6Y
-A KUBE-SVC-NPX46M4PTMTKRN6Y -m comment --comment "default/kubernetes:https" -j KUBE-SEP-CTNR2LSYMQN7HLKM
KUBE-SEP-CTNR2LSYMQN7HLKM
链的内容:
-N KUBE-SEP-CTNR2LSYMQN7HLKM
-A KUBE-SEP-CTNR2LSYMQN7HLKM -s 10.225.4.247/32 -m comment --comment "default/kubernetes:https" -j KUBE-MARK-MASQ
-A KUBE-SEP-CTNR2LSYMQN7HLKM -p tcp -m comment --comment "default/kubernetes:https" -m tcp -j DNAT --to-destination :0 --persistent --to-destination :0 --persistent --to-destination 0.0.0.0 --persistent
KUBE-MARK-MASQ
链的内容:
-N KUBE-MARK-MASQ
-A KUBE-MARK-MASQ -j MARK --set-xmark 0x4000/0x4000
1
tubaflute 2021-10-09 14:14:51 +08:00
hello,楼主把规则 写成 iptables -t nat -S 吧,这么看,确实有点眼花缭乱
|
2
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 ``` |
3
Nitroethane OP @tubaflute #1 已更新。你的这个 k8s 的版本是多少呢?因为我看一本书里讲的和你这个一样,但是书里用的版本比较旧
|
4
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 方的
|
5
Nitroethane OP @tubaflute 这个我知道。关键问题是我列出来的 DNAT 的那条规则很奇怪,跟你的完全不一样,从没见过 dnat 那样用的
|
6
tubaflute 2021-10-11 10:23:55 +08:00
@Nitroethane 会不会是你的网络插件的策略呢?我不懂 cilium,是不是 cilium 有修改网络策略的功能呢?
|
7
Nitroethane OP @tubaflute #6 应该不是 cilium 的问题。当时为了排除网络插件的原因,使用 flannel 也是这样的规则
|
8
Nitroethane OP @tubaflute 你部署 k8s 集群的内核版本是多少呢?我是安装的 elrepo 里 5.4 的内核
|