github.com/Prakhar-Agarwal-byte/moby@v0.0.0-20231027092010-a14e3e8ab87e/docs/cluster_volumes.md (about)

     1  Cluster Volumes
     2  ===============
     3  
     4  Docker Cluster Volumes is a new feature which allows using CSI plugins to
     5  create cluster-aware volumes.
     6  
     7  The Container Storage Interface is a platform-agnostic API for storage
     8  providers to write storage plugins which are compatible with many container
     9  orchestrators. By leveraging the CSI, Docker Swarm can provide intelligent,
    10  cluster-aware access to volumes across many supported storage providers.
    11  
    12  ## Installing a CSI plugin
    13  
    14  Docker accesses CSI plugins through the Docker managed plugin system, using the
    15  `docker plugin` command.
    16  
    17  If a plugin is available for Docker, it can be installed through the `docker
    18  plugin install` command. Plugins may require configuration specific to the
    19  user's environment, they will ultimately be detected by and work automatically
    20  with Docker once enabled.
    21  
    22  Currently, there is no way to automatically deploy a Docker Plugin across all
    23  nodes in a cluster. Therefore, users must ensure the Docker Plugin is installed
    24  on all nodes in the cluster on which it is desired. 
    25  
    26  The CSI plugin must be installed on all manager nodes. If a manager node does
    27  not have the CSI plugin installed, a leadership change to that manager nodes
    28  will make Swarm unable to use that driver.
    29  
    30  Docker Swarm worker nodes report their active plugins to the Docker Swarm
    31  managers, so it is not necessary to install a plugin on every worker node. The
    32  plugin only needs to be installed on those nodes need access to the volumes
    33  provided by that plugin.
    34  
    35  ### Multiple Instances of the Same Plugin
    36  
    37  In some cases, it may be desirable to run multiple instances of the same
    38  plugin. For example, there may be two different instances of some storage
    39  provider which each need a differently configured plugin.
    40  
    41  To run more than one instance of the same plugin, set the `--alias` option when
    42  installing the plugin. This will cause the plugin to take a local name
    43  different from its original name.
    44  
    45  Ensure that when using plugin name aliases, the plugin name alias is the same
    46  on every node.
    47  
    48  ## Creating a Docker CSI Plugin
    49  
    50  Most CSI plugins are shipped with configuration specific to Kubernetes. They
    51  are often provided in the form of Helm charts, and installation information may
    52  include Kubernetes-specific steps. Docker CSI Plugins use the same binaries as
    53  those for Kubernetes, but in a different environment and sometimes with
    54  different configuration.
    55  
    56  Before following this section, readers should ensure they are acquainted with
    57  the
    58  [Docker Engine managed plugin system](https://docs.docker.com/engine/extend/).
    59  Docker CSI plugins use this system to run.
    60  
    61  Docker Plugins consist of a root filesystem and a `config.json`. The root
    62  filesystem can generally be exported from whatever image is built for the
    63  plugin. The `config.json` specifies how the plugin is used. Several
    64  CSI-specific concerns, as well as some general but poorly-documented features,
    65  are outlined here.
    66  
    67  ### Basic Requirements
    68  
    69  Docker CSI plugins are identified with a special interface type. There are two
    70  related interfaces that CSI plugins can expose.
    71  
    72  * `docker.csicontroller/1.0` is used for CSI Controller plugins.
    73  * `docker.csinode/1.0` is used for CSI Node plugins.
    74  * Combined plugins should include both interfaces.
    75  
    76  Additionally, the interface field of the config.json includes a `socket` field.
    77  This can be set to any value, but the CSI plugin should have its `CSI_ENDPOINT`
    78  environment variable set appropriately.
    79  
    80  In the `config.json`, this should be set as such:
    81  
    82  ```json
    83    "interface": {
    84      "types": ["docker.csicontroller/1.0","docker.csinode/1.0"],
    85      "socket": "my-csi-plugin.sock"
    86    },
    87    "env": [
    88      {
    89        "name": "CSI_ENDPOINT",
    90        "value": "/run/docker/plugins/my-csi-plugin.sock"
    91      }
    92    ]
    93  ```
    94  
    95  The CSI specification states that CSI plugins should have
    96  `CAP_SYS_ADMIN` privileges, so this should be set in the `config.json` as
    97  well:
    98  
    99  ```json
   100    "linux" : {
   101      "capabilities": ["CAP_SYS_ADMIN"]
   102    }
   103  ```
   104  
   105  ### Propagated Mount
   106  
   107  In order for the plugin to expose volumes to Swarm, it must publish those
   108  volumes to a Propagated Mount location. This allows a mount to be itself
   109  mounted to a different location in the filesystem. The Docker Plugin system
   110  only allows one Propagated Mount, which is configured as a string representing
   111  the path in the plugin filesystem.
   112  
   113  When calling the CSI plugin, Docker Swarm specifies the publish target path,
   114  which is the path in the plugin filesystem that a volume should ultimately be
   115  used from. This is also the path that needs to be specified as the Propagated
   116  Mount for the plugin. This path is hard-coded to be `/data/published` in the
   117  plugin filesystem, and as such, the plugin configuration should list this as
   118  the Propagated Mount:
   119  
   120  ```json
   121    "propagatedMount": "/data/published"
   122  ```
   123  
   124  ### Configurable Options
   125  
   126  Plugin configurations can specify configurable options for many fields. To
   127  expose a field as configurable, the object including that field should include
   128  a field `Settable`, which is an array of strings specifying the name of
   129  settable fields.
   130  
   131  For example, consider a plugin that supports a config file.
   132  
   133  ```json
   134    "mounts": [
   135      {
   136        "name": "configfile",
   137        "description": "Config file mounted in from the host filesystem",
   138        "type": "bind",
   139        "destination": "/opt/my-csi-plugin/config.yaml",
   140        "source": "/etc/my-csi-plugin/config.yaml"
   141      }
   142    ]
   143  ```
   144  
   145  This configuration would result in a file located on the host filesystem at
   146  `/etc/my-csi-plugin/config.yaml` being mounted into the plugin filesystem at
   147  `/opt/my-csi-plugin/config.yaml`. However, hard-specifying the source path of
   148  the configuration is undesirable. Instead, the plugin author can put the
   149  `Source` field in the Settable array:
   150  
   151  ```json
   152    "mounts": [
   153      {
   154        "name": "configfile",
   155        "description": "Config file mounted in from the host filesystem",
   156        "type": "bind",
   157        "destination": "/opt/my-csi-plugin/config.yaml",
   158        "source": "",
   159        "settable": ["source"]
   160      }
   161    ]
   162  ```
   163  
   164  When a field is exposed as settable, the user can configure that field when
   165  installing the plugin.
   166  
   167  ```
   168  $ docker plugin install my-csi-plugin configfile.source="/srv/my-csi-plugin/config.yaml"
   169  ```
   170  
   171  Or, alternatively, it can be set while the plugin is disabled:
   172  
   173  ```
   174  $ docker plugin disable my-csi-plugin
   175  $ docker plugin set my-csi-plugin configfile.source="/var/lib/my-csi-plugin/config.yaml"
   176  $ docker plugin enable
   177  ```
   178  
   179  ### Split-Component Plugins
   180  
   181  For split-component plugins, users can specify either the
   182  `docker.csicontroller/1.0` or `docker.csinode/1.0` plugin interfaces. Manager
   183  nodes should run plugin instances with the `docker.csicontroller/1.0`
   184  interface, and worker nodes the `docker.csinode/1.0` interface.
   185  
   186  Docker does support running two plugins with the same name, nor does it support
   187  specifying different drivers for the node and controller plugins. This means in
   188  a fully split plugin, Swarm will be unable to schedule volumes to manager
   189  nodes.
   190  
   191  If it is desired to run a split-component plugin such that the Volumes managed
   192  by that plugin are accessible to Tasks on the manager node, the user will need
   193  to build the plugin such that some proxy or multiplexer provides the illusion
   194  of combined components to the manager through one socket, and ensure the plugin
   195  reports both interface types.
   196  
   197  ## Using Cluster Volumes
   198  
   199  ### Create a Cluster Volume
   200  
   201  Creating a Cluster Volume is done with the same `docker volume` commands as any
   202  other Volume. To create a Cluster Volume, one needs to do both of things:
   203  
   204  * Specify a CSI-capable driver with the `--driver` or `-d` option.
   205  * Use any one of the cluster-specific `docker volume create` flags.
   206  
   207  For example, to create a Cluster Volume called `my-volume` with the
   208  `democratic-csi` Volume Driver, one might use this command:
   209  
   210  ```bash
   211  docker volume create \
   212    --driver democratic-csi \
   213    --type mount \
   214    --sharing all \
   215    --scope multi \
   216    --limit-bytes 10G \
   217    --required-bytes 1G \
   218    my-volume
   219  ```
   220  
   221  ### List Cluster Volumes
   222  
   223  Cluster Volumes will be listed along with other volumes when doing
   224  `docker volume ls`. However, if users want to see only Cluster Volumes, and
   225  with cluster-specific information, the flag `--cluster` can be specified:
   226  
   227  ```
   228  $ docker volume ls --cluster
   229  VOLUME NAME   GROUP     DRIVER    AVAILABILITY   STATUS
   230  volume1       group1    driver1   active         pending creation
   231  volume2       group1    driver1   pause          created
   232  volume3       group2    driver2   active         in use (1 node)
   233  volume4       group2    driver2   active         in use (2 nodes)
   234  ```
   235  
   236  ### Deploying a Service
   237  
   238  Cluster Volumes are only compatible with Docker Services, not plain Docker
   239  Containers.
   240  
   241  In Docker Services, a Cluster Volume is used the same way any other volume
   242  would be used. The `type` should be set to `cluster`. For example, to create a
   243  Service that uses `my-volume` created above, one would execute a command like:
   244  
   245  ```bash
   246  docker service create \
   247    --name my-service \
   248    --mount type=cluster,src=my-volume,dst=/srv/www \
   249    nginx:alpine
   250  ```
   251  
   252  When scheduling Services which use Cluster Volumes, Docker Swarm uses the
   253  volume's information and state to make decisions about Task placement.
   254  
   255  For example, the Service will be constrained to run only on nodes on which the
   256  volume is available. If the volume is configured with `scope=single`, meaning
   257  it can only be used on one node in the cluster at a time, then all Tasks for
   258  that Service will be scheduled to that same node. If that node changes for some
   259  reason, like a node failure, then the Tasks will be rescheduled to the new
   260  node automatically, without user input.
   261  
   262  If the Cluster Volume is accessible only on some set of nodes at the same time,
   263  and not the whole cluster, then Docker Swarm will only schedule the Service to
   264  those nodes as reported by the plugin.
   265  
   266  ### Using Volume Groups
   267  
   268  It is frequently desirable that a Service use any available volume out of an
   269  interchangeable set. To accomplish this in the most simple and straightforward
   270  manner possible, Cluster Volumes use the concept of a volume "Group".
   271  
   272  The Volume Group is a field, somewhat like a special label, which is used to
   273  instruct Swarm that a given volume is interchangeable with every other volume
   274  of the same Group. When creating a Cluster Volume, the Group can be specified
   275  by using the `--group` flag.
   276  
   277  To use a Cluster Volume by Group instead of by Name, the mount `src` option is
   278  prefixed with `group:`, followed by the group name. For example:
   279  
   280  ```
   281  --mount type=cluster,src=group:my-group,dst=/srv/www
   282  ```
   283  
   284  This instructs Docker Swarm that any Volume with the Group `my-group` can be
   285  used to satisfy the mounts.
   286  
   287  Volumes in a Group do not need to be identical, but they must be
   288  interchangeable. These caveats should be kept in mind when using Groups:
   289  
   290  * No Service ever gets the monopoly on a Cluster Volume. If several Services
   291    use the same Group, then the Cluster Volumes in that Group can be used with
   292    any of those Services at any time. Just because a particular Volume was used
   293    by a particular Service at one point does not mean it won't be used by a
   294    different Service later.
   295  * Volumes in a group can have different configurations, but all of those
   296    configurations must be compatible with the Service. For example, if some of
   297    the Volumes in a group have `sharing=readonly`, then the Service must be
   298    capable of using the volume in read-only mode.
   299  * Volumes in a Group are created statically ahead of time, not dynamically
   300    as-needed. This means that the user must ensure a sufficient number of
   301    Volumes belong to the desired Group to support the needs of the Service.
   302  
   303  ### Taking Cluster Volumes Offline
   304  
   305  For various reasons, users may wish to take a particular Cluster Volume
   306  offline, such that is not actively used by Services. To facilitate this,
   307  Cluster Volumes have an `availability` option similar to Docker Swarm nodes.
   308  
   309  Cluster Volume availability can be one of three states:
   310  
   311  * `active` - Default. Volume can be used as normal.
   312  * `pause` - The volume will not be used for new Services, but existing Tasks
   313    using the volume will not be stopped.
   314  * `drain` - The volume will not be used for new Services, and any running Tasks
   315    using the volume will be stopped and rescheduled.
   316  
   317  A Volume can only be removed from the cluster entirely if its availability is
   318  set to `drain`, and it has been fully unpublished from all nodes.
   319  
   320  ## Unsupported Features
   321  
   322  The CSI Spec allows for a large number of features which Cluster Volumes in
   323  this initial implementation do not support. Most notably, Cluster Volumes do
   324  not support snapshots, cloning, or volume expansion.