V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Nitroethane
V2EX  ›  Kubernetes

k8s 中有关 service 的 iptables 的疑问

  •  
  •   Nitroethane · 2021-10-09 13:08:43 +08:00 · 1856 次点击
    这是一个创建于 1141 天前的主题,其中的信息可能已经有所发展或是发生改变。

    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 有解释一下吗?如果上面描述有问题也请指出

    第 1 条附言  ·  2021-10-09 14:20:41 +08:00

    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
    
    第 2 条附言  ·  2021-10-09 14:23:42 +08:00

    KUBE-MARK-MASQ 链的内容:

    -N KUBE-MARK-MASQ
    -A KUBE-MARK-MASQ -j MARK --set-xmark 0x4000/0x4000
    
    8 条回复    2021-10-11 16:37:24 +08:00
    tubaflute
        1
    tubaflute  
       2021-10-09 14:14:51 +08:00
    hello,楼主把规则 写成 iptables -t nat -S 吧,这么看,确实有点眼花缭乱
    tubaflute
        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
    ```
    Nitroethane
        3
    Nitroethane  
    OP
       2021-10-09 14:21:52 +08:00
    @tubaflute #1 已更新。你的这个 k8s 的版本是多少呢?因为我看一本书里讲的和你这个一样,但是书里用的版本比较旧
    tubaflute
        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 方的
    Nitroethane
        5
    Nitroethane  
    OP
       2021-10-09 16:57:25 +08:00 via iPhone
    @tubaflute 这个我知道。关键问题是我列出来的 DNAT 的那条规则很奇怪,跟你的完全不一样,从没见过 dnat 那样用的
    tubaflute
        6
    tubaflute  
       2021-10-11 10:23:55 +08:00
    @Nitroethane 会不会是你的网络插件的策略呢?我不懂 cilium,是不是 cilium 有修改网络策略的功能呢?
    Nitroethane
        7
    Nitroethane  
    OP
       2021-10-11 10:33:49 +08:00
    @tubaflute #6 应该不是 cilium 的问题。当时为了排除网络插件的原因,使用 flannel 也是这样的规则
    Nitroethane
        8
    Nitroethane  
    OP
       2021-10-11 16:37:24 +08:00 via iPhone
    @tubaflute 你部署 k8s 集群的内核版本是多少呢?我是安装的 elrepo 里 5.4 的内核
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1201 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 18:22 · PVG 02:22 · LAX 10:22 · JFK 13:22
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.