forked from openvswitch/ovs
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
docker: Integrate docker containers with Open vSwitch.
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 <[email protected]> Acked-by: Ben Pfaff <[email protected]>
- Loading branch information
Showing
9 changed files
with
294 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 [email protected]. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
for signal in 1 2 3 13 14 15; do | ||
trap 'delete_netns_link; trap - $signal; kill -$signal $$' $signal | ||
done | ||
fi | ||
} | ||
|
||
delete_netns_link () { | ||
rm -f /var/run/netns/"$PID" | ||
} | ||
|
||
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 |