Merge "Delete and move outdated docs"
This commit is contained in:
commit
1996d2b144
@ -35,10 +35,7 @@ Programming HowTos and Tutorials
|
||||
:maxdepth: 4
|
||||
|
||||
goals_and_use_cases
|
||||
libnetwork_remote_driver_design
|
||||
kuryr_mitaka_milestone
|
||||
k8s_api_watcher_design
|
||||
|
||||
|
||||
Indices and tables
|
||||
------------------
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,398 +0,0 @@
|
||||
=======================================
|
||||
Libnetwork Remote Network Driver Design
|
||||
=======================================
|
||||
|
||||
What is Kuryr
|
||||
-------------
|
||||
|
||||
Kuryr implements a `libnetwork remote network driver <https://github.com/docker/libnetwork/blob/master/docs/remote.md>`_
|
||||
and maps its calls to OpenStack `Neutron <https://wiki.openstack.org/wiki/Neutron>`_.
|
||||
It works as a translator between libnetwork's `Container Network Model <https://github.com/docker/libnetwork/blob/master/docs/design.md#the-container-network-model>`_ (CNM) and `Neutron's networking model <https://wiki.openstack.org/wiki/Neutron/APIv2-specification>`_.
|
||||
Kuryr also acts as a `libnetwork IPAM driver <https://github.com/docker/libnetwork/blob/master/docs/ipam.md>`_.
|
||||
|
||||
Goal
|
||||
~~~~
|
||||
|
||||
Through Kuryr any Neutron plugin can be used as libnetwork backend with no
|
||||
additional effort. Neutron APIs are vendor agnostic and thus all Neutron
|
||||
plugins will have the capability of providing the networking backend of Docker
|
||||
for a similar small plugging snippet as they have in nova.
|
||||
|
||||
Kuryr also takes care of binding one of a veth pair to a network interface on
|
||||
the host, e.g., Linux bridge, Open vSwitch datapath and so on.
|
||||
|
||||
|
||||
Kuryr Workflow - Host Networking
|
||||
--------------------------------
|
||||
Kuryr resides in each host that runs Docker containers and serves `APIs <https://github.com/docker/libnetwork/blob/master/docs/design.md#api>`_
|
||||
required for the libnetwork remote network driver. It is planned to use the
|
||||
`Adding tags to resources <https://review.openstack.org/#/c/216021/>`_
|
||||
new Neutron feature by Kuryr, to map between
|
||||
Neutron resource Id's and Docker Id's (UUID's)
|
||||
|
||||
1. libnetwork discovers Kuryr via `plugin discovery mechanism <https://github.com/docker/docker/blob/master/docs/extend/plugin_api.md#plugin-discovery>`_ *before the first request is made*
|
||||
|
||||
- During this process libnetwork makes a HTTP POST call on
|
||||
``/Plugin.Activate`` and examines the driver type, which defaults to
|
||||
``"NetworkDriver"`` and ``"IpamDriver"``
|
||||
- libnetwork also calls the following two API endpoints
|
||||
|
||||
1. ``/NetworkDriver.GetCapabilities`` to obtain the capability of Kuryr
|
||||
which defaults to ``"local"``
|
||||
2. ``/IpamDriver.GetDefaultAddressSpcaces`` to get the default address
|
||||
spaces used for the IPAM
|
||||
|
||||
2. libnetwork registers Kuryr as a remote driver
|
||||
|
||||
3. A user makes requests against libnetwork with the network driver specifier for Kuryr
|
||||
|
||||
- i.e., ``--driver=kuryr`` or ``-d kuryr`` **and** ``--ipam-driver=kuryr``
|
||||
for the Docker CLI
|
||||
|
||||
4. libnetwork makes API calls against Kuryr
|
||||
|
||||
5. Kuryr receives the requests and calls Neutron APIs with `Neutron client <http://docs.openstack.org/developer/python-neutronclient/>`_
|
||||
|
||||
6. Kuryr receives the responses from Neutron and compose the responses for
|
||||
libnetwork
|
||||
|
||||
7. Kuryr returns the responses to libnetwork
|
||||
|
||||
8. libnetwork stores the returned information to its key/value datastore
|
||||
backend
|
||||
|
||||
- the key/value datastore is abstracted by `libkv <https://github.com/docker/libkv>`_
|
||||
|
||||
|
||||
Libnetwork User Workflow (with Kuryr as remote network driver) - Host Networking
|
||||
---------------------------------------------------------------------------------
|
||||
1. A user creates a network ``foo`` with the subnet information::
|
||||
|
||||
$ sudo docker network create --driver=kuryr --ipam-driver=kuryr \
|
||||
--subnet 10.0.0.0/16 --gateway 10.0.0.1 --ip-range 10.0.0.0/24 foo
|
||||
286eddb51ebca09339cb17aaec05e48ffe60659ced6f3fc41b020b0eb506d364
|
||||
|
||||
This makes a HTTP POST call on ``/IpamDriver.RequestPool`` with the following
|
||||
JSON data::
|
||||
|
||||
{
|
||||
"AddressSpace": "global_scope",
|
||||
"Pool": "10.0.0.0/16",
|
||||
"SubPool": "10.0.0.0/24",
|
||||
"Options": {},
|
||||
"V6": false
|
||||
}
|
||||
|
||||
The value of ``SubPool`` comes from the value specified in ``--ip-range``
|
||||
option in the command above and value of ``AddressSpace`` will be ``global_scope`` or ``local_scope`` depending on value of ``capability_scope`` configuration option. Kuryr creates a subnetpool, and then returns
|
||||
the following response::
|
||||
|
||||
{
|
||||
"PoolID": "941f790073c3a2c70099ea527ee3a6205e037e84749f2c6e8a5287d9c62fd376",
|
||||
"Pool": "10.0.0.0/24",
|
||||
}
|
||||
|
||||
If the ``--gateway`` was specified like the command above, another HTTP POST
|
||||
call against ``/IpamDriver.RequestAddress`` follows with the JSON data below::
|
||||
|
||||
{
|
||||
"Address": "10.0.0.1",
|
||||
"PoolID": "941f790073c3a2c70099ea527ee3a6205e037e84749f2c6e8a5287d9c62fd376",
|
||||
"Options": {"RequestAddressType": "com.docker.network.gateway"},
|
||||
}
|
||||
|
||||
As the IPAM driver Kuryr allocates a requested IP address and returns the
|
||||
following response::
|
||||
|
||||
{
|
||||
"Address": "10.0.0.1/24",
|
||||
"Data": {}
|
||||
}
|
||||
|
||||
Finally a HTTP POST call on ``/NetworkDriver.CreateNetwork`` with the
|
||||
following JSON data::
|
||||
|
||||
{
|
||||
"NetworkID": "286eddb51ebca09339cb17aaec05e48ffe60659ced6f3fc41b020b0eb506d364",
|
||||
"IPv4Data": [{
|
||||
"Pool": "10.0.0.0/24",
|
||||
"Gateway": "10.0.0.1/24",
|
||||
"AddressSpace": ""
|
||||
}],
|
||||
"IPv6Data": [],
|
||||
"Options": {"com.docker.network.enable_ipv6", false, "com.docker.network.generic": {}}
|
||||
}
|
||||
|
||||
The Kuryr remote network driver will then generate a Neutron API request to
|
||||
create subnet with pool cidr and an underlying Neutron network. When the
|
||||
Neutron subnet and network has been created, the Kuryr remote network driver
|
||||
will generate an empty success response to the docker daemon. Kuryr tags the
|
||||
Neutron network with the NetworkID from docker.
|
||||
|
||||
2. A user launches a container against network ``foo``::
|
||||
|
||||
$ sudo docker run --net=foo -itd --name=container1 busybox
|
||||
78c0458ba00f836f609113dd369b5769527f55bb62b5680d03aa1329eb416703
|
||||
|
||||
This makes a HTTP POST call on ``/IpamDriver.RequestAddress`` with the
|
||||
following JSON data::
|
||||
|
||||
{
|
||||
"Address": "",
|
||||
"PoolID": "941f790073c3a2c70099ea527ee3a6205e037e84749f2c6e8a5287d9c62fd376",
|
||||
"Options": {},
|
||||
}
|
||||
|
||||
The IPAM driver Kuryr sends a port creation request to neutron and returns the following response with neutron provided ip address::
|
||||
|
||||
{
|
||||
"Address": "10.0.0.2/24",
|
||||
"Data": {}
|
||||
}
|
||||
|
||||
|
||||
Then another HTTP POST call on ``/NetworkDriver.CreateEndpoint`` with the
|
||||
following JSON data is made::
|
||||
|
||||
{
|
||||
"NetworkID": "286eddb51ebca09339cb17aaec05e48ffe60659ced6f3fc41b020b0eb506d364",
|
||||
"Interface": {
|
||||
"AddressIPv6": "",
|
||||
"MacAddress": "",
|
||||
"Address": "10.0.0.2/24"
|
||||
},
|
||||
"Options": {
|
||||
"com.docker.network.endpoint.exposedports": [],
|
||||
"com.docker.network.portmap": []
|
||||
},
|
||||
"EndpointID": "edb23d36d77336d780fe25cdb5cf0411e5edd91b0777982b4b28ad125e28a4dd"
|
||||
}
|
||||
|
||||
The Kuryr remote network driver then generates a Neutron API request to
|
||||
fetch port with the matching fields for interface in the request. Kuryr
|
||||
then updates this port's name, tagging it with endpoint ID.
|
||||
|
||||
Following steps are taken:
|
||||
|
||||
1) On the endpoint creation Kuryr examines if there's a Port with CIDR
|
||||
that corresponds to Address or AddressIPv6 requested.
|
||||
2) If there's a Port, Kuryr tries to reuse it without creating a new
|
||||
Port. Otherwise it creates a new one with the given address.
|
||||
3) Kuryr tags the Neutron port with EndpointID.
|
||||
|
||||
When the Neutron port has been updated, the Kuryr remote driver will
|
||||
generate a response to the docker daemon in following form:
|
||||
(https://github.com/docker/libnetwork/blob/master/docs/remote.md#create-endpoint)::
|
||||
|
||||
{
|
||||
"Interface": {"MacAddress": "08:22:e0:a8:7d:db"}
|
||||
}
|
||||
|
||||
|
||||
On receiving success response, libnetwork makes a HTTP POST call on ``/NetworkDriver.Join`` with
|
||||
the following JSON data::
|
||||
|
||||
{
|
||||
"NetworkID": "286eddb51ebca09339cb17aaec05e48ffe60659ced6f3fc41b020b0eb506d364",
|
||||
"SandboxKey": "/var/run/docker/netns/052b9aa6e9cd",
|
||||
"Options": null,
|
||||
"EndpointID": "edb23d36d77336d780fe25cdb5cf0411e5edd91b0777982b4b28ad125e28a4dd"
|
||||
}
|
||||
|
||||
Kuryr connects the container to the corresponding neutron network by doing
|
||||
the following steps:
|
||||
|
||||
1) Generate a veth pair.
|
||||
2) Connect one end of the veth pair to the container (which is running in a
|
||||
namespace that was created by Docker).
|
||||
3) Perform a neutron-port-type-dependent VIF-binding to the corresponding
|
||||
Neutron port using the VIF binding layer and depending on the specific
|
||||
port type.
|
||||
|
||||
After the VIF-binding is completed, the Kuryr remote network driver
|
||||
generates a response to the Docker daemon as specified in the libnetwork
|
||||
documentation for a join request.
|
||||
(https://github.com/docker/libnetwork/blob/master/docs/remote.md#join)
|
||||
|
||||
3. A user requests information about the network::
|
||||
|
||||
$ sudo docker network inspect foo
|
||||
[
|
||||
{
|
||||
"Name": "foo",
|
||||
"Id": "286eddb51ebca09339cb17aaec05e48ffe60659ced6f3fc41b020b0eb506d364",
|
||||
"Scope": "local",
|
||||
"Driver": "kuryr",
|
||||
"EnableIPv6": false,
|
||||
"IPAM": {
|
||||
"Driver": "kuryr",
|
||||
"Options": {},
|
||||
"Config": [{
|
||||
"Subnet": "10.0.0.0/16",
|
||||
"IPRange": "10.0.0.0/24",
|
||||
"Gateway": "10.0.0.1"
|
||||
}]
|
||||
},
|
||||
"Internal": false,
|
||||
"Containers": {
|
||||
"78c0458ba00f836f609113dd369b5769527f55bb62b5680d03aa1329eb416703": {
|
||||
"endpoint": "edb23d36d77336d780fe25cdb5cf0411e5edd91b0777982b4b28ad125e28a4dd",
|
||||
"mac_address": "02:42:c0:a8:7b:cb",
|
||||
"ipv4_address": "10.0.0.2/24",
|
||||
"ipv6_address": ""
|
||||
}
|
||||
},
|
||||
"Options": {},
|
||||
"Labels": {}
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
4. A user connects one more container to the network::
|
||||
|
||||
$ sudo docker network connect foo container2
|
||||
d7fcc280916a8b771d2375688b700b036519d92ba2989622627e641bdde6e646
|
||||
|
||||
$ sudo docker network inspect foo
|
||||
[
|
||||
{
|
||||
"Name": "foo",
|
||||
"Id": "286eddb51ebca09339cb17aaec05e48ffe60659ced6f3fc41b020b0eb506d364",
|
||||
"Scope": "local",
|
||||
"Driver": "kuryr",
|
||||
"EnableIPv6": false,
|
||||
"IPAM": {
|
||||
"Driver": "kuryr",
|
||||
"Options": {},
|
||||
"Config": [{
|
||||
"Subnet": "10.0.0.0/16",
|
||||
"IPRange": "10.0.0.0/24",
|
||||
"Gateway": "10.0.0.1"
|
||||
}]
|
||||
},
|
||||
"Internal": false,
|
||||
"Containers": {
|
||||
"78c0458ba00f836f609113dd369b5769527f55bb62b5680d03aa1329eb416703": {
|
||||
"endpoint": "edb23d36d77336d780fe25cdb5cf0411e5edd91b0777982b4b28ad125e28a4dd",
|
||||
"mac_address": "02:42:c0:a8:7b:cb",
|
||||
"ipv4_address": "10.0.0.2/24",
|
||||
"ipv6_address": ""
|
||||
},
|
||||
"d7fcc280916a8b771d2375688b700b036519d92ba2989622627e641bdde6e646": {
|
||||
"endpoint": "a55976bafaad19f2d455c4516fd3450d3c52d9996a98beb4696dc435a63417fc",
|
||||
"mac_address": "02:42:c0:a8:7b:cc",
|
||||
"ipv4_address": "10.0.0.3/24",
|
||||
"ipv6_address": ""
|
||||
}
|
||||
},
|
||||
"Options": {},
|
||||
"Labels": {}
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
5. A user disconnects a container from the network::
|
||||
|
||||
$ CID=d7fcc280916a8b771d2375688b700b036519d92ba2989622627e641bdde6e646
|
||||
$ sudo docker network disconnect foo $CID
|
||||
|
||||
This makes a HTTP POST call on ``/NetworkDriver.Leave`` with the following
|
||||
JSON data::
|
||||
|
||||
{
|
||||
"NetworkID": "286eddb51ebca09339cb17aaec05e48ffe60659ced6f3fc41b020b0eb506d364",
|
||||
"EndpointID": "a55976bafaad19f2d455c4516fd3450d3c52d9996a98beb4696dc435a63417fc"
|
||||
}
|
||||
|
||||
Kuryr remote network driver will remove the VIF binding between the
|
||||
container and the Neutron port, and generate an empty response to the
|
||||
Docker daemon.
|
||||
|
||||
Then libnetwork makes a HTTP POST call on ``/NetworkDriver.DeleteEndpoint`` with the
|
||||
following JSON data::
|
||||
|
||||
{
|
||||
"NetworkID": "286eddb51ebca09339cb17aaec05e48ffe60659ced6f3fc41b020b0eb506d364",
|
||||
"EndpointID": "a55976bafaad19f2d455c4516fd3450d3c52d9996a98beb4696dc435a63417fc"
|
||||
}
|
||||
|
||||
Kuryr remote network driver generates a Neutron API request to delete the
|
||||
associated Neutron port, in case the relevant port subnet is empty, Kuryr
|
||||
also deletes the subnet object using Neutron API and generate an empty
|
||||
response to the Docker daemon::
|
||||
|
||||
{}
|
||||
|
||||
Finally libnetwork makes a HTTP POST call on ``/IpamDriver.ReleaseAddress``
|
||||
with the following JSON data::
|
||||
|
||||
{
|
||||
"Address": "10.0.0.3",
|
||||
"PoolID": "941f790073c3a2c70099ea527ee3a6205e037e84749f2c6e8a5287d9c62fd376"
|
||||
}
|
||||
|
||||
Kuryr remote IPAM driver generates a Neutron API request to delete the associated Neutron port.
|
||||
As the IPAM driver Kuryr deallocates the IP address and returns the following response::
|
||||
|
||||
{}
|
||||
|
||||
6. A user deletes the network::
|
||||
|
||||
$ sudo docker network rm foo
|
||||
|
||||
This makes a HTTP POST call against ``/NetworkDriver.DeleteNetwork`` with the
|
||||
following JSON data::
|
||||
|
||||
{
|
||||
"NetworkID": "286eddb51ebca09339cb17aaec05e48ffe60659ced6f3fc41b020b0eb506d364"
|
||||
}
|
||||
|
||||
Kuryr remote network driver generates a Neutron API request to delete the
|
||||
corresponding Neutron network and subnets. When the Neutron network and subnets has been deleted,
|
||||
the Kuryr remote network driver generate an empty response to the docker
|
||||
daemon: {}
|
||||
|
||||
Then another HTTP POST call on ``/IpamDriver.ReleasePool`` with the
|
||||
following JSON data is made::
|
||||
|
||||
{
|
||||
"PoolID": "941f790073c3a2c70099ea527ee3a6205e037e84749f2c6e8a5287d9c62fd376"
|
||||
}
|
||||
|
||||
Kuryr delete the corresponding subnetpool and returns the following response::
|
||||
|
||||
{}
|
||||
|
||||
Mapping between the CNM and the Neutron's Networking Model
|
||||
----------------------------------------------------------
|
||||
|
||||
Kuryr communicates with Neutron via `Neutron client <http://docs.openstack.org/developer/python-neutronclient/>`_
|
||||
and bridges between libnetwork and Neutron by translating their networking models.
|
||||
The following table depicts the current mapping between libnetwork and Neutron models:
|
||||
|
||||
===================== ======================
|
||||
libnetwork Neutron
|
||||
===================== ======================
|
||||
Network Network
|
||||
Sandbox Subnet, Port and netns
|
||||
Endpoint Port
|
||||
===================== ======================
|
||||
|
||||
libnetwork's Sandbox and Endpoint can be mapped into Neutron's Subnet and Port,
|
||||
however, Sandbox is invisible from users directly and Endpoint is only the
|
||||
visible and editable resource entity attachable to containers from users'
|
||||
perspective. Sandbox manages information exposed by Endpoint behind the scene
|
||||
automatically.
|
||||
|
||||
|
||||
Notes on implementing the libnetwork remote driver API in Kuryr
|
||||
---------------------------------------------------------------
|
||||
|
||||
1. DiscoverNew Notification:
|
||||
Neutron does not use the information related to discovery of new resources such
|
||||
as new nodes and therefore the implementation of this API method does nothing.
|
||||
|
||||
2. DiscoverDelete Notification:
|
||||
Neutron does not use the information related to discovery of resources such as
|
||||
nodes being deleted and therefore the implementation of this API method does
|
||||
nothing.
|
Loading…
Reference in New Issue
Block a user