在启动 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 路径
--bootstrap-ca-cert: ca 证书
使用 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"