docker网络问题的排查

docker network

具体见https://docs.docker.com/network/
先讨论overlay, 近2天排查的是container之间的问题. 记录一下常用的脚本和命令.
https://docs.docker.com/netwo...
下图参考concept使用. 原图来自于
https://cloud.tencent.com/info/dc89b384392e75a6c3614d2dee4088ad.html
但链接已失效.
image.png

concept

network namespace

网络名字空间, 由linux kernel实现.
network namespace(网络名字空间)是相互隔离的网络视图,每个网络名字空间都有独立的网络配置,比如:网络设备、路由表等.
ip netns list 可列出network namespace

veth pair

虚拟网卡接口对.
链接不同network namespace

vxlan

跨机器通信, 通过3层的udp协议, 模拟2层网络.
docker container 也通过 veth pair 链接 container 和 overlay 的 network namespace.
所有的包都会发到br0网桥, 再通过vtep(VXLAN Tunnel End Point) 封包成udp协议发送至远端主机, 就像在同一台机器一样.

排查常用命令

将docker的network namespace纳入ip netns管理

cd /var/run &&sudo ln -s /var/run/docker/netns netns
root@xxxxx:/home/xxxxx# ip netns list
9c91cd6debed (id: 6)
5a80a1c4887f (id: 13)
eb26f4d5b623 (id: 9)
1f2110b87988 (id: 4)
...

找到container的network namespace

#!/bin/bash

all_netns=$(ip netns | awk {'print $1'})
declare -A mac_to_netns
for one_netns in $all_netns
do
  mac_addr=$(ip netns exec $one_netns ifconfig | grep "\beth1\b" | awk {'print $NF'})
  # echo "mac1$mac_addr"
  if [ -n "$mac_addr" ]; then
    mac_to_netns[$mac_addr]=$one_netns
  fi
done

for container in $(docker ps --format '{{.Names}}'); do
  mac_addr=`docker exec $container cat /sys/class/net/eth1/address`
  # echo "$container: $mac_addr"
  if [ -n "$mac_addr" ]; then
    echo "$container:${mac_to_netns[$mac_addr]}"
  fi
done

找到container的veth.

#!/bin/bash

for container in $(docker ps --format '{{.Names}}'); do
    iflink=`docker exec -it $container bash -c 'cat /sys/class/net/eth*/iflink'`
    for net in $iflink;do
        net=`echo $net|tr -d '\r'`
        veth=`grep -l $net /sys/class/net/veth*/ifindex`
        veth=`echo $veth|sed -e 's;^.*net/\(.*\)/ifindex$;\1;'`
        if [ -n "$veth" ]; then
          echo $container:$veth
        fi
    done
done

抓特定container包

用上面脚本拿到container的namespace

ip netns exec 0c9dbfeee12f tcpdump -i any host 192.168.xxx.xxx -w xx.cap

抓vxlan包

直接抓eth0, 可以用udp, port 4789 筛选

tcpdump -i eth0 host xxxx udp port 4789 -w xxx_vxlan.cap

你可能感兴趣的:(docker,tcpdump,network)