zoukankan      html  css  js  c++  java
  • k8s爬坑集锦[网络问题]-服务无法访问

    一,前情提要:

    集群中有3个节点(1个master, 2个node),部署的业务服务为NodePort类型,通过nodeip:port访问业务的时候发现,一个nodeIP不通,另外两个不通

    HOST_1=192.168.86.188  --master
    HOST_2=192.168.86.189
    HOST_3=192.168.86.190

    188上查看:---NOK
    #  curl http://192.168.86.188:30038/targets   

    189, 190上查看:---OK
    # curl http://192.168.86.189:30038/targets   ---ok
     
    二,定位过程
    0. 业务的pod和服务信息,业务pod实际的调度节点为host189, pod/容器IP为10.244.2.6
    # kubectl get svc  -nprometheus
    NAME                    TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)             AGE
    prometheus              ClusterIP   10.96.167.153    <none>        9090/TCP            138m
    prometheus-nodeport     NodePort    10.109.216.20    <none>        9090:30038/TCP      138m      ---服务ip地址
    
    
    # kubectl get pods  -nprometheus -owide
    NAME                                    READY   STATUS      RESTARTS   AGE    IP               NODE      NOMINATED NODE
    prometheus-0                            2/2     Running     0          143m   10.244.2.6       host189   <none>   
     
    1.查看各节点中iptables中的规则
    1)host188上,即问题节点上
    [root@host188 ~]## iptables -t nat -L KUBE-NODEPORTS
    KUBE-MARK-MASQ  tcp  --  anywhere             anywhere                         /* prometheus/prometheus-nodeport:http */ tcp dpt:30038
    KUBE-SVC-SO4PW3GA7SPS7IHM  tcp  --  anywhere  anywhere                          /* prometheus/prometheus-nodeport:http  */ tcp dpt:30038
    
    Chain KUBE-SVC-SO4PW3GA7SPS7IHM (2 references)
    target     prot opt source               destination         
    KUBE-SEP-5GEH5OENN4FETTOQ  all  --  anywhere             anywhere  
    
    Chain KUBE-SEP-5GEH5OENN4FETTOQ (1 references)
    target     prot opt source               destination         
    KUBE-MARK-MASQ  all  --  10.244.2.6           anywhere            
    DNAT       tcp  --  anywhere             anywhere             tcp to:10.244.2.6:9090

     【解析】: 如果目的地址是30038的,则首先,打上做MASQ的mark, 然后进行MASQ即将其进行目的地址转化,即交给SVC链(代表集群level的服务)

              然后,SVC链会做分流,然后选择一个SEP链(代表一个enpoint),在这里就是交给唯一的pod,地址正是10.244.2.6:9090

              最后,进入路由表进行路由匹配

    附: # iptables -t nat -S 和 #iptables -t nat -L

    二者还是有区别的,前者信息能更完整一些,所以推荐二者结合使用

    2. 路由方面的追踪

    [root@host188 ~]# route -n      ----问题节点上的路由表
    Kernel IP routing table
    Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
    0.0.0.0         192.168.86.1    0.0.0.0         UG    0      0        0 ens160
    10.244.0.0      0.0.0.0         255.255.255.0   U     0      0        0 cni0
    10.244.1.0      10.244.1.0      255.255.255.0   UG    0      0        0 flannel.1   ###去往宿主机是190上的路由,ok的
    169.254.0.0     0.0.0.0         255.255.0.0     U     1002   0        0 ens160
    172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
    192.168.86.0    0.0.0.0         255.255.255.0   U     0      0        0 ens160
    [root@host190 ~]# route -n       ----标准节点上的路由表
    Kernel IP routing table
    Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
    0.0.0.0         192.168.86.1    0.0.0.0         UG    0      0        0 ens160
    10.244.0.0      10.244.0.0      255.255.255.0   UG    0      0        0 flannel.1   ###去往宿主机188上的pods的网段路由
    10.244.1.0      0.0.0.0         255.255.255.0   U     0      0        0 cni0
    10.244.2.0      10.244.2.0      255.255.255.0   UG    0      0        0 flannel.1   ###去往189宿主机上pods的网段路由
    10.244.57.0     0.0.0.0         255.255.255.192 U     0      0        0 *
    169.254.0.0     0.0.0.0         255.255.0.0     U     1002   0        0 ens160
    172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
    192.168.86.0    0.0.0.0         255.255.255.0   U     0      0        0 ens160

    【解析】:可以看到188上的路由表中没有2.0网段的路由,即去190节点上的pod的路由,而目标pod正好是部署在了190节点上。那么路由是谁来添加的?

             根据k8s的网络原理(flannel)知道,k8s为集群中的每个节点分配一个子网段,然后记录在etcd中,flannel通过读取etcd的信息(不一定是直接读取,可能是借助api server)得到各个其他节点上分配的子网段信息,  然后向路由表中添加路由信息: 能够到达其他pod的路由信息。由此我们知道,出现问题可能有两个方向:  1)etcd信息损毁;   2)flannel添加路由失败。

    wxy碎碎念:

    实际上在开始查看路由表的时候,188节点上,使用ip route命令是没有该网段信息,而用route -n命令是可以看到2.0信息,但是其Iface对应的值是*,并不是应该的flannel.1

    然后删除这条路由失败,提示NO Process...,但后来发现是掩码不对,之后我们会说

     3. 检查etcd的信息

    HOST_1=192.168.86.188
    HOST_2=192.168.86.189
    HOST_3=192.168.86.190
    
    ENDPOINTS=$HOST_1:2379,$HOST_2:2379,$HOST_3:2379
    
    TLS_CERT=" --cacert=/etc/etcd/pki/ca.pem --cert=/etc/etcd/pki/client.pem --key=/etc/etcd/pki/client-key.pem"
    
    #  docker exec etcd /bin/sh -c "export ETCDCTL_API=3 && etcdctl --endpoints=$ENDPOINTS $TLS_CERT get /registry/minions/linuxtest1a7a"
    /registry/minions/host189
    结果:  
    ...以下信息为flannel的子网段信息和对应的public ip(host的地址)...
    "flannel.alpha.coreos.com/public-ip 
                                       192.168.86.189bB
    10.244.2.0/24 ¿!
    ....

      【解析】: 查看了所有节点的信息,发现子网段以及对应的public ip都是存在且正确的,所以说明问题不在etcd身上。(wxy:因为重启过etcd,  所以实际上一直担心是他的问题,这下稍稍放心了)

    4. flannel方面的问题

    1) 首先,检查下路由表关于flannel接口方面的信息,如下是查看interface的邻居,这些都是通过arp来发现的

    [root@host188 ~]## ip neigh show dev flannel.1   ###问题节点上,只发现了190一个neighbor
    10.244.1.0 lladdr 76:50:75:23:dd:f8 PERMANENT    
    
    [root@host189 ~]# ip neigh show dev flannel.1     ###ok节点1: 有发现两个neighbor
    10.244.1.0 lladdr 76:50:75:23:dd:f8 PERMANENT
    10.244.0.0 lladdr 5a:d6:46:ab:ea:17 PERMANENT
    
    [root@host188 net.d]# bridge fdb show flannel.1   ###问题节点上的,转发表信息
    01:00:5e:00:00:01 dev ens160 self permanent
    01:00:5e:00:00:01 dev docker0 self permanent
    b6:88:ae:4a:ac:42 dev docker0 vlan 1 master docker0 permanent
    76:50:75:23:dd:f8 dev flannel.1 dst 192.168.86.190 self permanent  ------------
    [root@host190 ~]#  ip neigh show dev flannel.1     ###ok节点2: 也有发现两个neighbor
    10.244.2.0 lladdr 92:e7:b6:4e:e5:73 PERMANENT
    10.244.0.0 lladdr 5a:d6:46:ab:ea:17 PERMANENT

       【解析】: 这其实是再一次印证了路由缺失的问题,因为如上是arp信息,正是因为路由的不存在,导致了对应的neighbor的缺失,所以还是要看看flannel的问题

    2) 然后,flannel插件的检查,发现其运行日志有报出路由添加失败,至此直接原因找到

    # kubectl logs -f -nkube-system kube-flannel-ds-fvj6h
    I1028 01:59:01.891322       1 main.go:475] Determining IP address of default interface   ----会有删除操作?
    I1028 01:59:01.891599       1 main.go:488] Using interface with name ens160 and address 192.168.86.188
    I1028 01:59:01.891622       1 main.go:505] Defaulting external address to interface address (192.168.86.188)
    I1028 01:59:01.996901       1 kube.go:131] Waiting 10m0s for node controller to sync
    I1028 01:59:01.996901       1 kube.go:294] Starting kube subnet manager
    I1028 01:59:02.997083       1 kube.go:138] Node controller sync successful
    I1028 01:59:02.997115       1 main.go:235] Created subnet manager: Kubernetes Subnet Manager - host188
    I1028 01:59:02.997131       1 main.go:238] Installing signal handlers
    I1028 01:59:02.997229       1 main.go:353] Found network config - Backend type: vxlan
    I1028 01:59:02.997297       1 vxlan.go:120] VXLAN config: VNI=1 Port=0 GBP=false DirectRouting=false
    I1028 01:59:02.997619       1 main.go:300] Wrote subnet file to /run/flannel/subnet.env
    I1028 01:59:02.997630       1 main.go:304] Running backend.
    I1028 01:59:02.997636       1 main.go:322] Waiting for all goroutines to exit
    I1028 01:59:02.997650       1 vxlan_network.go:60] watching for new subnet leases
    E1028 01:59:02.997781       1 vxlan_network.go:158] failed to add vxlanRoute (10.244.2.0/24 -> 10.244.2.0): invalid argument   ###关键:flannel报出路由添加失败

     3)进一步的,为为了验证flannel对路由的影响,我修改了DaemonSet,添加了亲和性,让问题节点188上不能被调度flannel,如下

    修改DaemonSet的亲和性, 让这个节点不启动flannel进程,查看路由信息是否会删除
    spec:
      revisionHistoryLimit: 10
      selector:
        matchLabels:
          app: flannel
          tier: node
      template:
        metadata:
          creationTimestamp: null
          labels:
            app: flannel
            tier: node
        spec:
          affinity:
            nodeAffinity:
              requiredDuringSchedulingIgnoredDuringExecution:
                nodeSelectorTerms:
                - matchExpressions:
                  - key: kubernetes.io/hostname
                    operator: NotIn
                    values:
                    - host188
    # kubectl logs -f -nkube-system kube-flannel-ds-fvj6h
    ...
    I1028 01:59:02.997650       1 vxlan_network.go:60] watching for new subnet leases
    E1028 01:59:02.997781       1 vxlan_network.go:158] failed to add vxlanRoute (10.244.2.0/24 -> 10.244.2.0): invalid argument
    I1028 05:31:48.554667       1 main.go:337] shutdownHandler sent cancel signal...
    E1028 05:31:48.554782       1 vxlan_network.go:183] DelARP failed: no such file or directory
    E1028 05:31:48.554812       1 vxlan_network.go:187] DelFDB failed: no such file or directory
    E1028 05:31:48.554835       1 vxlan_network.go:191] failed to delete vxlanRoute (10.244.2.0/24 -> 10.244.2.0): no such process

     【解析】:  也就是说,flannel在销毁的时候,是会尝试销毁相关的路由条目,但是为什么会删除失败呢,而且还是no such process,很明显这是内核报出的错误

                      而flannel程序本身不可能有问题,肯定是内核此时的状态,不允许flannel删除,为什么呢?在仔细看了下路由表,发现路由表中该条路由的掩码并不是24位,

                      这是哪里的进程残留下来的路由条目么?其实此时就有了蛛丝马迹,是由残留存在了...

                     再结合网络上的一些博客有提到:flannel报出 invalid argument,有可能是和接口地址冲突了,   再加上此时的这条残留,突然觉得是不是忽略了什么

    附: 删除路由操作

    # route -n
    Kernel IP routing table
    Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
    ..10.244.2.0      0.0.0.0         255.255.255.192 U     0      0        0 *    ----就是你
    
    
    手动删除:
    ip route del 10.244.2.0/24    --not ok
    
    # ip route del 10.244.2.0/255.255.255.192    --ok,删除成功
    # route -n
    Kernel IP routing table
    Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
    0.0.0.0         192.168.86.1    0.0.0.0         UG    0      0        0 ens160
    10.244.0.0      0.0.0.0         255.255.255.0   U     0      0        0 cni0
    169.254.0.0     0.0.0.0         255.255.0.0     U     1002   0        0 ens160
    172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
    192.168.86.0    0.0.0.0         255.255.255.0   U     0      0        0 ens160

     4) 接口信息全面检查

    # ifconfig -a   ###注意要有个参数a, 才能发现这条信息,查看了别的设备,虽然也有这个接口,但是网段都是非冲突的,如下
    [root@host188 etc]# ifconfig -a
    ....
    tunl0: flags=128<NOARP>  mtu 1440
            inet 10.244.2.0  netmask 255.255.255.255   ###这个网段,刚好是当前集群网络中使用的,所以导致发生了冲突
            tunnel   txqueuelen 1000  (IPIP Tunnel)
            RX packets 9552860  bytes 9661438904 (8.9 GiB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 10309373  bytes 2978060504 (2.7 GiB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    
    [root@host189 ~]# ifconfig -a
    ...
    tunl0: flags=128<NOARP>  mtu 1440
            inet 10.244.188.0  netmask 255.255.255.255
            tunnel   txqueuelen 1000  (IPIP Tunnel)
            RX packets 11031772  bytes 8680651091 (8.0 GiB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 10557451  bytes 9723264443 (9.0 GiB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    
    
    [root@host190 ~]# ifconfig -a
    ...
    tunl0: flags=128<NOARP>  mtu 1440
            inet 10.244.57.0  netmask 255.255.255.255
            tunnel   txqueuelen 1000  (IPIP Tunnel)
            RX packets 720412  bytes 48975635 (46.7 MiB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 701770  bytes 5701518725 (5.3 GiB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

    【解析】: 经过和ll确认,IPIP Tunnel是k8s 1.18版本中,calico类型的网络中使用的,并不是当前的,而这个测试环境会经常k8s 1.18切换安装,所以有了这样的残留。

    三,问题解决

    [root@host188 etc]# ifconfig tunl0 down
    [root@host188 etc]# ip tunnel del tunl0
    delete tunnel "tunl0" failed: Operation not permitted
    [root@host188 etc]# ip tunnel show
    tunl0: ip/ip remote any local any ttl inherit nopmtudisc
    [root@host188 etc]# lsmod
    Module                  Size  Used by
    ...
    ipip                   13465  0      ---ipip模块的存在让tunl0无法删除
    
    [root@host188 etc]# rmmod ipip       ----卸载内核模块
    [root@host188 etc]# ip tunnel show   ---此时删除成功
    [root@host188 etc]# route -n      ---至此,路由信息正确添加进来了 
    Kernel IP routing table
    Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
    0.0.0.0         192.168.86.1    0.0.0.0         UG    0      0        0 ens160
    10.244.0.0      0.0.0.0         255.255.255.0   U     0      0        0 cni0
    10.244.1.0      10.244.1.0      255.255.255.0   UG    0      0        0 flannel.1
    10.244.2.0      10.244.2.0      255.255.255.0   UG    0      0        0 flannel.1   ----有了
    169.254.0.0     0.0.0.0         255.255.0.0     U     1002   0        0 ens160
    172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
    192.168.86.0    0.0.0.0         255.255.255.0   U     0      0        0 ens160

     最后的最后,重新加载ipip模块

    # modprobe ipip
    
    # lsmod
    Module                  Size  Used by
    ipip                   13465  0 
    
    #此时tunl0也自动被创建,但并未申请ip tunl0: flags
    =128<NOARP> mtu 1480 tunnel txqueuelen 1000 (IPIP Tunnel) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

    ============================================END=========================================================================

     
  • 相关阅读:
    (转)RSS在.net下面的调用以及使用
    WEB打印的一些资料,做项目的时候用到转来(转)
    asp.net编码技巧汇集(转)也有自己的一些
    ASP.NET 中 DataGrid 导出到 Excel 的封装实现 (转)
    (转)上传与下载需要考虑的
    正则表达式之全部符号解释(转)
    开发过程遇到的无法打包问题的解决!
    传入参数,导出dbf以及删除dbf的sql 存储过程
    (转贴)MDSN关于.net连接池的讨论
    一个SessionInterPagesHelper类 (转)挺不错的想法
  • 原文地址:https://www.cnblogs.com/shuiguizi/p/13892688.html
Copyright © 2011-2022 走看看