]>
Commit | Line | Data |
---|---|---|
9fb4636f GS |
1 | Integration of Containers with OVN and OpenStack |
2 | ------------------------------------------------ | |
3 | ||
4 | Isolation between containers is weaker than isolation between VMs, so | |
5 | some environments deploy containers for different tenants in separate | |
6 | VMs as an additional security measure. This document describes creation of | |
7 | containers inside VMs and how they can be made part of the logical networks | |
8 | securely. The created logical network can include VMs, containers and | |
9 | physical machines as endpoints. To better understand the proposed integration | |
10 | of containers with OVN and OpenStack, this document describes the end to end | |
11 | workflow with an example. | |
12 | ||
13 | * A OpenStack tenant creates a VM (say VM-A) with a single network interface | |
14 | that belongs to a management logical network. The VM is meant to host | |
15 | containers. OpenStack Nova chooses the hypervisor on which VM-A is created. | |
16 | ||
17 | * A Neutron port may have been created in advance and passed in to Nova | |
18 | with the request to create a new VM. If not, Nova will issue a request | |
19 | to Neutron to create a new port. The ID of the logical port from | |
20 | Neutron will also be used as the vif-id for the virtual network | |
21 | interface (VIF) of VM-A. | |
22 | ||
23 | * When VM-A is created on a hypervisor, its VIF gets added to the | |
24 | Open vSwitch integration bridge. This creates a row in the Interface table | |
25 | of the Open_vSwitch database. As explained in the [IntegrationGuide.md], | |
26 | the vif-id associated with the VM network interface gets added in the | |
27 | external_ids:iface-id column of the newly created row in the Interface table. | |
28 | ||
29 | * Since VM-A belongs to a logical network, it gets an IP address. This IP | |
30 | address is used to spawn containers (either manually or through container | |
31 | orchestration systems) inside that VM and to monitor the health of the | |
32 | created containers. | |
33 | ||
34 | * The vif-id associated with the VM's network interface can be obtained by | |
35 | making a call to Neutron using tenant credentials. | |
36 | ||
37 | * This flow assumes a component called a "container network plugin". | |
38 | If you take Docker as an example for containers, you could envision | |
39 | the plugin to be either a wrapper around Docker or a feature of Docker itself | |
40 | that understands how to perform part of this workflow to get a container | |
41 | connected to a logical network managed by Neutron. The rest of the flow | |
42 | refers to this logical component that does not yet exist as the | |
43 | "container network plugin". | |
44 | ||
45 | * All the calls to Neutron will need tenant credentials. These calls can | |
46 | either be made from inside the tenant VM as part of a container network plugin | |
47 | or from outside the tenant VM (if the tenant is not comfortable using temporary | |
48 | Keystone tokens from inside the tenant VMs). For simplicity, this document | |
49 | explains the work flow using the former method. | |
50 | ||
51 | * The container hosting VM will need Open vSwitch installed in it. The only | |
52 | work for Open vSwitch inside the VM is to tag network traffic coming from | |
53 | containers. | |
54 | ||
55 | * When a container needs to be created inside the VM with a container network | |
56 | interface that is expected to be attached to a particular logical switch, the | |
57 | network plugin in that VM chooses any unused VLAN (This VLAN tag only needs to | |
58 | be unique inside that VM. This limits the number of container interfaces to | |
59 | 4096 inside a single VM). This VLAN tag is stripped out in the hypervisor | |
60 | by OVN and is only useful as a context (or metadata) for OVN. | |
61 | ||
62 | * The container network plugin then makes a call to Neutron to create a | |
63 | logical port. In addition to all the inputs that a call to create a port in | |
64 | Neutron that are currently needed, it sends the vif-id and the VLAN tag as | |
65 | inputs. | |
66 | ||
67 | * Neutron in turn will verify that the vif-id belongs to the tenant in question | |
68 | and then uses the OVN specific plugin to create a new row in the Logical_Port | |
69 | table of the OVN Northbound Database. Neutron responds back with an | |
70 | IP address and MAC address for that network interface. So Neutron becomes | |
71 | the IPAM system and provides unique IP and MAC addresses across VMs and | |
72 | containers in the same logical network. | |
73 | ||
74 | * The Neutron API call above to create a logical port for the container | |
75 | could add a relatively significant amount of time to container creation. | |
76 | However, an optimization is possible here. Logical ports could be | |
77 | created in advance and reused by the container system doing container | |
78 | orchestration. Additional Neutron API calls would only be needed if the | |
79 | port needs to be attached to a different logical network. | |
80 | ||
81 | * When a container is eventually deleted, the network plugin in that VM | |
82 | may make a call to Neutron to delete that port. Neutron in turn will | |
83 | delete the entry in the Logical_Port table of the OVN Northbound Database. | |
84 | ||
85 | As an example, consider Docker containers. Since Docker currently does not | |
86 | have a network plugin feature, this example uses a hypothetical wrapper | |
87 | around Docker to make calls to Neutron. | |
88 | ||
89 | * Create a Logical switch, e.g.: | |
90 | ||
91 | ``` | |
92 | % ovn-docker --cred=cca86bd13a564ac2a63ddf14bf45d37f create network LS1 | |
93 | ``` | |
94 | ||
95 | The above command will make a call to Neutron with the credentials to create | |
96 | a logical switch. The above is optional if the logical switch has already | |
97 | been created from outside the VM. | |
98 | ||
99 | * List networks available to the tenant. | |
100 | ||
101 | ``` | |
102 | % ovn-docker --cred=cca86bd13a564ac2a63ddf14bf45d37f list networks | |
103 | ``` | |
104 | ||
105 | * Create a container and attach a interface to the previously created switch | |
106 | as a logical port. | |
107 | ||
108 | ``` | |
109 | % ovn-docker --cred=cca86bd13a564ac2a63ddf14bf45d37f --vif-id=$VIF_ID \ | |
110 | --network=LS1 run -d --net=none ubuntu:14.04 /bin/sh -c \ | |
111 | "while true; do echo hello world; sleep 1; done" | |
112 | ``` | |
113 | ||
114 | The above command will make a call to Neutron with all the inputs it currently | |
115 | needs to create a logical port. In addition, it passes the $VIF_ID and a | |
116 | unused VLAN. Neutron will add that information in OVN and return back | |
117 | a MAC address and IP address for that interface. ovn-docker will then create | |
118 | a veth pair, insert one end inside the container as 'eth0' and the other end | |
119 | as a port of a local OVS bridge as an access port of the chosen VLAN. | |
120 | ||
121 | [IntegrationGuide.md]:IntegrationGuide.md |