zoukankan      html  css  js  c++  java
  • k8s中service 的iptables

    首先调整kubeproxy 的模式为iptables

    kubectl edit configmap kube-proxy -n kube-system
    修改

    kind: KubeProxyConfiguration
    metricsBindAddress: 127.0.0.1:10249
    mode: "ipvs"                          ##### 修改这一行留空则为iptables
    nodePortAddresses: null
    

    然后杀掉kubeproxy的pod ,让deployment 自动拉起来新配置pod

    输出kubeproxy的pod 日志,看是否采用了iptables
    kubectl logs kube-proxy-xxx -n kube-system

    已经修改模式为iptables了。

    目前集群已有svc

    NAMESPACE              NAME                        TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                   AGE
    default                go-web-service              NodePort    10.96.97.253    <none>        3009:30009/TCP            20d
    kube-system            kube-dns                    ClusterIP   10.96.0.10      <none>        53/UDP,53/TCP,9153/TCP    72d
    

    观察启动go-web-service这条的iptables 脉络

    [root@ebs-76642 ~]# iptables -t nat -L KUBE-SERVICES |egrep 'go-web-service'
    target     prot opt source               destination
    KUBE-MARK-MASQ  tcp  -- !ebs-76642/16         ebs-76642            /* default/go-web-service:http cluster IP */ tcp dpt:pxc-ntfy
    KUBE-SVC-KG4IN6CR36NHNLPD  tcp  --  anywhere             ebs-76642            /* default/go-web-service:http cluster IP */ tcp dpt:pxc-ntfy
    
    [root@ebs-76642 ~]# iptables -t nat -L KUBE-SVC-KG4IN6CR36NHNLPD
    Chain KUBE-SVC-KG4IN6CR36NHNLPD (2 references)
    target     prot opt source               destination
    KUBE-SEP-TKPLZBGAW27QFDLO  all  --  anywhere             anywhere             statistic mode random probability 0.50000000000
    KUBE-SEP-LEFZ7V5H5GEG5L4O  all  --  anywhere             anywhere
    
    [root@ebs-76642 ~]# iptables -t nat -L KUBE-SEP-TKPLZBGAW27QFDLO
    Chain KUBE-SEP-TKPLZBGAW27QFDLO (1 references)
    target     prot opt source               destination
    KUBE-MARK-MASQ  all  --  172.16.1.43          anywhere
    DNAT       tcp  --  anywhere             anywhere             tcp to:172.16.1.43:3009
    
    [root@ebs-76642 ~]# k get pods -A -o wide|grep '172.16.1.43'
    default                go-web-app-68797989b8-2vctz                 1/1     Running   3          20d   172.16.1.43      ebs-82413   <none>           <none>
    
    

    观察kube-dns这条iptables 脉络,这里暴露了三个ports(dns-tcp,dns,metrics)

    [root@ebs-76642 ~]# iptables -t nat -L KUBE-SERVICES |egrep 'kube-dns'
    KUBE-MARK-MASQ  tcp  -- !ebs-76642/16         ebs-76642            /* kube-system/kube-dns:dns-tcp cluster IP */ tcp dpt:domain
    KUBE-SVC-ERIFXISQEP7F7OF4  tcp  --  anywhere             ebs-76642            /* kube-system/kube-dns:dns-tcp cluster IP */ tcp dpt:domain
    KUBE-MARK-MASQ  udp  -- !ebs-76642/16         ebs-76642            /* kube-system/kube-dns:dns cluster IP */ udp dpt:domain
    KUBE-SVC-TCOU7JCQXEZGVUNU  udp  --  anywhere             ebs-76642            /* kube-system/kube-dns:dns cluster IP */ udp dpt:domain
    KUBE-MARK-MASQ  tcp  -- !ebs-76642/16         ebs-76642            /* kube-system/kube-dns:metrics cluster IP */ tcp dpt:9153
    KUBE-SVC-JD5MR3NA4I4DYORP  tcp  --  anywhere             ebs-76642            /* kube-system/kube-dns:metrics cluster IP */ tcp dpt:9153
    
    - 先看ports name为dns-tcp 这个的
    [root@ebs-76642 ~]# iptables -t nat -L KUBE-SVC-ERIFXISQEP7F7OF4
    Chain KUBE-SVC-ERIFXISQEP7F7OF4 (1 references)
    target     prot opt source               destination
    KUBE-SEP-7LK5TTMYU3GPSJJW  all  --  anywhere             anywhere             statistic mode random probability 0.50000000000
    KUBE-SEP-3NE7D5ZQGKE4MF2Z  all  --  anywhere             anywhere
    
    - 对应dns-tcp后端的两个pods
    [root@ebs-76642 ~]# iptables -t nat -L KUBE-SEP-7LK5TTMYU3GPSJJW
    Chain KUBE-SEP-7LK5TTMYU3GPSJJW (1 references)
    target     prot opt source               destination
    KUBE-MARK-MASQ  all  --  172.16.0.15          anywhere
    DNAT       tcp  --  anywhere             anywhere             tcp to:172.16.0.15:53
    [root@ebs-76642 ~]# iptables -t nat -L KUBE-SEP-3NE7D5ZQGKE4MF2Z
    Chain KUBE-SEP-3NE7D5ZQGKE4MF2Z (1 references)
    target     prot opt source               destination
    KUBE-MARK-MASQ  all  --  172.16.1.44          anywhere
    DNAT       tcp  --  anywhere             anywhere             tcp to:172.16.1.44:53
    

    对于iptable方式的service:

    流量从pod network namespace(cluster ip类型的service)或者外部(node port类型的service)进入到host netwok namespace之中。

    在host netwok namespace的PREROUTING chain中会经过一系列target,KUBE-SERVICES(cluster ip类型的service),KUBE-NODEPORTS (node port类型的service),KUBE-SVC-XXX,KUBE-SEP-XXX。

    在这些target里根据iptable内核随机模块random来实现匹配endpoint target,实现负载均衡。

    在endpoint target(KUBE-SEP-XXX)里实现了DNAT,也就是将目标地址cluster ip转化为实际的pod的ip。

    数据包经过以上修改根据host network namespace的路由表做下一跳路由选择。

    对于ipvs方式的service:

    流量从pod network namespace(cluster ip类型的service)或者外部(node port类型的service)进入到host netwok namespace之中。

    对于clutser ip类型的service,在host netwok namespace的PREROUTING chain中经过匹配ipset KUBE-CLUSTER-IP做mask标记操作。

    对于node port类型的service,在PREROUTING chain中经过匹配ipset KUBE-NODE-PORT-TCP做mask标记操作。

    对于clutser ip类型的service,由于host network namespace中有创建网络设备kube-ipvs0,并且绑定所有cluster ip,这样从pod发出的数据包目标ip为cluster ip,有kube-ipvs0网络设备对应,数据进入INPUT chain中。

    对于node port类型的service,由于数据包的目标ip是host的ip地址,所以也进入了host network namespace的INPUT chain中。

    利用linux内核模块ipvs,数据在INPUT chain中被ipvs的规则修改(可由ipvsadm查看规则),完成负载均衡和DNAT,然后将数据直接送入POSTROUTING chain。

    数据在POSTROUTING chain中,经过KUBE-POSTROUTING target,根据之前的mark操作完成MASQUERADE SNAT。

    数据包经过以上修改根据host network namespace的路由表做下一跳路由选择。

    对于iptable和ipvs方式的service:

    两者都是采用linux内核模块完成负载均衡和endpoint的映射,所有操作都在内核空间完成,没有在应用程序的用户空间。

    iptable方式依赖于linux netfilter/iptable内核模块。

    ipvs方式依赖linux netfilter/iptable模块,ipset模块,ipvs模块。

    iptable方式中,host宿主中ipatble的entry数目会随着service和对应endpoints的数目增多而增多。举个例子,比如有10个cluster ip类型的service,每个service有6个endpoints。那么在KUBE-SERVICES target中至少有10个entries(KUBE-SVC-XXX)与10个service对应,每个KUBE-SVC-XXX target中会有6个KUBE-SEP-XXX与6个endpoints来对应,每个KUBE-SEP-XXX会有2个enrties来分别做mark masq和DNAT,这样算起来至少有1062=120个entries在iptable中。试想如果application中service和endpoints数目巨大,iptable entries也是非常庞大的,在一定情况下有可能带来性能上的问题。

    ipvs方式中host宿主中iptable的entry数目是固定的,因为iptable做匹配的时候会利用ipset(KUBE-CLUSTER-IP或者KUBE-NODE-PORT-TCP)来匹配,service的数目决定了ipset的大小,并不会影响iptable的大小。这样就解决了iptable模式下,entries随着service和endpoints的增多而增多的问题。

    对于负载均衡,iptable方式采用random模块来完成负载均衡,ipvs方式支持多种负载均衡,例如round-robin,least connection,source hash等(可参考http://www.linuxvirtualserver.org/),并且由kubelet启动参数--ipvs-scheduler控制。

    对于目标地址的映射,iptable方式采用linux原生的DNAT,ipvs方式则利用ipvs模块完成。

    ipvs方式会在host netwok namespace中创建网络设备kube-ipvs0,并且绑定了所有的cluster ip,这样保证了cluster-ip类型的service数据进入INPUT chain,从而让ipvs来完成负载均衡和目标地址的映射。

    iptable方式不会在host netwok namespace中创建额外的网络设备。

    iptable方式数据在host network namespace的chain中的路径是:PREROUTING-->FORWARDING-->POSTROUTING

    在PREROUTING chain中完成负载均衡,mark masq和目标地址映射。

    ipvs方式数据在host network namespace的chain中的路径是:

    PREROUTING-->INPUT-->POSTROUTING

    在PREROUTING chain中完成mark masq SNAT,在INPUT chain利用ipvs完成负载均衡和目标地址映射。

    iptable和ipvs方式在完成负载均衡和目标地址映射后都会根据host network namespace的路由表做下一跳路由选择。

    关于iptable和ipvs方式的选择并没有固定答案,要根据项目的需求和实际情况而定。

    iptables nat表中的详细过程

    [root@docker3 ~]#  iptables -nL -t nat -v
    Chain PREROUTING (policy ACCEPT 2 packets, 1152 bytes)
    pkts bytes target     prot opt in     out     source               destination        
    10837 3999K KUBE-SERVICES  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* kubernetes service portals */
    ====》1. 进入的请求,首先匹配PREROUTING 链里的该规则,并进入KUBE-SERVICES链
      238 27286 DOCKER     all  --  *      *       0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCAL
     
    Chain INPUT (policy ACCEPT 2 packets, 1152 bytes)
    pkts bytes target     prot opt in     out     source               destination        
     
    Chain OUTPUT (policy ACCEPT 8 packets, 480 bytes)
    pkts bytes target     prot opt in     out     source               destination        
    61563 3722K KUBE-SERVICES  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* kubernetes service portals */
        0     0 DOCKER     all  --  *      *       0.0.0.0/0           !127.0.0.0/8          ADDRTYPE match dst-type LOCAL
     
    Chain POSTROUTING (policy ACCEPT 8 packets, 480 bytes)
    pkts bytes target     prot opt in     out     source               destination        
    61840 3742K KUBE-POSTROUTING  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* kubernetes postrouting rules */
    ====》6. 需要路由到另一个主机的连接经由POSTROUTING该规则,进入KUBE-POSTROUTING 链
       62  4323 MASQUERADE  all  --  *      !docker0  10.2.39.0/24         0.0.0.0/0          
        0     0 MASQUERADE  all  --  *      !docker0  10.1.33.0/24         0.0.0.0/0          
     
    Chain DOCKER (2 references)
    pkts bytes target     prot opt in     out     source               destination        
        0     0 RETURN     all  --  docker0 *       0.0.0.0/0            0.0.0.0/0          
     
    Chain KUBE-MARK-DROP (0 references)
    pkts bytes target     prot opt in     out     source               destination        
        0     0 MARK       all  --  *      *       0.0.0.0/0            0.0.0.0/0            MARK or 0x8000
     
    Chain KUBE-MARK-MASQ (6 references)
    pkts bytes target     prot opt in     out     source               destination        
        2   128 MARK       all  --  *      *       0.0.0.0/0            0.0.0.0/0            MARK or 0x4000
     
    Chain KUBE-NODEPORTS (1 references)
    pkts bytes target     prot opt in     out     source               destination        
        2   128 KUBE-MARK-MASQ  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/k8s-nginx: */ tcp dpt:30780
        2   128 KUBE-SVC-2RMP45C4XWDG5BGC  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/k8s-nginx: */ tcp dpt:30780
        ====》3.请求命中上述两个规则,一个进行进入KUBE-MARK-MASQ 链进行标记,一个进入KUBE-SVC-2RMP45C4XWDG5BGC链
     
    Chain KUBE-POSTROUTING (1 references)
    pkts bytes target     prot opt in     out     source               destination        
        1    64 MASQUERADE  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* kubernetes service traffic requiring SNAT */ mark match 0x4000/0x4000
        ====》7. 执行源地址转换(在flannel网络这里转换的地址是flannel.1即flannel在ifconfig里输出接口的地址),发往另一个node
     
    Chain KUBE-SEP-D5T62RWZFFOCR77Q (1 references)
    pkts bytes target     prot opt in     out     source               destination        
        0     0 KUBE-MARK-MASQ  all  --  *      *       10.2.39.3            0.0.0.0/0            /* default/k8s-nginx: */
        1    64 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/k8s-nginx: */ tcp to:10.2.39.3:80
        ====》5-2. DNAT到本机,交给INPUT
     
    Chain KUBE-SEP-IK3IYR4STYKRJP77 (1 references)
    pkts bytes target     prot opt in     out     source               destination        
        0     0 KUBE-MARK-MASQ  all  --  *      *       10.2.39.2            0.0.0.0/0            /* kube-system/kube-dns:dns-tcp */
        0     0 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            /* kube-system/kube-dns:dns-tcp */ tcp to:10.2.39.2:53
     
    Chain KUBE-SEP-WV6S37CDULKCYEVE (1 references)
    pkts bytes target     prot opt in     out     source               destination        
        0     0 KUBE-MARK-MASQ  all  --  *      *       10.2.39.2            0.0.0.0/0            /* kube-system/kube-dns:dns */
        0     0 DNAT       udp  --  *      *       0.0.0.0/0            0.0.0.0/0            /* kube-system/kube-dns:dns */ udp to:10.2.39.2:53
     
    Chain KUBE-SEP-X7YOSBI66WAQ7F6X (2 references)
    pkts bytes target     prot opt in     out     source               destination        
        0     0 KUBE-MARK-MASQ  all  --  *      *       172.16.199.17        0.0.0.0/0            /* default/kubernetes:https */
        0     0 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/kubernetes:https */ recent: SET name: KUBE-SEP-X7YOSBI66WAQ7F6X side: source mask: 255.255.255.255 tcp to:172.16.199.17:6443
     
    Chain KUBE-SEP-YXWG4KEJCDIRMCO5 (1 references)
    pkts bytes target     prot opt in     out     source               destination        
        0     0 KUBE-MARK-MASQ  all  --  *      *       10.2.4.2             0.0.0.0/0            /* default/k8s-nginx: */
        1    64 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/k8s-nginx: */ tcp to:10.2.4.2:80
        ====》5-1. DNAT到另一个node,随后执行postrouting
     
    Chain KUBE-SERVICES (2 references)
    pkts bytes target     prot opt in     out     source               destination        
        0     0 KUBE-SVC-2RMP45C4XWDG5BGC  tcp  --  *      *       0.0.0.0/0            169.169.148.143      /* default/k8s-nginx: cluster IP */ tcp dpt:80
        0     0 KUBE-SVC-NPX46M4PTMTKRN6Y  tcp  --  *      *       0.0.0.0/0            169.169.0.1          /* default/kubernetes:https cluster IP */ tcp dpt:443
        0     0 KUBE-SVC-TCOU7JCQXEZGVUNU  udp  --  *      *       0.0.0.0/0            169.169.0.53         /* kube-system/kube-dns:dns cluster IP */ udp dpt:53
        0     0 KUBE-SVC-ERIFXISQEP7F7OF4  tcp  --  *      *       0.0.0.0/0            169.169.0.53         /* kube-system/kube-dns:dns-tcp cluster IP */ tcp dpt:53
        2   128 KUBE-NODEPORTS  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* kubernetes service nodeports; NOTE: this must be the last rule in this chain */ ADDRTYPE match dst-type LOCAL
        ====》2.连接随后并该规则匹配,进入KUBE-NODEPORTS 链
     
    Chain KUBE-SVC-2RMP45C4XWDG5BGC (2 references)
    pkts bytes target     prot opt in     out     source               destination        
        1    64 KUBE-SEP-D5T62RWZFFOCR77Q  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/k8s-nginx: */ statistic mode random probability 0.50000000000
        1    64 KUBE-SEP-YXWG4KEJCDIRMCO5  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/k8s-nginx: */
    ====》4.请求被该链中两个规则匹配,这里只有两个规则,按照50% RR规则进行负载均衡分发,两个目标链都是进行DNAT,一个转到本node的pod IP上,一个转到另一台宿主机的pod上,因为该service下只有两个pod
    ==========》乱入的广告,www.myf5.net《==================
    Chain KUBE-SVC-ERIFXISQEP7F7OF4 (1 references)
    pkts bytes target     prot opt in     out     source               destination        
        0     0 KUBE-SEP-IK3IYR4STYKRJP77  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* kube-system/kube-dns:dns-tcp */
     
    Chain KUBE-SVC-NPX46M4PTMTKRN6Y (1 references)
    pkts bytes target     prot opt in     out     source               destination        
        0     0 KUBE-SEP-X7YOSBI66WAQ7F6X  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/kubernetes:https */ recent: CHECK seconds: 10800 reap name: KUBE-SEP-X7YOSBI66WAQ7F6X side: source mask: 255.255.255.255
        0     0 KUBE-SEP-X7YOSBI66WAQ7F6X  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* default/kubernetes:https */
     
    Chain KUBE-SVC-TCOU7JCQXEZGVUNU (1 references)
    pkts bytes target     prot opt in     out     source               destination        
        0     0 KUBE-SEP-WV6S37CDULKCYEVE  all  --  *      *       0.0.0.0/0            0.0.0.0/0            /* kube-system/kube-dns:dns */
    
  • 相关阅读:
    CAP
    plugins for ST3 to frontend
    OAuth 2.0 详解
    Git SSH生成
    Android FrameWork 学习之Android 系统源码调试
    node.js安装步骤
    数据结构-- 队列 循环与顺序
    jsp之认识 servlet (基础、工作原理、容器请求处理)
    android 蓝牙开发---与蓝牙模块进行通讯 基于eclipse项目
    Android 仿微信调用第三方应用导航(百度,高德、腾讯)
  • 原文地址:https://www.cnblogs.com/plefan/p/14966487.html
Copyright © 2011-2022 走看看