通过 OVS+DPDK 连接的 Docker 容器, `Ping` 工作但 `iperf` NOT

标签 docker ping openvswitch iperf

我正在尝试使用 DockerOVS+DPDK 构建一个平台。

<强>1。设置DPDK + OVS

我使用 dpdk-2.2.0openvswitch-2.5.1 设置了 DPDK+OVS。首先,我编译了DPDK的代码,设置了hugepages。我没有绑定(bind) NIC,因为我没有从外部获取流量。

然后,我编译openvswitch的代码,设置with-dpdk。使用以下脚本启动 OVS:

#!/bin/sh
sudo rm /var/log/openvswitch/my-ovs-vswitchd.log*

export PATH=$PATH:/usr/local/share/openvswitch/scripts

export DB_SOCK=/usr/local/var/run/openvswitch/db.sock

sudo ovsdb-server --remote=punix:/usr/local/var/run/openvswitch/db.sock \
                     --remote=db:Open_vSwitch,Open_vSwitch,manager_options \
                     --private-key=db:Open_vSwitch,SSL,private_key \
                     --certificate=db:Open_vSwitch,SSL,certificate \
                     --bootstrap-ca-cert=db:Open_vSwitch,SSL,ca_cert \
                     --pidfile --detach

sudo ovs-vsctl --no-wait set Open_vSwitch . other_config:dpdk-init=true

sudo ovs-vsctl set Open_vSwitch . other_config:pmd-cpu-mask=0x6

sudo ovs-vswitchd --dpdk -c 0x1 -n 4 -- unix:$DB_SOCK --pidfile --detach \
                        --log-file=/var/log/openvswitch/my-ovs-vswitchd.log

一切正常,我的 OVS 现在可以使用 DPDK 支持。

<强>2。创建 Docker 容器,并设置网桥和端口。

我使用 ubuntu:14.04 中的 Docker 图像如下:

#
# Ubuntu Dockerfile
#
# https://github.com/dockerfile/ubuntu
#

# Pull base image.
FROM ubuntu:14.04

# Install.
RUN \
  sed -i 's/# \(.*multiverse$\)/\1/g' /etc/apt/sources.list && \
  apt-get update && \
  apt-get -y upgrade && \
  apt-get install -y build-essential && \
  apt-get install -y software-properties-common && \
  apt-get install -y byobu curl git htop man unzip vim wget && \
  apt-get install -y iperf net-tools && \
  rm -rf /var/lib/apt/lists/*

# Add files.
ADD root/.bashrc /root/.bashrc
ADD root/.gitconfig /root/.gitconfig
ADD root/.scripts /root/.scripts

# Set environment variables.
ENV HOME /root

# Define working directory.
WORKDIR /root

# Install tcpreply
RUN apt-get update
RUN apt-get install -y libpcap-dev
ADD tcpreplay-4.3.2 /root/tcpreplay-4.3.2
WORKDIR /root/tcpreplay-4.3.2   
RUN ./configure
RUN make
RUN make install

# Copy pcap file
ADD test_15M /root/test_15M

# Define default command.
CMD ["bash"]

然后,我使用脚本创建一个 OVS 网桥,即 ovs-br1,以及两个带有 ovs-docker 的端口:

#!/bin/sh

sudo ovs-vsctl add-br ovs-br1 -- set bridge ovs-br1 datapath_type=netdev

sudo ifconfig ovs-br1 173.16.1.1 netmask 255.255.255.0 up

sudo docker run -itd --name="box1" "ubuntu14-tcpreplay:v1"

sudo docker run -itd --name="box2" "ubuntu14-tcpreplay:v1"

sudo ovs-docker add-port ovs-br1 eth1 box1 --ipaddress=173.16.1.2/24

sudo ovs-docker add-port ovs-br1 eth1 box2 --ipaddress=173.16.1.3/24 

现在,我有一个网桥 ovs-br1,有两个端口(无名称)。一个连接到 box1(容器 1),另一个连接到 box2(容器 2)。

<强>3。检查 box1box2

之间的连接

首先,我转储ovs-br1

的流程
wcf@wcf-OptiPlex-7060:~/ovs$ sudo ovs-ofctl dump-flows ovs-br1
NXST_FLOW reply (xid=0x4):
 cookie=0x0, duration=130.711s, table=0, n_packets=10, n_bytes=768, idle_age=121, priority=0 actions=NORMAL

然后,我转到 box1 并 ping box2

wcf@wcf-OptiPlex-7060:~/ovs$ sudo docker exec -it box1 "/bin/bash"
[ root@45514f0108a9:~/tcpreplay-4.3.2 ]$ ping 173.16.1.3     
PING 173.16.1.3 (173.16.1.3) 56(84) bytes of data.
64 bytes from 173.16.1.3: icmp_seq=1 ttl=64 time=0.269 ms
64 bytes from 173.16.1.3: icmp_seq=2 ttl=64 time=0.149 ms
64 bytes from 173.16.1.3: icmp_seq=3 ttl=64 time=0.153 ms
64 bytes from 173.16.1.3: icmp_seq=4 ttl=64 time=0.155 ms
64 bytes from 173.16.1.3: icmp_seq=5 ttl=64 time=0.167 ms
64 bytes from 173.16.1.3: icmp_seq=6 ttl=64 time=0.155 ms
^C
--- 173.16.1.3 ping statistics ---
6 packets transmitted, 6 received, 0% packet loss, time 4997ms
rtt min/avg/max/mdev = 0.149/0.174/0.269/0.045 ms

一切正常。 box1 可以 ping 到 box2

最后,我测试了 box1box2 之间的 iperf。我在两个容器中都安装了 iperf2

box1:

[ root@45514f0108a9:~/tcpreplay-4.3.2 ]$ iperf -c 173.16.1.3 -u -t 5
------------------------------------------------------------
Client connecting to 173.16.1.3, UDP port 5001
Sending 1470 byte datagrams
UDP buffer size:  208 KByte (default)
------------------------------------------------------------
[  3] local 173.16.1.2 port 49558 connected with 173.16.1.3 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0- 5.0 sec   642 KBytes  1.05 Mbits/sec
[  3] Sent 447 datagrams
[  3] WARNING: did not receive ack of last datagram after 10 tries.

box2:

[ root@2e19a616d2af:~/tcpreplay-4.3.2 ]$ iperf -s -u
------------------------------------------------------------
Server listening on UDP port 5001
Receiving 1470 byte datagrams
UDP buffer size:  208 KByte (default)
------------------------------------------------------------

来自 box1iperf 数据包没有得到 box2 的响应。

我使用 wireshark 监控 ovs-br1box1box2 的两个 OVS 端口。

ovs-br1 不查看任何流量,但是,两个 OVS 端口都查看流量。 wireshark的截图:

wireshark: two OVS ports

感谢您分享您的想法。

祝福

最佳答案

如果意图是将数据包从一个容器 1 直接发送到容器 2,则应该有流规则说明相同的内容。比如./ovs-ofctl add-flow br0 in_port=1,action=output:2或者./ovs-ofctl add-flow br0 in_port=2,action=output:1.

应用流规则以确保从 Linux 内核堆栈至少配置默认路由以将数据包发送到所需接口(interface)。例如 173.16.1.0/24 的默​​认路由条目

关于通过 OVS+DPDK 连接的 Docker 容器, `Ping` 工作但 `iperf` NOT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56539216/

相关文章:

django - 当主机系统上只有Nginx时,使用Docker的静态文件

Java 进程作为非 root 占用 100% CPU,但作为 root 没问题

java - 速度测试应用程序 下载 上传 Ping

Linux ping广播开关

xml - 如何使用 virt-install 将 VLAN 信息添加到 VM xml 文件?

bash - 尝试使用 `kubectl cp`将文件复制到Pod,但出现错误:未知标志:--all-namespaces

firebase - 哪个 docker 镜像包含 firebase 和 gcloud 的 CLI?

linux - 如何从开发箱检查某个端口是否打开或在任何其他服务器上被阻止?

python - 使用 pyparsing 从 ovs 转储流中提取数据

c++ - 函数前的参数有什么意义?