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.