{"id":129,"date":"2020-05-23T01:30:18","date_gmt":"2020-05-23T01:30:18","guid":{"rendered":"https:\/\/www.vandervecken.com\/faucet\/?p=129"},"modified":"2020-05-23T01:30:18","modified_gmt":"2020-05-23T01:30:18","slug":"connecting-containers-to-faucet","status":"publish","type":"post","link":"https:\/\/faucet.vandervecken.com\/index.php\/2020\/05\/23\/connecting-containers-to-faucet\/","title":{"rendered":"Connecting Containers to Faucet"},"content":{"rendered":"\n<p>One of the installation paths for Faucet is to run inside of a <a href=\"https:\/\/docs.faucet.nz\/en\/latest\/installation.html?highlight=docker#installation-with-docker\">Docker container<\/a> and happily control an OpenFlow network of both physical and virtual switches. However, what about using Faucet to control the network of Docker containers themselves? You might be asking yourself right about now why you would even want to do that though. One of the motivations behind it is to be able to restrict L2 connectivity between containers just like Faucet lets you do with a hardware switch. In a hybrid world where containers, virtual machines, and bare metal servers all have their own MAC addresses and IP addresses on the same network, having a single centralized controller for routing, access control, monitoring, and management of that network makes for an appealing option.<\/p>\n\n\n\n<p>Docker networking is a complex beast and has made different iterations over the years. One of the current patterns that seems to have stuck is the use of <a href=\"https:\/\/www.docker.com\/blog\/understanding-docker-networking-drivers-use-cases\/\">Docker Networking Drivers<\/a>. These drivers are particularly nice because it allows developers to write their own plugins that can be used to create networks that containers attach to, without having to hack, wrap, or otherwise change Docker directly.<\/p>\n\n\n\n<p>One of the early examples of such a driver was from Weaveworks, who wrote <a href=\"https:\/\/github.com\/weaveworks-experiments\/docker-plugin\">this<\/a>, which was the inspiration for other developers and companies to start writing their own plugins that integrated their own variations of networking that folks might want to attach containers to. One such group were the folks behind <a href=\"https:\/\/github.com\/gopher-net\/gopher-net\">gopher-net<\/a> who wrote an <a href=\"https:\/\/github.com\/gopher-net\/docker-ovs-plugin\">Open vSwitch network plugin<\/a> for Docker.<\/p>\n\n\n\n<p>Hey, now we&#8217;re on to something, Faucet already works with Open vSwitch! After taking a poke at the existing code base, now approaching 5 years being stale, it seemed like the right path forward was forking the project and modernizing the packages and making it Faucet friendly. So that&#8217;s exactly what we did. Introducing <a href=\"https:\/\/github.com\/CyberReboot\/dovesnap\">dovesnap<\/a>.<\/p>\n\n\n\n<p>With dovesnap, connecting containers to a Faucet controlled network is a breeze. Dovesnap uses docker-compose to build and start the containers used for Open vSwitch itself and the plugin that interfaces with Docker. The following are the basic steps to get it up and running:<\/p>\n\n\n\n<p>First, make sure you have the Open vSwitch kernel module loaded:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ sudo modprobe openvswitch<\/code><\/pre>\n\n\n\n<p>Next, clone the repo, start the service, and verify that it is up:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ git clone https:\/\/github.com\/cyberreboot\/dovesnap\n$ cd dovesnap\n$ docker-compose up -d --build\n$ docker ps\nCONTAINER ID        IMAGE                  COMMAND                  CREATED             STATUS                    PORTS               NAMES\n2048530e312a        cyberreboot\/dovesnap   \"dovesnap -d\"            11 minutes ago      Up 30 seconds                                 dovesnap_plugin_1_115df2016fd9\nddbd1fcd6148        openvswitch:2.13.0     \"\/usr\/bin\/supervisord\"   11 minutes ago      Up 30 seconds (healthy)                       dovesnap_ovs_1_d0a0cee6f49d<\/code><\/pre>\n\n\n\n<p>Now create a network with our new <code>ovs<\/code> driver (note you can make as many of these as you like as long as they don&#8217;t have overlapping IP space):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ docker network create mynet -d ovs -o ovs.bridge.mode=nat -o ovs.bridge.dpid=0x1 -o ovs.bridge.controller=tcp:127.0.0.1:6653 --subnet 172.12.0.0\/24 --ip-range=172.12.0.8\/29 --gateway=172.12.0.1\n2ce5e00010331ec9115afd0adfc972a3beb530d3086bea20932e5edc85cfa4de<\/code><\/pre>\n\n\n\n<p>In this example we included a lot of options, but the only ones necessary are:<br> <code>-d ovs<\/code> (for the driver)<br> <code>-o ovs.bridge.controller=tcp:127.0.0.1:6653<\/code> (so that it can connect to Faucet)<\/p>\n\n\n\n<p>By default, creating a network with this driver will use &#8220;flat&#8221; mode, which means no natting and you&#8217;ll need to connect a network interface as a port on the OVS bridge for routing (i.e. <code>-o ovs.bridge.add_ports=enx0023569c0114<\/code>). For this example, we chose the &#8220;nat&#8221; mode which will use natting and not require routing from another interface. Additionally, we&#8217;ve supplied the DPID for the bridge making it easy to add to the Faucet config. Lastly, we have set what subnet, IP range, and gateway it should create and use.<\/p>\n\n\n\n<p>Finally with our network created, we can start up containers that are attached to it:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ docker run -td --net=mynet busybox\n205e47b076195513a54b98ea78c4c449c5ac403371508e457a6631f64c0c3596\n$ docker run -td --net=mynet busybox\n8486e5a8dd8df0969a25b934bac8a3ebd7c040a91816403a2e3ddb067e559aa3<\/code><\/pre>\n\n\n\n<p>Once they are started, we can inspect the network to see all of our settings, as well as the IPs that were allocated for the two containers we just created:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ docker network inspect mynet\n&#091;\n    {\n        \"Name\": \"mynet\",\n        \"Id\": \"2ce5e00010331ec9115afd0adfc972a3beb530d3086bea20932e5edc85cfa4de\",\n        \"Created\": \"2020-05-21T13:23:45.13078807+12:00\",\n        \"Scope\": \"local\",\n        \"Driver\": \"ovs\",\n        \"EnableIPv6\": false,\n        \"IPAM\": {\n            \"Driver\": \"default\",\n            \"Options\": {},\n            \"Config\": &#091;\n                {\n                    \"Subnet\": \"172.12.0.0\/24\",\n                    \"IPRange\": \"172.12.0.8\/29\",\n                    \"Gateway\": \"172.12.0.1\"\n                }\n            ]\n        },\n        \"Internal\": false,\n        \"Attachable\": false,\n        \"Ingress\": false,\n        \"ConfigFrom\": {\n            \"Network\": \"\"\n        },\n        \"ConfigOnly\": false,\n        \"Containers\": {\n            \"205e47b076195513a54b98ea78c4c449c5ac403371508e457a6631f64c0c3596\": {\n                \"Name\": \"cool_hawking\",\n                \"EndpointID\": \"3190227dd6ae96568c18101cbbd55c11b0b9d62fd907784d29b64cc8df7ce1b7\",\n                \"MacAddress\": \"\",\n                \"IPv4Address\": \"172.12.0.8\/24\",\n                \"IPv6Address\": \"\"\n            },\n            \"8486e5a8dd8df0969a25b934bac8a3ebd7c040a91816403a2e3ddb067e559aa3\": {\n                \"Name\": \"vibrant_haibt\",\n                \"EndpointID\": \"7154d47c2db8820990538c9a673a319c0c0c4afd32e18d68fa878f1ce5a723b0\",\n                \"MacAddress\": \"\",\n                \"IPv4Address\": \"172.12.0.9\/24\",\n                \"IPv6Address\": \"\"\n            }\n        },\n        \"Options\": {\n            \"ovs.bridge.controller\": \"tcp:127.0.0.1:6653\",\n            \"ovs.bridge.dpid\": \"0x1\",\n            \"ovs.bridge.mode\": \"nat\"\n        },\n        \"Labels\": {}\n    }\n]<\/code><\/pre>\n\n\n\n<p>If we go into one of the containers we can also verify the network matches what we expect:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$ docker exec -ti 8486e5a8dd8d ifconfig\neth0      Link encap:Ethernet  HWaddr DE:BC:94:F9:63:33\n          inet addr:172.12.0.9  Bcast:172.12.0.255  Mask:255.255.255.0\n          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1\n          RX packets:9 errors:0 dropped:0 overruns:0 frame:0\n          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0\n          collisions:0 txqueuelen:0\n          RX bytes:726 (726.0 B)  TX bytes:0 (0.0 B)<\/code><\/pre>\n\n\n\n<p>Here&#8217;s an example minimal <code>faucet.yaml<\/code> that connects the OVS bridge to Faucet. We&#8217;ve supplied a range of 10 ports on the same native VLAN, which the first 10 containers attached to the network will get assigned to.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>dps:\n  docker-ovs:\n    dp_id: 0x1\n    hardware: Open vSwitch\n    interfaces:\n      0xfffffffe:\n        native_vlan: 100\n    interface_ranges:\n      1-10:\n        native_vlan: 100<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code>Note: the interface 0xfffffffe is needed specifically for only the \"nat\" mode of our plugin with OVS. <\/code><\/pre>\n\n\n\n<p>Now you can monitor and control the network your containers use with Faucet!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>One of the installation paths for Faucet is to run inside of a Docker container and happily control an OpenFlow network of both physical and virtual switches. However, what about using Faucet to control the network of Docker containers themselves? You might be asking yourself right about now why you would even want to do &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/faucet.vandervecken.com\/index.php\/2020\/05\/23\/connecting-containers-to-faucet\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Connecting Containers to Faucet&#8221;<\/span><\/a><\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-129","post","type-post","status-publish","format-standard","hentry","category-uncategorised","entry"],"_links":{"self":[{"href":"https:\/\/faucet.vandervecken.com\/index.php\/wp-json\/wp\/v2\/posts\/129","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/faucet.vandervecken.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/faucet.vandervecken.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/faucet.vandervecken.com\/index.php\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/faucet.vandervecken.com\/index.php\/wp-json\/wp\/v2\/comments?post=129"}],"version-history":[{"count":3,"href":"https:\/\/faucet.vandervecken.com\/index.php\/wp-json\/wp\/v2\/posts\/129\/revisions"}],"predecessor-version":[{"id":132,"href":"https:\/\/faucet.vandervecken.com\/index.php\/wp-json\/wp\/v2\/posts\/129\/revisions\/132"}],"wp:attachment":[{"href":"https:\/\/faucet.vandervecken.com\/index.php\/wp-json\/wp\/v2\/media?parent=129"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/faucet.vandervecken.com\/index.php\/wp-json\/wp\/v2\/categories?post=129"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/faucet.vandervecken.com\/index.php\/wp-json\/wp\/v2\/tags?post=129"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}