网络不通通俗一点就是报文不可达 在这里就不多说了
举个例子
容器A访问不了容器B,也就是容器A ping 不通容器B
排查思路:
正向
容器A的内容是否发送到容器A所在的node上
容器A所在的节点node是否发送出去
容器B所在的节点node是否接收到容器A所在的节点node发送的报文
容器B所在的节点node是否把报文发送到容器B中
反向
容器B的内容是否发送到容器B所在的node上
容器B所在的节点node是否发送出去
容器A所在的节点node是否接收到容器B所在的节点node发送的报文
容器A所在的节点node是否把报文发送到容器A中
具体实践
[root@dev-master- ~]# kubectl get pods -owide -n qateam
NAME READY STATUS RESTARTS AGE IP NODE
asa--td4wp / Running d . dev-master-
aws--mkfs5 / Running d . dev-master-
demo- / Running d . dev-slave-
demo-- / Running d . dev-slave-
demo22- / Running d . dev-slave-
erfasd--h94fh / Running d . dev-master-
sas--fmq45 / Running d . dev-master-
先用calicoctl查看容器A的workloadEndpoint:
[[email protected] ~]# calicoctl get workloadendpoint --workload=qateam.asa-532345087-td4wp -oyaml
- apiVersion: v1
kind: workloadEndpoint
metadata:
labels:
ClusterID: CID-f794208bc85f
UserID: "45"
calico/k8s_ns: qateam
name: asa
pod-template-hash: "532345087"
name: eth0
node: dev-master-105
orchestrator: k8s
workload: qateam.asa-532345087-td4wp
spec:
interfaceName: calicc354b946ce
ipNetworks:
- ./
mac: f6:77:d3:29:1a:50
profiles:
- k8s_ns.qateam
可以看到容器A的相关网路的信息
容器A的绑定的网卡 calicc354b946ce
容器A的mac地址f6::d3::a:
容器的IP地址./ 所在的节点dev-master-
查看容器A内的网卡是否正确,ip和mac是否与从calico中查询到的一致:
[root@dev-master- ~]# kubectl exec -it asa-532345087-td4wp -n qateam sh
sh-# ifconfig
eth0: flags=<UP,BROADCAST,RUNNING,MULTICAST> mtu
inet . netmask . broadcast ...
inet6 fe80::f477:d3ff:fe29:a5 prefixlen scopeid <link>
ether f6::d3::a: txqueuelen (Ethernet)
RX packets bytes ( MiB)
RX errors dropped overruns frame
TX packets bytes ( KiB)
TX errors dropped overruns carrier collisions
lo: flags=<UP,LOOPBACK,RUNNING> mtu
inet .. netmask ..
inet6 :: prefixlen scopeid <host>
loop txqueuelen (Local Loopback)
RX packets bytes (. B)
RX errors dropped overruns frame
TX packets bytes (. B)
TX errors dropped overruns carrier collisions
可以看到mac地址以及ip地址 跟通过calicoctl 取到的是一致的
查看容器A的默认路由是否是169.254.1.1,且没有额外的路由:
sh-# ip route
default via dev eth0
dev eth0 scope link
在node上执行,查看calicc354b946ce的网卡的mac地址是否跟之前通过calicoctl查询得到的结果一致
[root@dev-master- ~]# ip link show calicc354b946ce
: calicc354b946ce@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu qdisc noqueue state UP mode DEFAULT
link/ether :::09:0b:cd brd ff:ff:ff:ff:ff:ff link-netnsid
查看容器A内记录的169.254.1.1的mac地址是否是node上的calico网卡的mac
sh-4.2# ip neigh
169.254.1.1 dev eth0 lladdr 22:49:04:09:0b:cd STALE
这里需要一点说明,使用calico后,在容器内只有一条默认路由,所有的报文都通过169.254.1.1送出。但是这个IP是RFC约定保留的无效IP,报文怎么还能送出去呢?
秘密就是容器内的arp记录,在容器A内记录的169.254.1.1的mac地址是:
node上的caliXX网卡的mac。
node上的caliXX网卡和容器内的eth0网卡,是一对veth设备。veth网卡的特性是,向eth0写入的报文,会通过caliXX流出。
在容器A中向eth0写入的报文,它目的mac是caliXX网卡的mac,当报文经caliXX流出时,就 进入到了node的协议栈中,开始在node的网络空间中流转。
在容器A所在的node上用tcpdump监听calicc354b946ce网卡,查看是否能够收到容器A发出的报文:
[root@dev-master- ~]# tcpdump -i calicc354b946ce
tcpdump: WARNING: calicc354b946ce: no IPv4 address assigned
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on calicc354b946ce, link-type EN10MB (Ethernet), capture size bytes
检查发送端node上的路由,目标IP的下一跳地址是否正确,目标IP是容器的地址,检查下一跳是否对应了正确的node ip:
...
/ via dev tunl0 proto bird onlink
...
这条路由是通过BGP协议得知的,它的意思是说192.168.19.0/26这个网段可以通过10.39.0.105到达。
然后还需要检查发送端node上的iptables规则,看一下iptable是否拒绝了这个报文。
很多组件都会设置iptables规则,有可能是别的组件,譬如docker,设置的规则导致不通。
从calico中获取接收端容器B的信息:
[[email protected] ~]# calicoctl get workloadendpoint --workload=qateam.dev-3629875698-b58t6 -oyaml
- apiVersion: v1
kind: workloadEndpoint
metadata:
labels:
ClusterID: CID-f794208bc85f
UserID: "45"
calico/k8s_ns: qateam
name: dev
pod-template-hash: "3629875698"
tenxcloud.com/appName: dev
tenxcloud.com/svcName: dev
name: eth0
node: dev-master-
orchestrator: k8s
workload: qateam.dev--b58t6
spec:
interfaceName: cali9ee0bd99a15
ipNetworks:
- /
mac: :eb::::d9
profiles:
- k8s_ns.qateam
可以得到容器B的以下信息:
容器的网络接口(网卡)cali9ee0bd99a15
容器的节点dev-master-
监听容器B所在node的网卡,检查是否收到了容器A所在的node发送来的报文:
[root@dev-master- ~]# tcpdump -i cali9ee0bd99a15
tcpdump: WARNING: cali9ee0bd99a15: no IPv4 address assigned
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on cali9ee0bd99a15, link-type EN10MB (Ethernet), capture size bytes
检查容器B所在node上的路由,检查目标IP是否对应了正确的calico网卡:
[[email protected] ~]# ip route
...
dev cali9ee0bd99a15 scope link
...
前面我们说明了报文如何从容器A到达容器A所在的node,那么还有一个问题是, 报文又是怎样从node到达容器内部的呢?
答案是node上的路由。
上面那条路由的意思是,192.168.60.173这个IP对应的网卡是caliXXX,报文会被写入到这个网卡中。 这个网卡和容器内的网卡是一对veth设备,写入caliXX的报文会通过容器内的eth0流出,从而进入到容器的网络空间中。
这里同样需要检查接收端node上的iptables规则,看一下报文是否被iptables拒绝。
参考:
http://mp.weixin.qq.com/s/MZIj_cvvtTiAfNf_0lpfTg