启动

在启动 ovs-vswitchd 之前,我们需要先启动它的配置数据库:ovsdb-server。每一个安装了 Open vSwitch 的机器,都需要运行一份 ovsdb-server 的副本。

创建数据库

$ mkdir -p /usr/local/etc/openvswitch
$ sudo ovsdb-tool create /usr/local/etc/openvswitch/conf.db vswitchd/vswitch.ovsschema

启动服务

# 启动数据库服务
$ 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 init

# 启动 Open vSwitch 后台服务
$ sudo ovs-vswitchd --pidfile --detach

参数解释:

  • --remote: 监听的 unix socket 路径

  • --remote: 连接到在数据库中指定的管理器

  • --private-key: 私钥

  • --certificate: 证书

  • --bootstrap-ca-cert: ca 证书

  • --pidfile: pid文件

  • --detach: 进程分离

使用 ovs 打通节点内部容器间的通信

注:ovs-vsctl 的参考文档: [ovs-vsctl](http://www.openvswitch.org/support/dist-docs-2.5/ovs-vsctl.8.html)

这里主要是为 docker 容器配置使用 ovs 创建的网桥,并能够使各容器间的网络互通。

创建网桥

$ sudo ovs-vsctl add-br br0
$ sudo ovs-vsctl show
d845f6af-c6d7-4a7c-9c08-14ad1b541374
    Bridge "br0"
        Port "br0"
            Interface "br0"
                type: internal
# 为网桥配置 ip 地址
$ sudo ifconfig br0 172.17.42.2/16

启动无网络的 docker 容器

$ sudo docker run -d --name c1 -it --net=none --privileged=true busybox sh
# 查看容器内网络,只有一个回环网卡
$ docker exec -it c1 sh -c "ifconfig"
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

使用 ovs-docker 为其添加网络

$ sudo ovs-docker add-port br0 eth0 c1 --ipaddress=172.17.1.1/16 --gateway=172.17.42.2
# 再次查看容器内的网络信息, 此时多了 eth0 网卡
$ docker exec -it c1 sh -c "ifconfig"
eth0      Link encap:Ethernet  HWaddr CE:AB:5B:49:06:8E  
          inet addr:172.17.1.1  Bcast:0.0.0.0  Mask:255.255.0.0
          inet6 addr: fe80::ccab:5bff:fe49:68e/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:656 (656.0 B)  TX bytes:656 (656.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
# ping 一下 br0
$ docker exec -it c1 sh -c "ping -c 3 172.17.42.2"
PING 172.17.42.2 (172.17.42.2): 56 data bytes
64 bytes from 172.17.42.2: seq=0 ttl=64 time=0.663 ms
64 bytes from 172.17.42.2: seq=1 ttl=64 time=0.129 ms
64 bytes from 172.17.42.2: seq=2 ttl=64 time=0.127 ms

启动另一个容器,测试容器间的通信

$ sudo docker run -d -it --name c2 --net=none --privileged=true busybox sh
$ sudo ovs-docker add-port br0 eth0 c2 --ipaddress=172.17.1.2/16 --gateway=172.17.42.2
$ docker exec -it c2 sh -c "ping -c 3 172.17.1.1"
PING 172.17.1.1 (172.17.1.1): 56 data bytes
64 bytes from 172.17.1.1: seq=0 ttl=64 time=0.203 ms
64 bytes from 172.17.1.1: seq=1 ttl=64 time=0.132 ms
64 bytes from 172.17.1.1: seq=2 ttl=64 time=0.135 ms

这样,我们就打通了主机上各个容器之间的通信,最终的网络拓扑应该如下:

这张图上还显示了 veth pair 设备,veth pair 是用来打通容器和 Host 之间的网络的,那么怎么查看 veth pair 设备的关系呢?我们可以通过以下方式:

# 对容器执下面的指令,注意eth0@if14,这里的 if14 就是 Host 上序号为 14 的设备
$ docker exec -it c2 sh -c "ip link show eth0"
13: eth0@if14: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue qlen 1000
    link/ether 9e:57:5f:92:ce:18 brd ff:ff:ff:ff:ff:ff
$ 在 Host 上执行
$ ip link | grep 14
14: 26e46bb479354_l@if13: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master ovs-system state UP mode DEFAULT group default qlen 1000

我们再验证一下 br0 设备上是否有两个容器的 veth pair:

$ sudo ovs-vsctl show
d845f6af-c6d7-4a7c-9c08-14ad1b541374
    Bridge "br0"
        Port "br0"
            Interface "br0"
                type: internal
        Port "26e46bb479354_l"
            Interface "26e46bb479354_l"
        Port "ff0601af29664_l"
            Interface "ff0601af29664_l"

Last updated