> For the complete documentation index, see [llms.txt](https://jiangpengfei.gitbook.io/open-vswitch/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://jiangpengfei.gitbook.io/open-vswitch/jin-jie/shi-yong-ovs-da-tong-duo-jie-dian-shang-de-rong-qi-tong-xin-overlay.md).

# 使用 OVS 打通多节点上的容器通信(Overlay)

### 概述

在《启动》这一篇中，学习了如何启动 ovs 服务，并使用 ovs 创建 bridge 设备，然后打通节点内容器间的通信。这一节主要是学习在多节点之间构建一个 overlay 的网络，然后打通所有容器间的通信。最终的网络拓扑图可能如下：

![图 1](/files/-M5zsHrysdnPLU_tELvS)

### 准备工作

我这里写了两个很简单的创建 bridge，然后将容器加入到 bridge 上。

```
#!/bin/bash

BR0_IP="172.19.49.2"
C1_IP="172.19.2.1"
C2_IP="172.19.2.2"

ovs-vsctl add-br br0
ifconfig br0 $BR0_IP/16
docker run -d --name c1 -it --net=none --privileged=true busybox sh
ovs-docker add-port br0 eth0 c1 --ipaddress=$C1_IP/16 --gateway=$BR0_IP
docker run -d -it --name c2 --net=none --privileged=true busybox sh
ovs-docker add-port br0 eth0 c2 --ipaddress=$C2_IP/16 --gateway=$BR0_IP
```

使用上面的脚本创建基本环境后，可以得到下图所示的情况：

![图 2](/files/-M5zsOY1t5VDQjLXctTZ)

### 使用 VXLAN 构建 overlay 网络

VXLAN 在每个节点上都会启动 vtep，然后使用 UDP 封装 IP 包进行转发，由 vtep 进行封包和解包。我们这里使用 ovs 来创建 VXLAN 网络，写了一个简单的脚本帮助快速创建：

```
#!/bin/bash

REMOTE_IP="192.168.33.11"

ovs-vsctl add-port br0 vxlan1 -- set interface vxlan1 type=vxlan options:remote_ip=$REMOTE_IP options:key=flow options:dst_port=8472
```

创建结束后，我们确认一下 vxlan 的 vtep 是否启动了。可以看到确实有进程监听了 8472 这个端口。

```
$  netstat -anp | grep 8472
udp        0      0 0.0.0.0:8472            0.0.0.0:*                           -                   
udp6       0      0 :::8472                 :::* 
```

现在测试一下容器之间的网络通信：

```
# 同一个节点内的网络通信
$ docker exec -it c1 sh -c "ping -c 3 172.19.1.2"
PING 172.19.1.2 (172.19.1.2): 56 data bytes
64 bytes from 172.19.1.2: seq=0 ttl=64 time=0.197 ms
64 bytes from 172.19.1.2: seq=1 ttl=64 time=0.147 ms
64 bytes from 172.19.1.2: seq=2 ttl=64 time=0.135 ms

# 和另一个节点上容器的通信
$ docker exec -it c1 sh -c "ping -c 3 172.19.2.2"
PING 172.19.2.2 (172.19.2.2): 56 data bytes
64 bytes from 172.19.2.2: seq=0 ttl=64 time=1.150 ms
64 bytes from 172.19.2.2: seq=1 ttl=64 time=1.289 ms
64 bytes from 172.19.2.2: seq=2 ttl=64 time=1.071 ms
```

此时的网络拓扑图应该如下：

![图 3](/files/-M5zwgNzXWzJ0p8MOZoP)

TODO: 此时容器中还没法访问互联网

### 使用 GRE 构建 overlay 网络

使用 GRE 来构建 overlay 网络和使用 VXLAN 类似，执行类似以下代码即可：

```
#!/bin/bash

REMOTE_IP="192.168.33.11"

ovs-vsctl add-port br0 gre0 -- set interface gre0 type=gre options:remote_ip=$REMOTE_IP
```

测试一下跨节点容器的网络连通性：

```
$ docker exec -it c1 sh -c "ping -c 3 172.19.2.1"
PING 172.19.2.1 (172.19.2.1): 56 data bytes
64 bytes from 172.19.2.1: seq=0 ttl=64 time=0.643 ms
64 bytes from 172.19.2.1: seq=1 ttl=64 time=1.175 ms
64 bytes from 172.19.2.1: seq=2 ttl=64 time=1.088 ms
```
