几个容器网络相关问题的分析和解决总结

摘要:
网络/容器网络因为其本身的复杂性,以及很多侧重软件开发的童鞋并不熟悉网络,导致和网络/容器网络相关问题的定位、分析和解决都比较困难,很多时候有无从下手之感。我对最近、再加上以前参与处理了的几个网络/容器网络相关的问题,总结如下,希望能给遇到类似的问题的童鞋一点启发。

【摘要】 网络/容器网络因为其本身的复杂性,以及很多侧重软件开发的童鞋并不熟悉网络,导致和网络/容器网络相关问题的定位、分析和解决都比较困难,很多时 候有无从下手之感。我对最近、再加上以前参与处理了的几个网络/容器网络相关的问题,总结如下,希望能给遇到类似的问题的童鞋一点启发。

目录

1. 目标主机上没有到源主机的路由,导致ping包没有返回 - route
2. Pod可以跨节点访问docker0 IP,但是不能跨节点访问Pod IP - ip_forward
3. Flannel隧道内部payload的源地址改变为flannel0设备地址 - iptables
4. 从Docker容器内可以ping通宿主机IP,但ping不通其它主机 - iptables
5. K8s集群掉电,导致所有的服务不能访问 - flannel & docker0
6. K8s Master主机上ping不通Node节点上的docker0和容器,但在Node上可以ping通 - iptables

网络/容器网络因为其本身的复杂性,以及很多侧重软件开发的童鞋并不熟悉网络,导致和网络/容器网络相关问题的定位、分析和解决都比较困难,很多时 候有无从下手之感。我对最近、再加上以前参与处理了的几个网络/容器网络相关的问题,总结如下,希望能给遇到类似的问题的童鞋一点启发。

总结一下,引起网络不通的主要原因有:

路由(route)问题。这类问题多如牛毛。常见的是目标主机到源主机的路由不通。

防火墙(iptables)问题。这类问题多如牛毛,但iptables比route更复杂。主要有:(1)防火墙filter表的规则阻止icmp包;(2)防火墙NAT表的SNAT/MASQUERADE。

系统内核参数问题。较少,更隐蔽,现象怪异得会让你怀疑自己的智商和人生。例如ip_forward,rp_filter等。

Linux设备参数设置。较少,更隐蔽,现象怪异得会让你怀疑自己的智商和人生。例如MTU等。 至于IP地址配置错误等问题就太明显了,不在本文讨论之列。

1. 目标主机上没有到源主机的路由,导致ping包没有返回 - route

问题现象:

某类生产环境,因为网络不通导致安装PaaS平台失败。从源主机ping目标主机,数据包没有返回。

分析排查:

思路得清楚,你需要画一张类似如下的图:

几个容器网络相关问题的分析和解决总结第1张

在目标主机使用route -n查看没有到源主机网络的路由。

源主机和目标主机都需要加路由。否则目标机器能收到ping包,但是返回报文会因为路由不通丢失。

route add -net 192.144.52.0/24 gw 192.144.152.253 dev eth1
route add -net 192.144.152.0/24 gw 192.144.52.253 dev eth0

2. Pod可以跨节点访问docker0 IP,但是不能跨节点访问Pod IP - ip_forward

问题现象:

某生产环境,K8s+Docker+flannel。从pod内跨节点ping另外节点的pod ip,不通;但是ping另外节点的docker0,是可以ping通的。意思是Pod可以跨节点访问docker0(证明flannel隧道是可以的),但是不能跨节点访问pod。

图示如下:

几个容器网络相关问题的分析和解决总结第2张

分析排查:

排查如下:

几个容器网络相关问题的分析和解决总结第3张

测试如下:

几个容器网络相关问题的分析和解决总结第4张

问题解决:

因为问题现象比较怪异,一度开始怀疑自己的智商和人生。

最后欧拉的同事发现是故障节点的内核参数ip_forward=0。

这个ip_forward是必须打开的参数,否则内核收到来自docker0的非本地地址的数据包会丢弃,而不会转发(forward)出去。

几个容器网络相关问题的分析和解决总结第5张

进一步分析,应该是EulerOS的security-tool启动时修改了内核参数(包括设置net.ipv4.ip_forward=0)导致的问题。

Docker engine启动的时候默认也会设置net.ipv4.ip_forward=1,但是security-tool和docker engine都是系统的service,启动时间和快慢不同,可能导致这个值被两个工具设置的先后顺序不一样,导致我们看到不一样的行为。(注:这个分析待商榷)

建议的解决办法:

设置/etc/sysconf中的net.ipv4.ip_forward=1,执行sysctl –p。但这个需要欧拉Docker确认security-tool修改的其它内核参数和安全加固等,会不会影响docker引擎。
如果还不行,就修改security-tool的配置(不推荐): 修改/etc/euleros_security/security.conf的
301@m@/etc/sysctl.conf@net.ipv4.ip_forward=@0 --->
301@m@/etc/sysctl.conf@net.ipv4.ip_forward=@1
当然我们的Salt脚本也会显式地设置这个值。

3. Flannel隧道内部payload的源地址改变为flannel0设备地址 - iptables

问题现象:

但是在抓包的过程中,发现Flannel隧道内部payload的源地址改变为发起请求的Pod所在节点的flannel0设备地址,而不是发起请求的Pod的IP地址。

关于这个问题的详细分析,请见Flannel隧道内部payload的源地址改变为flannel0设备地址的问题分析

分析排查:

首先,应该不是Kube-Proxy做的修改。因为Kube-Proxy只对访问Service(ClusterIP)的流量,做了很多iptables规则;而抓包实验中是直接使用Pod的IP地址操作的。

其次,进程flanneld应该不会修改这个源IP地址。因为flanneld在跨节点传送数据的过程中的一个主要作用是做隧道的解/封装,它没有理由去修改payload的内容(inner source ip)。

我们有理由相信,flanneld拿到这个数据包时,这个inner source ip已经被修改成发起请求的Pod所在节点的flannel0设备地址了。

通过查看iptables规则,发现有如下一条:

-A POSTROUTING -s 10.1.15.0/24 ! -o docker0 -j MASQUERADE
这是docker设置的。它的意思是:在POSTROUTING链上,如果源地址属于10.1.15.0/24,且出站网络接口不是docker0,则做地址伪装。

MASQUERADE,即IP伪装,是SNAT的一种特殊形式。这应该只用于动态分配IP地址的场景。在MASQURADE中,你不需要明确指定源地址,iptables会使用该数据包出站时的网口的IP地址。关于MASQUERADE,请参考Kubernetes和容器网络详解系列之Kubernetes iptables。

由于以上这条规则,从docker0入站的流量,最终通过flannel0出站时,会把数据包源地址修改为出站接口flannel0的地址。这个时候flanneld再做封装时,payload中的源地址(inner source ip)已经被修改成flannel0的地址了。

问题解决:

删除这条规则。

4. 从Docker容器内可以ping通宿主机IP,但ping不通其它主机IP - iptables

问题现象:

从Docker容器内可以ping通宿主机IP,但ping不通其它主机IP。

分析排查:

从现象可以看到数据包可以从Pod中经过docker0出去。检查防火墙规则的时候发现是因为没有做SNAT。这样会导致目标主机可以收到ping包,但是返回包会丢失。(没有抓码流验证)

问题解决:

给防火墙添加了如下iptables规则: iptables -t nat -A POSTROUTING -s 172.16.94.0/24 -j SNAT --to <宿主机IP>

5. K8s集群掉电,导致所有的服务不能访问 - flannel & docker0

问题现象:

K8s集群掉电后,服务不能访问。 查看主机上的flannel.1和docker0网络,发现网段不一致。

如下:

几个容器网络相关问题的分析和解决总结第6张

分析排查:

原因:掉电导致集群节点的docker0网络配置和flannel0的网络配置不一致。flannel的网络配置是保存在etcd集群中的,以此为准。

问题解决:

解决办法:

1、ifconfig flannel0和ifconfig docker0看到二者的网络配置不一致
2、停止docker0,并删除之:ifconfig docker0 down; brctl delbr docker0
3、修改/etc/default/docker中的--bip,和flannel0的保持一致
4、重启docker daemon,service docker restart
5、docker服务运行正常后,ifconfig docker0检查:(1)docker0是否重新创建;(2)网段配置是否和flannel0保持一致。如果提示没有docker0设备,稍等一会,或者再次重启docker服务
6、重启docker服务,会造成上面的pod运行状态错误为Error。用watch kubectl get pods监视一会,会自动恢复正常。
7、按照常规测试业务的连通性。
建议:较新版本的CCE已经对此问题有处理手段,建议升级。

6. K8s Master主机上ping不通Node节点上的docker0和容器,但在Node上可以ping通 - iptables

问题现象:

一个K8s集群,包含一个Master三个Node,Master没有Node的角色,但同时安装和启动了Flannel。 使用Flannel做Overlay,backend是VXLAN。从Master上ping其它Node的docker0/Pod IP不通,从Node节点上互ping docker0/Pod IP没有问题。 导致开放原生K8s API失败(从api server代理proxy流量到Pod失败)。

分析排查:

在目标Node节点的flannel.1上抓包,可以看到有返回包,但是收不到。 检查IP、路由、网络设备等均无发现问题。

几个容器网络相关问题的分析和解决总结第7张

在Master节点上,用ipables-save查看防火墙规则,发现如下两条和icmp相关的,一条在INPUT链上,一条在FORWARD链上:

-A INPUT -j REJECT --reject-with icmp-host-prohibited
... ...
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
可以看出Master节点会拒绝掉icmp包,理由是主机不允许。

问题解决:

找到以上两条防火墙规则的所在行号,然后删除之:

查看INPUT链:
iptables -L INPUT --line-numbers
如下:
7 REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
删除:
iptables -D INPUT 7
查看FORWARD链:
iptables -L FORWARD --line-numbers
如下:
13 REJECT all -- anywhere anywhere reject-with icmp-host-prohibited
删除:
iptables -D FORWARD 13

来源:华为云社区 作者: 乔雷

免责声明:文章转载自《几个容器网络相关问题的分析和解决总结》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇使用postman调用webservice接口Spring Security中的MD5盐值加密下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

P2P简介

在这信息无处不在的时代,我们无时不刻都在接收和发送者信息。那么既然每个人需要的信息量那么大,在这个网络服务器仍然受着限制的时代,各大厂商比如迅雷是如何给每个用户传输信息并且能保持如此之快的速度的呢。这里就要讲到了P2P技术。 点对点技术(peer-to-peer, 简称P2P)又称对等互联网络技术,是一种网络新技术,依赖网络中参与者的计算能力和带宽,而不是把...

HFish蜜罐-基于Docker的搭建与配置

HFish介绍 HFish 是一款基于 Golang 开发的跨平台多功能主动诱导型开源蜜罐框架系统,为了企业安全防护做出了精心的打造,全程记录黑客攻击手段,实现防护自主化。 在Docker上搭建HFish 获取镜像 docker pull imdevops/hfish 容器部署 docker run -d --name hfish -p 21:21 -...

Kubernetes 将Pod调度到Master节点

  出于安全考虑,默认配置下Kubernetes不会将Pod调度到Master节点。如果希望将k8s-master也当作Node使用,可以执行如下命令: kubectl taint node k8s-master node-role.kubernetes.io/master- 其中k8s-master是主机节点hostname如果要恢复Master Onl...

记录一次docker报错

最近新搭建了一台docker服务器,把本地镜像load导入的时候报错:devmapper:ThinPoolhas163029freedatablockswhichislessthanminimumrequired163840freedatablocks.Createmorefreespaceinthinpoolorusedm.min_free_spaceo...

003-Centos7.3下安装Jumpserver 1.0.0(支持windows组件)

Jumpserver最新版本支持windows组件,废话不多介绍了,下面直接介绍下部署过程: 0)系统环境 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 CentOS 7.3 IP: 192.168.10.210   [root@jumpserver-server ~]# cat /etc/red...

igraph——图挖掘助力社会网络分析

http://www.ituring.com.cn/article/1762 社交网络(如Facebook,Twitter)可以完整地表现人们的生活。人们用不同的方式与他人互动,并且这些信息都可以在社交网络中抓取到。挖掘某个站点的有用信息可以帮助一些团体增加竞争力。 我最近无意中发现一款叫做“igraph”的工具,它提供了一些非常有效的挖掘功能。以下列举几...