On Wed, Oct 29, 2014 at 5:49 AM, Flavio Leitner <f...@redhat.com> wrote: > On Thu, Oct 16, 2014 at 01:26:37AM -0700, Gurucharan Shetty wrote: >> Open vSwitch does not have native integration with Docker. >> INSTALL.Docker explains how Open vSwitch can be integrated >> with docker non-natively. >> >> ovs-docker is a helper script to add network interfaces to >> docker containers and to attach them as ports to OVS bridge. >> This script can be further enhanced as we understand different >> use cases. >> >> Signed-off-by: Gurucharan Shetty <gshe...@nicira.com> > > Docker supports Linux bridge and it seems to me that it > should also be changed to support Open vSwitch, not the > other way around. > > I did a quick hack sort of replacing brctl commands with > ovs-vsctl commands to see if it works here: > https://github.com/fleitner/docker-ovs/tree/v1.2.0-ovs > > I am quite sure there are other forks doing something like that. > > My concern is with long term support/maintenance of this > because as soon as OVS support gets integrated to Docker, > we would have to keep supporting this method anyway. I did not intend to support this long term. My plan is to update the INSTALL.Docker if/when there is native integration of Docker with Open vSwitch.
> > Maybe this patch could be another new project apart from OVS? > > fbl > > >> --- >> INSTALL.Docker | 82 ++++++++++++++++ >> Makefile.am | 1 + >> NEWS | 2 + >> README.md | 2 + >> debian/openvswitch-common.install | 1 + >> rhel/openvswitch-fedora.spec.in | 1 + >> rhel/openvswitch.spec.in | 1 + >> utilities/automake.mk | 4 +- >> utilities/ovs-docker | 201 >> ++++++++++++++++++++++++++++++++++++++ >> 9 files changed, 294 insertions(+), 1 deletion(-) >> create mode 100644 INSTALL.Docker >> create mode 100755 utilities/ovs-docker >> >> diff --git a/INSTALL.Docker b/INSTALL.Docker >> new file mode 100644 >> index 0000000..1c492f3 >> --- /dev/null >> +++ b/INSTALL.Docker >> @@ -0,0 +1,82 @@ >> + How to Use Open vSwitch with Docker >> + ==================================== >> + >> +This document describes how to use Open vSwitch with Docker 1.2.0 or >> +later. This document assumes that you followed INSTALL or installed >> +Open vSwitch from distribution packaging such as a .deb or .rpm. >> +Consult www.docker.com for instructions on how to install Docker. >> + >> +Limitations >> +----------- >> +Currently there is no native integration of Open vSwitch in Docker, i.e., >> +one cannot use the Docker client to automatically add a container's >> +network interface to an Open vSwitch bridge during the creation of the >> +container. This document describes addition of new network interfaces to an >> +already created container and in turn attaching that interface as a port to >> an >> +Open vSwitch bridge. >> + >> +Setup >> +----- >> +* Create your container, e.g.: >> + >> +% docker run -d ubuntu:14.04 /bin/sh -c \ >> +"while true; do echo hello world; sleep 1; done" >> + >> +The above command creates a container with one network interface 'eth0' >> +and attaches it to a Linux bridge called 'docker0'. 'eth0' by default >> +gets an IP address in the 172.17.0.0/16 space. Docker sets up iptables >> +NAT rules to let this interface talk to the outside world. Also since >> +it is connected to 'docker0' bridge, it can talk to all other containers >> +connected to the same bridge. If you prefer that no network interface be >> +created by default, you can start your container with >> +the option '--net=none', e,g.: >> + >> +% docker run -d --net=none ubuntu:14.04 /bin/sh -c \ >> +"while true; do echo hello world; sleep 1; done" >> + >> +The above commands will return a container id. You will need to pass this >> +value to the utility 'ovs-docker' to create network interfaces attached to >> an >> +Open vSwitch bridge as a port. This document will reference this value >> +as $CONTAINER_ID in the next steps. >> + >> +* Add a new network interface to the container and attach it to an Open >> vSwitch >> + bridge. e.g.: >> + >> +% ovs-docker add-port br-int eth1 $CONTAINER_ID >> + >> +The above command will create a network interface 'eth1' inside the >> container >> +and then attaches it to the Open vSwitch bridge 'br-int'. This is done by >> +creating a veth pair. One end of the interface becomes 'eth1' inside the >> +container and the other end attaches to 'br-int'. >> + >> +The script also lets one to add an IP address to the interface. e.g.: >> + >> +% ovs-docker add-port br-int eth1 $CONTAINER_ID 192.168.1.1/24 >> + >> +* A previously added network interface can be deleted. e.g.: >> + >> +% ovs-docker del-port br-int eth1 $CONTAINER_ID >> + >> +All the previously added Open vSwitch interfaces inside a container can be >> +deleted. e.g.: >> + >> +% ovs-docker del-ports br-int $CONTAINER_ID >> + >> +It is important that the same $CONTAINER_ID be passed to both add-port >> +and del-port[s] commands. >> + >> +* More network control. >> + >> +Once a container interface is added to an Open vSwitch bridge, one can >> +set VLANs, create Tunnels, add OpenFlow rules etc for more network control. >> +Please read the man pages of ovs-vsctl, ovs-ofctl, ovs-vswitchd, >> +ovsdb-server ovs-vswitchd.conf.db etc for more details. >> + >> +Docker networking is quite flexible and can be used in multiple ways. For >> more >> +information, please read: >> +https://docs.docker.com/articles/networking >> + >> +Bug Reporting >> +------------- >> + >> +Please report problems to b...@openvswitch.org. >> diff --git a/Makefile.am b/Makefile.am >> index 77ceec6..43cc420 100644 >> --- a/Makefile.am >> +++ b/Makefile.am >> @@ -68,6 +68,7 @@ EXTRA_DIST = \ >> FAQ \ >> INSTALL \ >> INSTALL.Debian \ >> + INSTALL.Docker \ >> INSTALL.DPDK \ >> INSTALL.Fedora \ >> INSTALL.KVM \ >> diff --git a/NEWS b/NEWS >> index 74984a7..7851f6e 100644 >> --- a/NEWS >> +++ b/NEWS >> @@ -36,6 +36,8 @@ Post-v2.3.0 >> still needed, so this should not be enabled on production environments. >> - Stats are no longer updated on fake bond interface. >> - Keep active bond slave selection across OVS restart. >> + - A simple wrapper script, 'ovs-docker', to integrate OVS with Docker >> + containers. >> >> >> v2.3.0 - 14 Aug 2014 >> diff --git a/README.md b/README.md >> index e4bc75a..5386130 100644 >> --- a/README.md >> +++ b/README.md >> @@ -88,6 +88,8 @@ platform, please see one of these files: >> >> To use Open vSwitch... >> >> +- ...with Docker on Linux, read INSTALL.Docker. >> + >> - ...with KVM on Linux, read INSTALL, read INSTALL.KVM. >> >> - ...with Libvirt, read INSTALL.Libvirt. >> diff --git a/debian/openvswitch-common.install >> b/debian/openvswitch-common.install >> index f2a0d48..11bb596 100644 >> --- a/debian/openvswitch-common.install >> +++ b/debian/openvswitch-common.install >> @@ -1,5 +1,6 @@ >> usr/bin/ovs-appctl >> usr/bin/ovs-benchmark >> +usr/bin/ovs-docker >> usr/bin/ovs-ofctl >> usr/bin/ovs-parse-backtrace >> usr/bin/ovs-pki >> diff --git a/rhel/openvswitch-fedora.spec.in >> b/rhel/openvswitch-fedora.spec.in >> index c5e99ef..d3b0ecb 100644 >> --- a/rhel/openvswitch-fedora.spec.in >> +++ b/rhel/openvswitch-fedora.spec.in >> @@ -173,6 +173,7 @@ systemctl start openvswitch.service >> /usr/sbin/ovs-vswitchd >> /usr/sbin/ovsdb-server >> /usr/bin/ovs-appctl >> +/usr/bin/ovs-docker >> /usr/bin/ovs-dpctl >> /usr/bin/ovs-dpctl-top >> /usr/bin/ovs-ofctl >> diff --git a/rhel/openvswitch.spec.in b/rhel/openvswitch.spec.in >> index 5e99ccb..5d26d59 100644 >> --- a/rhel/openvswitch.spec.in >> +++ b/rhel/openvswitch.spec.in >> @@ -130,6 +130,7 @@ exit 0 >> /usr/bin/ovs-benchmark >> /usr/bin/ovs-dpctl >> /usr/bin/ovs-dpctl-top >> +/usr/bin/ovs-docker >> /usr/bin/ovs-ofctl >> /usr/bin/ovs-parse-backtrace >> /usr/bin/ovs-pcap >> diff --git a/utilities/automake.mk b/utilities/automake.mk >> index 87ccb98..9ddbbe2 100644 >> --- a/utilities/automake.mk >> +++ b/utilities/automake.mk >> @@ -4,7 +4,8 @@ bin_PROGRAMS += \ >> utilities/ovs-dpctl \ >> utilities/ovs-ofctl \ >> utilities/ovs-vsctl >> -bin_SCRIPTS += utilities/ovs-pki >> +bin_SCRIPTS += utilities/ovs-docker \ >> + utilities/ovs-pki >> if HAVE_PYTHON >> bin_SCRIPTS += \ >> utilities/ovs-dpctl-top \ >> @@ -27,6 +28,7 @@ EXTRA_DIST += \ >> utilities/ovs-check-dead-ifs.in \ >> utilities/ovs-ctl.in \ >> utilities/ovs-dev.py \ >> + utilities/ovs-docker \ >> utilities/ovs-dpctl-top.in \ >> utilities/ovs-l3ping.in \ >> utilities/ovs-lib.in \ >> diff --git a/utilities/ovs-docker b/utilities/ovs-docker >> new file mode 100755 >> index 0000000..d27228a >> --- /dev/null >> +++ b/utilities/ovs-docker >> @@ -0,0 +1,201 @@ >> +#!/bin/bash >> +# Copyright (C) 2014 Nicira, Inc. >> +# >> +# Licensed under the Apache License, Version 2.0 (the "License"); >> +# you may not use this file except in compliance with the License. >> +# You may obtain a copy of the License at: >> +# >> +# http://www.apache.org/licenses/LICENSE-2.0 >> +# >> +# Unless required by applicable law or agreed to in writing, software >> +# distributed under the License is distributed on an "AS IS" BASIS, >> +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. >> +# See the License for the specific language governing permissions and >> +# limitations under the License. >> + >> +check_command_avail () { >> + while [ $# -ne 0 ]; do >> + if ("$1" --version) > /dev/null 2>&1; then :; else >> + echo >&2 "$UTIL: missing $1, cannot proceed" >> + exit 1 >> + fi >> + shift >> + done >> +} >> + >> +ovs_vsctl () { >> + ovs-vsctl --timeout=60 "$@" >> +} >> + >> +create_netns_link () { >> + mkdir -p /var/run/netns >> + if [ ! -e /var/run/netns/"$PID" ]; then >> + ln -s /proc/"$PID"/ns/net /var/run/netns/"$PID" >> + trap 'delete_netns_link' 0 1 2 3 13 14 15 >> + fi >> +} >> + >> +delete_netns_link () { >> + RET="$?" >> + rm -f /var/run/netns/"$PID" >> + trap '' 0 1 2 3 13 14 15 >> + exit "$RET" >> +} >> + >> +add_port () { >> + BRIDGE="$1" >> + INTERFACE="$2" >> + CONTAINER="$3" >> + ADDRESS="$4" >> + >> + if [ "$#" -lt 3 ]; then >> + usage >> + exit 1 >> + fi >> + >> + if ovs_vsctl --may-exist add-br "$BRIDGE"; then :; else >> + echo >&2 "$UTIL: Failed to create bridge $BRIDGE" >> + exit 1 >> + fi >> + >> + if PID=`docker inspect -f '{{.State.Pid}}' "$CONTAINER"`; then :; else >> + echo >&2 "$UTIL: Failed to get the PID of the container" >> + exit 1 >> + fi >> + >> + create_netns_link >> + >> + # Create a veth pair. >> + ID=`uuidgen | sed 's/-//g'` >> + PORTNAME="${ID:0:13}" >> + ip link add "${PORTNAME}_l" type veth peer name "${PORTNAME}_c" >> + >> + # Add one end of veth to OVS bridge. >> + if ovs_vsctl --may-exist add-port "$BRIDGE" "${PORTNAME}_l" \ >> + -- set interface "${PORTNAME}_l" \ >> + external_ids:container_id="$CONTAINER" \ >> + external_ids:container_iface="$INTERFACE"; then :; else >> + echo >&2 "$UTIL: Failed to add "${PORTNAME}_l" port to bridge >> $BRIDGE" >> + ip link delete "${PORTNAME}_l" >> + exit 1 >> + fi >> + >> + ip link set "${PORTNAME}_l" up >> + >> + # Move "${PORTNAME}_c" inside the container and changes its name. >> + ip link set "${PORTNAME}_c" netns "$PID" >> + ip netns exec "$PID" ip link set dev "${PORTNAME}_c" name "$INTERFACE" >> + ip netns exec "$PID" ip link set "$INTERFACE" up >> + >> + if [ -n "$ADDRESS" ]; then >> + ip netns exec "$PID" ip addr add "$ADDRESS" dev "$INTERFACE" >> + fi >> +} >> + >> +del_port () { >> + BRIDGE="$1" >> + INTERFACE="$2" >> + CONTAINER="$3" >> + >> + if [ "$#" -lt 3 ]; then >> + usage >> + exit 1 >> + fi >> + >> + PORT=`ovs_vsctl --data=bare --no-heading --columns=name find interface \ >> + external_ids:container_id="$CONTAINER" \ >> + external_ids:container_iface="$INTERFACE"` >> + if [ -z "$PORT" ]; then >> + echo >&2 "$UTIL: Failed to find any attached port in $BRIDGE" \ >> + "for CONTAINER=$CONTAINER and INTERFACE=$INTERFACE" >> + exit 1 >> + fi >> + >> + ovs_vsctl --if-exists del-port "$PORT" >> + >> + ip link delete "$PORT" >> +} >> + >> +del_ports () { >> + BRIDGE="$1" >> + CONTAINER="$2" >> + if [ "$#" -lt 2 ]; then >> + usage >> + exit 1 >> + fi >> + >> + PORTS=`ovs_vsctl --data=bare --no-heading --columns=name find interface >> \ >> + external_ids:container_id="$CONTAINER"` >> + if [ -z "$PORTS" ]; then >> + exit 0 >> + fi >> + >> + for PORT in $PORTS; do >> + ovs_vsctl --if-exists del-port "$PORT" >> + ip link delete "$PORT" >> + done >> +} >> + >> +usage() { >> + cat << EOF >> +${UTIL}: Performs integration of Open vSwitch with Docker. >> +usage: ${UTIL} COMMAND >> + >> +Commands: >> + add-port BRIDGE INTERFACE CONTAINER [ADDRESS] >> + Adds INTERFACE inside CONTAINER and connects it as a >> port >> + in Open vSwitch BRIDGE. Optionally, sets ADDRESS on >> + INTERFACE. ADDRESS can include a '/' to represent >> network >> + prefix length. e.g.: >> + ${UTIL} add-port br-int eth1 c474a0e2830e 192.168.1.2/24 >> + del-port BRIDGE INTERFACE CONTAINER >> + Deletes INTERFACE inside CONTAINER and removes its >> + connection to Open vSwitch BRIDGE. e.g.: >> + ${UTIL} del-port br-int eth1 c474a0e2830e >> + del-ports BRIDGE CONTAINER >> + Removes all Open vSwitch interfaces from CONTAINER. >> e.g.: >> + ${UTIL} del-ports br-int c474a0e2830e >> +Options: >> + -h, --help display this help message. >> +EOF >> +} >> + >> +UTIL=$(basename $0) >> +check_command_avail ovs-vsctl docker uuidgen >> + >> +if (ip netns) > /dev/null 2>&1; then :; else >> + echo >&2 "$UTIL: ip utility not found (or it does not support netns),"\ >> + "cannot proceed" >> + exit 1 >> +fi >> + >> +if [ $# -eq 0 ]; then >> + usage >> + exit 0 >> +fi >> + >> +case $1 in >> + "add-port") >> + shift >> + add_port "$@" >> + exit 0 >> + ;; >> + "del-port") >> + shift >> + del_port "$@" >> + exit 0 >> + ;; >> + "del-ports") >> + shift >> + del_ports "$@" >> + exit 0 >> + ;; >> + -h | --help) >> + usage >> + exit 0 >> + ;; >> + *) >> + echo >&2 "$UTIL: unknown command \"$1\" (use --help for help)" >> + exit 1 >> + ;; >> +esac >> -- >> 1.9.1 >> >> _______________________________________________ >> dev mailing list >> dev@openvswitch.org >> http://openvswitch.org/mailman/listinfo/dev >> _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev