{"action":"created","issue":{"url":"https://api.github.com/repos/docker/docker/issues/11090","labels_url":"https://api.github.com/repos/docker/docker/issues/11090/labels{/name}","comments_url":"https://api.github.com/repos/docker/docker/issues/11090/comments","events_url":"https://api.github.com/repos/docker/docker/issues/11090/events","html_url":"https://github.com/docker/docker/issues/11090","id":59356698,"number":11090,"title":"Docker Storage API","user":{"login":"hoskeri","id":19318,"avatar_url":"https://avatars.githubusercontent.com/u/19318?v=3","gravatar_id":"","url":"https://api.github.com/users/hoskeri","html_url":"https://github.com/hoskeri","followers_url":"https://api.github.com/users/hoskeri/followers","following_url":"https://api.github.com/users/hoskeri/following{/other_user}","gists_url":"https://api.github.com/users/hoskeri/gists{/gist_id}","starred_url":"https://api.github.com/users/hoskeri/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hoskeri/subscriptions","organizations_url":"https://api.github.com/users/hoskeri/orgs","repos_url":"https://api.github.com/users/hoskeri/repos","events_url":"https://api.github.com/users/hoskeri/events{/privacy}","received_events_url":"https://api.github.com/users/hoskeri/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2015-02-28T20:22:51Z","updated_at":"2015-03-01T14:11:24Z","closed_at":null,"body":"# Docker Storage API - Proposal\r\n\r\n## Motivation\r\n\r\n   1. Data volumes cannot be described fully by docker/containers.\r\n   2. Image storage for containers is not configurable.\r\n   3. There is currently no infrastructure to support distributed\r\n      storage volumes from within docker.\r\n   4. To manage life-cycle of data, image and metadata volumes\r\n   5. Ability to manage shared volumes across a cluster of docker hosts\r\n\r\n## Volumes as a first class object in Docker.\r\n\r\n   We achieve these goals by promoting Volumes and Storage as\r\n   first class entities in docker on the same level as containers.\r\n\r\n   This would also allow containers to describe the volumes they must be\r\n   attached and store the container configuration in a way that permits the\r\n   creation of Highly available containers.\r\n\r\n   Another feature would be the ability to discover capabilities of various\r\n   storage backends and automatically provision and configure storage volume\r\n   based on QoS specs for containers.\r\n\r\n## Use Case Example.\r\n\r\n   Lets take the example of a common pattern for multi-tiered database application.\r\n\r\n   Such an application may consist of one or more database servers, a number of\r\n   application processes, HTTP servers, caching servers, load balancers, management, etc.\r\n\r\n   The deployment of such an application imposes different levels of performance,\r\n   availability and reliability requirements. It is useful to be able to specify\r\n   what each volume and each container type needs, and for the available storage\r\n   to be matched and provisioned automatically.\r\n\r\n   Thus user facing terms like 'high', 'low' can be translated by docker and/or volume \r\n   drivers to concrete metrics such as IOPS, etc.\r\n\r\n   Examples of such containers and their storage needs:\r\n\r\n            :database-master:\r\n              build: .\r\n              ports:\r\n               - \"8000:8000\"\r\n              volumes:\r\n                name: DataVolume\r\n                size: 10G\r\n                type: block\r\n                path: /dev/sdb\r\n                qos-spec:\r\n                    availability: high\r\n                    performance: high\r\n\r\n            :database-replica:\r\n              build: .\r\n              ports:\r\n               - \"3307:3307\"\r\n              volumes:\r\n                name: DataVolumeReplica1\r\n                size: 10G\r\n                type: block\r\n                path: /dev/sdb\r\n                qos-spec:\r\n                    availability: medium\r\n                    performance: high\r\n\r\n            :caching-server:\r\n              build: .\r\n              ports:\r\n               - \"3307:3307\"\r\n              volumes:\r\n                name: VarnishCache\r\n                size: 2G\r\n                type: fs\r\n                path: /var/lib/varnish-cache\r\n                qos-spec:\r\n                    availability: low\r\n                    performance: medium\r\n\r\n            :application-worker:\r\n              build: .\r\n              ports:\r\n               - \"3307:3307\"\r\n              volumes:\r\n                name: ScratchVolume1\r\n                size: 1G\r\n                type: fs\r\n                path: /var/lib/app-scratch\r\n                qos-spec:\r\n                    availability: low\r\n                    performance: low\r\n\r\n            :load-balancer:\r\n              build: .\r\n              ports:\r\n               - \"3307:3307\"\r\n              volumes:\r\n                name: LoggingVolume1\r\n                size: 1G\r\n                type: fs\r\n                path: /var/lib/balancer\r\n                read-only: true\r\n                qos-spec:\r\n                    availability: low\r\n                    performance: low\r\n\r\n## Design Overview.\r\n\r\nWe create a new type of driver interface called the 'storagedriver'.\r\n\r\nJust like the existing 'graphdriver' and 'execdriver' interfaces,\r\nthis will allow the existence of multiple implementations of\r\nthe interface - referred to below as 'drivers'.\r\n\r\nThe central new entity introduced by this interface is called the\r\n'Volume'. Each driver allows the creation, manipulation and destruction\r\nof these volumes.\r\n\r\n'Volumes' are meant to supersede and formalize the existing concept of\r\ndata volumes. They can also be used to represent individual layers in a\r\ncontainer. Thus any snapshot capability offered by the storage can be used\r\nto implement the layering of filesystems needs for docker to work.\r\n\r\nWe also create definitions of service levels and performance criteria\r\nthat can serve as input to the storage drivers to manage their resources.\r\n\r\n## Interface/API definitions.\r\n\r\n        package driver\r\n        \r\n        // Custom metadata for volumes.\r\n        type VolumeTags map[string]string\r\n\r\n        const (\r\n        \tMETADATA = iota\r\n        \tDATA     = iota\r\n        )\r\n\r\n        type storageDriverInfo struct {\r\n        \tdriver *Driver\r\n        }\r\n\r\n        // List of available storage drivers.\r\n        var storageDrivers []storageDriverInfo\r\n\r\n        func Register(d *Driver) (err error) {\r\n        \treturn nil\r\n        }\r\n\r\n        type PolicySpec struct {\r\n        \tAvailabilityZone []string // List of availablity zones to replicate to.\r\n                                      // Also specifies no. of copies.\r\n        \tMinIOPS          uint64   // Min IOPS expected.\r\n        \tMaxIOPS          uint64   // Max IOPS allowed.\r\n        \tMinLatency       uint64   // Min Latency allowed.\r\n        \tMaxLatency       uint64   // Max Latency expected.\r\n        \tBurst            uint64   // Number to denote 'burstiness'\r\n        \tMinThroughput    uint64   // Guaranteed throughput\r\n        \tMaxThroughput    uint64   // Max throughput allowed.\r\n        \tMinResv          uint64   // Minimum bytes to reserve.\r\n        \tMaxResv          uint64   // Max bytes reserved. Same as capacity/size of the volume\r\n                                      // if Min = 0, implies thin provisioning\r\n                                      // if Min == Max, implies thick provisioning\r\n        \tDedup            bool     // Dedup enabled.\r\n        \tCompression      string   // Compression type, if enabled.\r\n        \tEncryption       string   // Encryption type, if enabled.\r\n        \tRPO              uint64   // Recovery Point Objective - represented by date/time\r\n        \tRTO              uint64   // Recovery Time Objective - represented by date/time\r\n        }\r\n\r\n\r\n        // Interface to be implemented by each of the drivers.\r\n        type Driver interface {\r\n            // Create a Volume given a name, a policy specification, and optionally a\r\n            // source snapshot to fork from\r\n            // tags is a set of arbitrary key value pairs\r\n            // to associate meta-data.\r\n        \tCreate(name string, snapshot VolumeID, spec VolumePolicySpec, tags VolumeTags) (v *VolumeID, err error)\r\n\r\n            // Get the runtime structure representing a volume.\r\n        \tGet(v *VolumeID) (vol *Volume, err error)\r\n\r\n            // Update the PolicySpec and/or other parameters\r\n        \tUpdate(v *VolumeID, spec VolumePolicySpec) (err error)\r\n\r\n            // Delete this volume\r\n            // lazy implies that delete will be\r\n            // kept pending until last mount is detached,\r\n            // instead of failing if its still in use.\r\n        \tDelete(v *VolumeID, bool lazy) (err error)\r\n\r\n            // Clone a volume from another volume or snapshot.\r\n            // This creates a writeable copy of this volume.\r\n        \tClone(v *VolumeID, name string, spec VolumePolicySpec, tags VolumeTags) (v *VolumeID, err error)\r\n\r\n            // Create a read-only point in time snapshot.\r\n        \tSnapshot(v *VolumeID, name string, spec VolumePolicySpec, tags VolumeTags) (v *VolumeID, err error)\r\n\r\n            // Get a list of all child snapshots or clones created\r\n            // from this volume.\r\n            EnumerateSnapshots(v *VolumeID) (snapshots *[]VolumeID, err error)\r\n\r\n            // Stream snapshot diff between two volumes/snapshots to a third Volume.\r\n            SnapshotDiff(v *VolumeID, other *VolumeID, dest *VolumeID) (err error)\r\n\r\n            // Restore the contents of this volume from a previous snapshot.\r\n        \tRevert(v *VolumeID, to VolumeID) (err error)\r\n\r\n            // Ask the driver to setup the volume,\r\n            // and return the access point - eg. block device file, local directory, nfs mountpoint, iscsi volume etc.\r\n        \tAttach(v *VolumeID) (id string, t AccessType, err error)\r\n\r\n            // Ask the driver to destroy the access point\r\n            // and free resources.\r\n        \tDetach(v *VolumeID, lazy bool) (err error)\r\n\r\n            // General lookup of all volumes provided by this driver,\r\n            // search could be by ID, name, policy, snapshot-create-time, etc.\r\n        \tSearch(query string) (result *[]VolumeID, err error)\r\n        }\r\n\r\n        // Representation of the run time status\r\n        // of the volume and any of its access points,\r\n        // associated containers, hosts, etc.\r\n        type Volume struct {\r\n        \t// Run time details.\r\n        \tName  string\r\n        \tSpec  VolumePolicySpec\r\n        \tStats string\r\n        \t// alarms, hosts attached, policy compliance status, etc.\r\n        \tStatus string\r\n        }\r\n\r\n## Future work.\r\n- Allow Delegation to out of process daemon to permit hot plugging of drivers.\r\n"},"comment":{"url":"https://api.github.com/repos/docker/docker/issues/comments/76598251","html_url":"https://github.com/docker/docker/issues/11090#issuecomment-76598251","issue_url":"https://api.github.com/repos/docker/docker/issues/11090","id":76598251,"user":{"login":"thaJeztah","id":1804568,"avatar_url":"https://avatars.githubusercontent.com/u/1804568?v=3","gravatar_id":"","url":"https://api.github.com/users/thaJeztah","html_url":"https://github.com/thaJeztah","followers_url":"https://api.github.com/users/thaJeztah/followers","following_url":"https://api.github.com/users/thaJeztah/following{/other_user}","gists_url":"https://api.github.com/users/thaJeztah/gists{/gist_id}","starred_url":"https://api.github.com/users/thaJeztah/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/thaJeztah/subscriptions","organizations_url":"https://api.github.com/users/thaJeztah/orgs","repos_url":"https://api.github.com/users/thaJeztah/repos","events_url":"https://api.github.com/users/thaJeztah/events{/privacy}","received_events_url":"https://api.github.com/users/thaJeztah/received_events","type":"User","site_admin":false},"created_at":"2015-03-01T14:11:24Z","updated_at":"2015-03-01T14:11:24Z","body":"For reference; another proposal was also created recently; [Proposal: Storage Interfaces for Docker #11020](https://github.com/docker/docker/issues/11020)"}}