github.com/Heebron/moby@v0.0.0-20221111184709-6eab4f55faf7/libnetwork/docs/remote.md (about)

     1  Remote Drivers
     2  ==============
     3  
     4  The `drivers.remote` package provides the integration point for dynamically-registered drivers. Unlike the other driver packages, it does not provide a single implementation of a driver; rather, it provides a proxy for remote driver processes, which are registered and communicate with LibNetwork via the Docker plugin package.
     5  
     6  For the semantics of driver methods, which correspond to the protocol below, please see the [overall design](design.md).
     7  
     8  ## LibNetwork integration with the Docker `plugins` package
     9  
    10  When LibNetwork initializes the `drivers.remote` package with the `Init()` function, it passes a `DriverCallback` as a parameter, which implements `RegisterDriver()`. The remote driver package uses this interface to register remote drivers with LibNetwork's `NetworkController`, by supplying it in a `plugins.Handle` callback.
    11  
    12  The callback is invoked when a driver is loaded with the `plugins.Get` API call. How that comes about is out of scope here (but it might be, for instance, when that driver is mentioned by the user).
    13  
    14  This design ensures that the details of driver registration mechanism are owned by the remote driver package, and it doesn't expose any of the driver layer to the North of LibNetwork.
    15  
    16  ## Implementation
    17  
    18  The remote driver implementation uses a `plugins.Client` to communicate with the remote driver process. The `driverapi.Driver` methods are implemented as RPCs over the plugin client.
    19  
    20  The payloads of these RPCs are mostly direct translations into JSON of the arguments given to the method. There are some exceptions to account for the use of the interfaces `InterfaceInfo` and `JoinInfo`, and data types that do not serialise to JSON well (e.g., `net.IPNet`). The protocol is detailed below under "Protocol".
    21  
    22  ## Usage
    23  
    24  A remote driver proxy follows all the rules of any other in-built driver and has exactly the same `Driver` interface exposed. LibNetwork will also support driver-specific `options` and user-supplied `labels` which may influence the behaviour of a remote driver process.
    25  
    26  ## Protocol
    27  
    28  The remote driver protocol is a set of RPCs, issued as HTTP POSTs with JSON payloads. The proxy issues requests, and the remote driver process is expected to respond usually with a JSON payload of its own, although in some cases these are empty maps.
    29  
    30  ### Errors
    31  
    32  If the remote process cannot decode, or otherwise detects a syntactic problem with the HTTP request or payload, it must respond with an HTTP error status (4xx or 5xx).
    33  
    34  If the remote process http server receives a request for an unknown URI, it should respond with the HTTP StatusCode `404 Not Found`. This allows LibNetwork to detect when a remote driver does not implement yet a newly added method, therefore not to deem the request as failed.
    35  
    36  If the remote process can decode the request, but cannot complete the operation, it must send a response in the form
    37  
    38      {
    39  		"Err": string
    40      }
    41  
    42  The string value supplied may appear in logs, so should not include confidential information.
    43  
    44  ### Handshake
    45  
    46  When loaded, a remote driver process receives an HTTP POST on the URL `/Plugin.Activate` with no payload. It must respond with a manifest of the form
    47  
    48      {
    49  		"Implements": ["NetworkDriver"]
    50      }
    51  
    52  Other entries in the list value are allowed; `"NetworkDriver"` indicates that the plugin should be registered with LibNetwork as a driver.
    53  
    54  ### Set capability
    55  
    56  After Handshake, the remote driver will receive another POST message to the URL `/NetworkDriver.GetCapabilities` with no payload. The driver's response should have the form:
    57  
    58  	{
    59  		"Scope":             "local"
    60  		"ConnectivityScope": "global"
    61  	}
    62  
    63  Value of "Scope" should be either "local" or "global" which indicates whether the resource allocations for this driver's network can be done only locally to the node or globally across the cluster of nodes. Any other value will fail driver's registration and return an error to the caller.
    64  Similarly, value of "ConnectivityScope" should be either "local" or "global" which indicates whether the driver's network can provide connectivity only locally to this node or globally across the cluster of nodes. If the value is missing, libnetwork will set it to the value of "Scope". should be either "local" or "global" which indicates
    65  
    66  ### Create network
    67  
    68  When the proxy is asked to create a network, the remote process shall receive a POST to the URL `/NetworkDriver.CreateNetwork` of the form
    69  
    70      {
    71  		"NetworkID": string,
    72  		"IPv4Data" : [
    73  		{
    74  			"AddressSpace": string,
    75  			"Pool": ipv4-cidr-string,
    76  			"Gateway" : ipv4-cidr-string,
    77  			"AuxAddresses": {
    78  				"<identifier1>" : "<ipv4-address1>",
    79  				"<identifier2>" : "<ipv4-address2>",
    80  				...
    81  			}
    82  		},
    83  		],
    84  		"IPv6Data" : [
    85  		{
    86  			"AddressSpace": string,
    87  			"Pool": ipv6-cidr-string,
    88  			"Gateway" : ipv6-cidr-string,
    89  			"AuxAddresses": {
    90  				"<identifier1>" : "<ipv6-address1>",
    91  				"<identifier2>" : "<ipv6-address2>",
    92  				...
    93  			}
    94  		},
    95  		],
    96  		"Options": {
    97  			...
    98  		}
    99      }
   100  
   101  * `NetworkID` value is generated by LibNetwork which represents a unique network. 
   102  * `Options` value is the arbitrary map given to the proxy by LibNetwork. 
   103  * `IPv4Data` and `IPv6Data` are the ip-addressing data configured by the user and managed by IPAM driver. The network driver is expected to honor the ip-addressing data supplied by IPAM driver. The data include,
   104  * `AddressSpace` : A unique string represents an isolated space for IP Addressing 
   105  * `Pool` : A range of IP Addresses represented in CIDR format address/mask. Since, the IPAM driver is responsible for allocating container ip-addresses, the network driver can make use of this information for the network plumbing purposes.
   106  * `Gateway` : Optionally, the IPAM driver may provide a Gateway IP address in CIDR format for the subnet represented by the Pool. The network driver can make use of this information for the network plumbing purposes.
   107  * `AuxAddresses` : A list of pre-allocated ip-addresses with an associated identifier as provided by the user to assist network driver if it requires specific ip-addresses for its operation.
   108  
   109  The response indicating success is empty:
   110  
   111      {}
   112  
   113  ### Delete network
   114  
   115  When a network owned by the remote driver is deleted, the remote process shall receive a POST to the URL `/NetworkDriver.DeleteNetwork` of the form
   116  
   117      {
   118  		"NetworkID": string
   119      }
   120  
   121  The success response is empty:
   122  
   123      {}
   124  
   125  ### Create endpoint
   126  
   127  When the proxy is asked to create an endpoint, the remote process shall receive a POST to the URL `/NetworkDriver.CreateEndpoint` of the form
   128  
   129      {
   130  		"NetworkID": string,
   131  		"EndpointID": string,
   132  		"Options": {
   133  			...
   134  		},
   135  		"Interface": {
   136  			"Address": string,
   137  			"AddressIPv6": string,
   138  			"MacAddress": string
   139  		}
   140      }
   141  
   142  The `NetworkID` is the generated identifier for the network to which the endpoint belongs; the `EndpointID` is a generated identifier for the endpoint.
   143  
   144  `Options` is an arbitrary map as supplied to the proxy.
   145  
   146  The `Interface` value is of the form given. The fields in the `Interface` may be empty; and the `Interface` itself may be empty. If supplied, `Address` is an IPv4 address and subnet in CIDR notation; e.g., `"192.168.34.12/16"`. If supplied, `AddressIPv6` is an IPv6 address and subnet in CIDR notation. `MacAddress` is a MAC address as a string; e.g., `"6e:75:32:60:44:c9"`.
   147  
   148  A success response is of the form
   149  
   150      {
   151  		"Interface": {
   152  			"Address": string,
   153  			"AddressIPv6": string,
   154  			"MacAddress": string
   155  		}
   156      }
   157  
   158  with values in the `Interface` as above. As far as the value of `Interface` is concerned, `MacAddress` and either or both of `Address` and `AddressIPv6` must be given.
   159  
   160  If the remote process was supplied a non-empty value in `Interface`, it must respond with an empty `Interface` value. LibNetwork will treat it as an error if it supplies a non-empty value and receives a non-empty value back, and roll back the operation.
   161  
   162  ### Endpoint operational info
   163  
   164  The proxy may be asked for "operational info" on an endpoint. When this happens, the remote process shall receive a POST to `/NetworkDriver.EndpointOperInfo` of the form
   165  
   166      {
   167  		"NetworkID": string,
   168  		"EndpointID": string
   169      }
   170  
   171  where `NetworkID` and `EndpointID` have meanings as above. It must send a response of the form
   172  
   173      {
   174  		"Value": { ... }
   175      }
   176  
   177  where the value of the `Value` field is an arbitrary (possibly empty) map.
   178  
   179  ### Delete endpoint
   180  
   181  When an endpoint is deleted, the remote process shall receive a POST to the URL `/NetworkDriver.DeleteEndpoint` with a body of the form
   182  
   183      {
   184  		"NetworkID": string,
   185  		"EndpointID": string
   186      }
   187  
   188  where `NetworkID` and `EndpointID` have meanings as above. A success response is empty:
   189  
   190      {}
   191  
   192  ### Join
   193  
   194  When a sandbox is given an endpoint, the remote process shall receive a POST to the URL `NetworkDriver.Join` of the form
   195  
   196      {
   197  		"NetworkID": string,
   198  		"EndpointID": string,
   199  		"SandboxKey": string,
   200  		"Options": { ... }
   201      }
   202  
   203  The `NetworkID` and `EndpointID` have meanings as above. The `SandboxKey` identifies the sandbox. `Options` is an arbitrary map as supplied to the proxy.
   204  
   205  The response must have the form
   206  
   207      {
   208  		"InterfaceName": {
   209  			SrcName: string,
   210  			DstPrefix: string
   211  		},
   212  		"Gateway": string,
   213  		"GatewayIPv6": string,
   214  		"StaticRoutes": [{
   215  			"Destination": string,
   216  			"RouteType": int,
   217  			"NextHop": string,
   218  		}, ...]
   219      }
   220  
   221  `Gateway` is optional and if supplied is an IP address as a string; e.g., `"192.168.0.1"`. `GatewayIPv6` is optional and if supplied is an IPv6 address as a string; e.g., `"fe80::7809:baff:fec6:7744"`.
   222  
   223  The entries in `InterfaceName` represent actual OS level interfaces that should be moved by LibNetwork into the sandbox; the `SrcName` is the name of the OS level interface that the remote process created, and the `DstPrefix` is a prefix for the name the OS level interface should have after it has been moved into the sandbox (LibNetwork will append an index to make sure the actual name does not collide with others).
   224  
   225  The entries in `"StaticRoutes"` represent routes that should be added to an interface once it has been moved into the sandbox. Since there may be zero or more routes for an interface, unlike the interface name they can be supplied in any order.
   226  
   227  Routes are either given a `RouteType` of `0` and a value for `NextHop`; or, a `RouteType` of `1` and no value for `NextHop`, meaning a connected route.
   228  
   229  If no gateway and no default static route is set by the driver in the Join response, LibNetwork will add an additional interface to the sandbox connecting to a default gateway network (a bridge network named *docker_gwbridge*) and program the default gateway into the sandbox accordingly, pointing to the interface address of the bridge *docker_gwbridge*.
   230  
   231  ### Leave
   232  
   233  If the proxy is asked to remove an endpoint from a sandbox, the remote process shall receive a POST to the URL `/NetworkDriver.Leave` of the form
   234  
   235      {
   236  		"NetworkID": string,
   237  		"EndpointID": string
   238      }
   239  
   240  where `NetworkID` and `EndpointID` have meanings as above. The success response is empty:
   241  
   242      {}
   243  
   244  ### DiscoverNew Notification
   245  
   246  LibNetwork listens to inbuilt docker discovery notifications and passes it along to the interested drivers. 
   247  
   248  When the proxy receives a DiscoverNew notification, the remote process shall receive a POST to the URL `/NetworkDriver.DiscoverNew` of the form
   249  
   250      {
   251  		"DiscoveryType": int,
   252  		"DiscoveryData": {
   253  			...
   254  		}
   255      }
   256  
   257  `DiscoveryType` represents the discovery type. Each Discovery Type is represented by a number.
   258  `DiscoveryData` carries discovery data the structure of which is determined by the DiscoveryType
   259  
   260  The response indicating success is empty:
   261  
   262      {}
   263  
   264  *  Node Discovery
   265  
   266  Node Discovery is represented by a `DiscoveryType` value of `1` and the corresponding `DiscoveryData` will carry Node discovery data.
   267  
   268      {
   269  		"DiscoveryType": int,
   270  		"DiscoveryData": {
   271                      "Address" : string
   272                      "self" : bool
   273  		}
   274      }
   275  
   276  ### DiscoverDelete Notification
   277  
   278  When the proxy receives a DiscoverDelete notification, the remote process shall receive a POST to the URL `/NetworkDriver.DiscoverDelete` of the form
   279  
   280      {
   281  		"DiscoveryType": int,
   282  		"DiscoveryData": {
   283  			...
   284  		}
   285      }
   286  
   287  `DiscoveryType` represents the discovery type. Each Discovery Type is represented by a number.
   288  `DiscoveryData` carries discovery data the structure of which is determined by the DiscoveryType
   289  
   290  The response indicating success is empty:
   291  
   292      {}
   293  
   294  * Node Discovery
   295  
   296  Similar to the DiscoverNew call, Node Discovery is represented by a `DiscoveryType` value of `1` and the corresponding `DiscoveryData` will carry Node discovery data to be deleted.
   297  
   298      {
   299  		"DiscoveryType": int,
   300  		"DiscoveryData": {
   301                      "Address" : string
   302                      "self" : bool
   303  		}
   304      }