github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/libnetwork/docs/ipam.md (about)

     1  # IPAM Driver
     2  
     3  During the Network and Endpoints lifecycle, the CNM model controls the IP address assignment for network and endpoint interfaces via the IPAM driver(s).
     4  Libnetwork has a default, built-in IPAM driver and allows third party IPAM drivers to be dynamically plugged. On network creation, the user can specify which IPAM driver libnetwork needs to use for the network's IP address management. This document explains the APIs with which the IPAM driver needs to comply, and the corresponding HTTPS request/response body relevant for remote drivers.
     5  
     6  
     7  ## Remote IPAM driver
     8  
     9  On the same line of remote network driver registration (see [remote.md](./remote.md) for more details), libnetwork initializes the `ipams.remote` package with the `Init()` function. It passes a `ipamapi.Callback` as a parameter, which implements `RegisterIpamDriver()`. The remote driver package uses this interface to register remote drivers with libnetwork's `NetworkController`, by supplying it in a `plugins.Handle` callback.  The remote drivers register and communicate with libnetwork via the Docker plugin package. The `ipams.remote` provides the proxy for the remote driver processes.
    10  
    11  
    12  ## Protocol
    13  
    14  Communication protocol is the same as the remote network driver.
    15  
    16  ## Handshake
    17  
    18  During driver registration, libnetwork will query the remote driver about the default local and global address spaces strings, and about the driver capabilities.
    19  More detailed information can be found in the respective section in this document.
    20  
    21  ## Datastore Requirements
    22  
    23  It is the remote driver's responsibility to manage its database. 
    24  
    25  ## Ipam Contract
    26  
    27  The remote IPAM driver must serve the following requests:
    28  
    29  - **GetDefaultAddressSpaces**
    30  
    31  - **RequestPool**
    32  
    33  - **ReleasePool**
    34  
    35  - **Request address**
    36  
    37  - **Release address**
    38  
    39  
    40  The following sections explain each of the above requests' semantic, when they are called during network/endpoint lifecycle, and the corresponding payload for remote driver HTTP request/responses.
    41  
    42  
    43  ## IPAM Configuration and flow
    44  
    45  A libnetwork user can provide IPAM related configuration when creating a network, via the `NetworkOptionIpam` setter function. 
    46  
    47  ```go
    48  func NetworkOptionIpam(ipamDriver string, addrSpace string, ipV4 []*IpamConf, ipV6 []*IpamConf, opts map[string]string) NetworkOption
    49  ```
    50  
    51  The caller has to provide the IPAM driver name and may provide the address space and a list of `IpamConf` structures for IPv4 and a list for IPv6. The IPAM driver name is the only mandatory field. If not provided, network creation will fail.
    52  
    53  In the list of configurations, each element has the following form:
    54  
    55  ```go
    56  // IpamConf contains all the ipam related configurations for a network
    57  type IpamConf struct {
    58  	// The master address pool for containers and network interfaces
    59  	PreferredPool string
    60  	// A subset of the master pool. If specified,
    61  	// this becomes the container pool
    62  	SubPool string
    63  	// Input options for IPAM Driver (optional)
    64  	Options map[string]string
    65  	// Preferred Network Gateway address (optional)
    66  	Gateway string
    67  	// Auxiliary addresses for network driver. Must be within the master pool.
    68  	// libnetwork will reserve them if they fall into the container pool
    69  	AuxAddresses map[string]string
    70  }
    71  ```
    72  
    73  On network creation, libnetwork will iterate the list and perform the following requests to the IPAM driver:
    74  
    75  1. Request the address pool and pass the options along via `RequestPool()`.
    76  2. Request the network gateway address if specified. Otherwise request any address from the pool to be used as network gateway. This is done via `RequestAddress()`.
    77  3. Request each of the specified auxiliary addresses via `RequestAddress()`.
    78  
    79  If the list of IPv4 configurations is empty, libnetwork will automatically add one empty `IpamConf` structure. This will cause libnetwork to request IPAM driver an IPv4 address pool of the driver's choice on the configured address space, if specified, or on the IPAM driver default address space otherwise. If the IPAM driver is not able to provide an address pool, network creation will fail.
    80  If the list of IPv6 configurations is empty, libnetwork will not take any action.
    81  The data retrieved from the IPAM driver during the execution of point 1) to 3) will be stored in the network structure as a list of `IpamInfo` structures for IPv4 and a list for IPv6.
    82  
    83  On endpoint creation, libnetwork will iterate over the list of configs and perform the following operation:
    84  
    85  1. Request an IPv4 address from the IPv4 pool and assign it to the endpoint interface IPv4 address. If successful, stop iterating.
    86  2. Request an IPv6 address from the IPv6 pool (if exists) and assign it to the endpoint interface IPv6 address. If successful, stop iterating.
    87  
    88  Endpoint creation will fail if any of the above operation does not succeed
    89  
    90  On endpoint deletion, libnetwork will perform the following operations:
    91  
    92  1. Release the endpoint interface IPv4 address
    93  2. Release the endpoint interface IPv6 address if present
    94  
    95  On network deletion, libnetwork will iterate the list of `IpamData` structures and perform the following requests to ipam driver:
    96  
    97  1. Release the network gateway address via `ReleaseAddress()`
    98  2. Release each of the auxiliary addresses via `ReleaseAddress()`
    99  3. Release the pool via `ReleasePool()`
   100  
   101  ### GetDefaultAddressSpaces
   102  
   103  GetDefaultAddressSpaces returns the default local and global address space names for this IPAM. An address space is a set of non-overlapping address pools isolated from other address spaces' pools. In other words, same pool can exist on N different address spaces. An address space naturally maps to a tenant name. 
   104  In libnetwork, the meaning associated to `local` or `global` address space is that a local address space doesn't need to get synchronized across the
   105  cluster whereas the global address spaces does. Unless specified otherwise in the IPAM configuration, libnetwork will request address pools from the default local or default global address space based on the scope of the network being created. For example, if not specified otherwise in the configuration, libnetwork will request address pool from the default local address space for a bridge network, whereas from the default global address space for an overlay network.
   106  
   107  During registration, the remote driver will receive a POST message to the URL `/IpamDriver.GetDefaultAddressSpaces` with no payload. The driver's response should have the form:
   108  
   109  
   110  	{
   111  		"LocalDefaultAddressSpace": string
   112  		"GlobalDefaultAddressSpace": string
   113  	}
   114  
   115  
   116  
   117  ### RequestPool
   118  
   119  This API is for registering an address pool with the IPAM driver. Multiple identical calls must return the same result.
   120  It is the IPAM driver's responsibility to keep a reference count for the pool.
   121  
   122  ```go
   123  RequestPool(addressSpace, pool, subPool string, options map[string]string, v6 bool) (string, *net.IPNet, map[string]string, error)
   124  ```
   125  
   126  
   127  For this API, the remote driver will receive a POST message to the URL `/IpamDriver.RequestPool` with the following payload:
   128  
   129      {
   130  		"AddressSpace": string
   131  		"Pool":         string 
   132  		"SubPool":      string 
   133  		"Options":      map[string]string 
   134  		"V6":           bool 
   135      }
   136  
   137      
   138  Where:
   139  
   140      * `AddressSpace` the IP address space. It denotes a set of non-overlapping pools.
   141      * `Pool` The IPv4 or IPv6 address pool in CIDR format
   142      * `SubPool` An optional subset of the address pool, an ip range in CIDR format
   143      * `Options` A map of IPAM driver specific options
   144      * `V6` Whether an IPAM self-chosen pool should be IPv6
   145      
   146  AddressSpace is the only mandatory field. If no `Pool` is specified IPAM driver may choose to return a self chosen address pool. In such case, `V6` flag must be set if caller wants an IPAM-chosen IPv6 pool. A request with empty `Pool` and non-empty `SubPool` should be rejected as invalid.
   147  If a `Pool` is not specified IPAM will allocate one of the default pools. When `Pool` is not specified, the `V6` flag should be set if the network needs IPv6 addresses to be allocated.
   148  
   149  A successful response is in the form:
   150  
   151  
   152  	{
   153  		"PoolID": string
   154  		"Pool":   string
   155  		"Data":   map[string]string
   156  	}
   157  
   158  
   159  Where:
   160  
   161  * `PoolID` is an identifier for this pool. Same pools must have same pool id.
   162  * `Pool` is the pool in CIDR format
   163  * `Data` is the IPAM driver supplied metadata for this pool
   164  
   165  
   166  ### ReleasePool
   167  
   168  This API is for releasing a previously registered address pool.
   169  
   170  ```go
   171  ReleasePool(poolID string) error
   172  ```
   173  
   174  For this API, the remote driver will receive a POST message to the URL `/IpamDriver.ReleasePool` with the following payload:
   175  
   176  	{
   177  		"PoolID": string
   178  	}
   179  
   180  Where:
   181  
   182  * `PoolID` is the pool identifier
   183  
   184  A successful response is empty:
   185  
   186      {}
   187      
   188  ### RequestAddress
   189  
   190  This API is for reserving an ip address.
   191  
   192  ```go
   193  RequestAddress(string, net.IP, map[string]string) (*net.IPNet, map[string]string, error)
   194  ```
   195  
   196  For this API, the remote driver will receive a POST message to the URL `/IpamDriver.RequestAddress` with the following payload:
   197  
   198      {
   199  		"PoolID":  string
   200  		"Address": string
   201  		"Options": map[string]string
   202      }
   203      
   204  Where:
   205  
   206  * `PoolID` is the pool identifier
   207  * `Address` is the required address in regular IP form (A.B.C.D). If this address cannot be satisfied, the request fails. If empty, the IPAM driver chooses any available address on the pool
   208  * `Options` are IPAM driver specific options
   209  
   210  
   211  A successful response is in the form:
   212  
   213  
   214  	{
   215  		"Address": string
   216  		"Data":    map[string]string
   217  	}
   218  
   219  
   220  Where:
   221  
   222  * `Address` is the allocated address in CIDR format (A.B.C.D/MM)
   223  * `Data` is some IPAM driver specific metadata
   224  
   225  ### ReleaseAddress
   226  
   227  This API is for releasing an IP address.
   228  
   229  For this API, the remote driver will receive a POST message to the URL `/IpamDriver.ReleaseAddress` with the following payload:
   230  
   231      {
   232  		"PoolID": string
   233  		"Address": string
   234      }
   235      
   236  Where:
   237  
   238  * `PoolID` is the pool identifier
   239  * `Address` is the IP address to release
   240  
   241  
   242  
   243  ### GetCapabilities
   244  
   245  During the driver registration, libnetwork will query the driver about its capabilities. It is not mandatory for the driver to support this URL endpoint. If driver does not support it, registration will succeed with empty capabilities automatically added to the internal driver handle.
   246  
   247  During registration, the remote driver will receive a POST message to the URL `/IpamDriver.GetCapabilities` with no payload. The driver's response should have the form:
   248  
   249  
   250  	{
   251  		"RequiresMACAddress": bool
   252  		"RequiresRequestReplay": bool
   253  	}
   254  	
   255  	
   256  	
   257  ## Capabilities
   258  
   259  Capabilities are requirements, features the remote ipam driver can express during registration with libnetwork.
   260  As of now libnetwork accepts the following capabilities:
   261  
   262  ### RequiresMACAddress
   263  
   264  It is a boolean value which tells libnetwork whether the ipam driver needs to know the interface MAC address in order to properly process the `RequestAddress()` call.
   265  If true, on `CreateEndpoint()` request, libnetwork will generate a random MAC address for the endpoint (if an explicit MAC address was not already provided by the user) and pass it to `RequestAddress()` when requesting the IP address inside the options map. The key will be the `netlabel.MacAddress` constant: `"com.docker.network.endpoint.macaddress"`.
   266  
   267  ### RequiresRequestReplay
   268  
   269  It is a boolean value which tells libnetwork whether the ipam driver needs to receive the replay of the `RequestPool()` and `RequestAddress()` requests on daemon reload.  When libnetwork controller is initializing, it retrieves from local store the list of current local scope networks and, if this capability flag is set, it allows the IPAM driver to reconstruct the database of pools by replaying the `RequestPool()` requests for each pool and the `RequestAddress()` for each network gateway owned by the local networks. This can be useful to ipam drivers which decide not to persist the pools allocated to local scope networks.
   270  
   271  
   272  ## Appendix
   273  
   274  A Go extension for the IPAM remote API is available at [docker/go-plugins-helpers/ipam](https://github.com/docker/go-plugins-helpers/tree/master/ipam)