Browse code

Updating for CAS changes and new select a driver section Adding changes requested by @jamtur01 and wrapping to 80 chars Adding typo fixes and replacing tabs with 4xspaces Closes and fixes #19240 Updating with content addressable storage model changes

Signed-off-by: Nigel <nigelpoulton@hotmail.com>

Nigel authored on 2016/01/12 02:39:41
Showing 14 changed files
... ...
@@ -10,184 +10,203 @@ parent = "engine_driver"
10 10
 
11 11
 # Docker and AUFS in practice
12 12
 
13
-AUFS was the first storage driver in use with Docker. As a result, it has a long and close history with Docker, is very stable, has a lot of real-world deployments, and has strong community support.  AUFS has several features that make it a good choice for Docker. These features enable:
13
+AUFS was the first storage driver in use with Docker. As a result, it has a
14
+long and close history with Docker, is very stable, has a lot of real-world
15
+deployments, and has strong community support. AUFS has several features that
16
+make it a good choice for Docker. These features enable:
14 17
 
15 18
 - Fast container startup times.
16 19
 - Efficient use of storage.
17 20
 - Efficient use of memory.
18 21
 
19
-Despite its capabilities and long history with Docker, some Linux distributions do not support AUFS. This is usually because AUFS is not included in the mainline (upstream) Linux kernel.
22
+Despite its capabilities and long history with Docker, some Linux distributions
23
+ do not support AUFS. This is usually because AUFS is not included in the
24
+mainline (upstream) Linux kernel.
20 25
 
21
-The following sections examine some AUFS features and how they relate to Docker.
26
+The following sections examine some AUFS features and how they relate to
27
+Docker.
22 28
 
23 29
 ## Image layering and sharing with AUFS
24 30
 
25
-AUFS is a *unification filesystem*. This means that it takes multiple directories on a single Linux host, stacks them on top of each other, and provides a single unified view. To achieve this, AUFS uses *union mount*.
31
+AUFS is a *unification filesystem*. This means that it takes multiple
32
+directories on a single Linux host, stacks them on top of each other, and
33
+provides a single unified view. To achieve this, AUFS uses a *union mount*.
26 34
 
27
-AUFS stacks multiple directories and exposes them as a unified view through a single mount point. All of the directories in the stack, as well as the union mount point, must all exist on the same Linux host. AUFS refers to each directory that it stacks as a *branch*.
35
+AUFS stacks multiple directories and exposes them as a unified view through a
36
+single mount point. All of the directories in the stack, as well as the union
37
+mount point, must all exist on the same Linux host. AUFS refers to each
38
+directory that it stacks as a *branch*.
28 39
 
29
-Within Docker, AUFS union mounts enable image layering. The AUFS storage driver implements Docker image layers using this union mount system. AUFS branches correspond to Docker image layers. The diagram below shows a Docker container based on the `ubuntu:latest` image.
40
+Within Docker, AUFS union mounts enable image layering. The AUFS storage driver
41
+ implements Docker image layers using this union mount system. AUFS branches
42
+correspond to Docker image layers. The diagram below shows a Docker container
43
+based on the `ubuntu:latest` image.
30 44
 
31 45
 ![](images/aufs_layers.jpg)
32 46
 
33
-This diagram shows the relationship between the Docker image layers and the AUFS branches (directories) in `/var/lib/docker/aufs`. Each image layer  and the container layer correspond to an AUFS branch (directory) in the Docker host's local storage area. The union mount point gives the unified view of all layers.
47
+This diagram shows that each image layer, and the container layer, is
48
+represented in the Docker hosts filesystem as a directory under
49
+`/var/lib/docker/`. The union mount point provides the unified view of all
50
+layers. As of Docker 1.10, image layer IDs do not correspond to the names of
51
+the directories that contain their data.
34 52
 
35
-AUFS also supports the copy-on-write technology (CoW). Not all storage drivers do.
53
+AUFS also supports the copy-on-write technology (CoW). Not all storage drivers
54
+do.
36 55
 
37 56
 ## Container reads and writes with AUFS
38 57
 
39
-Docker leverages AUFS CoW technology to enable image sharing and minimize the use of disk space. AUFS works at the file level. This means that all AUFS CoW operations copy entire files - even if only a small part of the file is being modified. This behavior can have a noticeable impact on container performance, especially if the files being copied are large, below a lot of image layers, or the CoW operation must search a deep directory tree.
40
-
41
-Consider, for example, an application running in a container needs to add a single new value to a large key-value store (file). If this is the first time the file is modified it does not yet exist in the container's top writable layer. So, the CoW must *copy up* the file from the underlying image. The AUFS storage driver searches each image layer for the file. The search order is from top to bottom. When it is found, the entire file is *copied up* to the container's top writable layer. From there, it can be opened and modified.
42
-
43
-Larger files obviously take longer to *copy up* than smaller files, and files that exist in lower image layers take longer to locate than those in higher layers. However, a *copy up* operation only occurs once per file on any given container. Subsequent reads and writes happen against the file's copy already *copied-up* to the container's top layer.
44
-
58
+Docker leverages AUFS CoW technology to enable image sharing and minimize the
59
+use of disk space. AUFS works at the file level. This means that all AUFS CoW
60
+operations copy entire files - even if only a small part of the file is being
61
+modified. This behavior can have a noticeable impact on container performance,
62
+ especially if the files being copied are large, below a lot of image layers,
63
+or the CoW operation must search a deep directory tree.
64
+
65
+Consider, for example, an application running in a container needs to add a
66
+single new value to a large key-value store (file). If this is the first time
67
+the file is modified, it does not yet exist in the container's top writable
68
+layer. So, the CoW must *copy up* the file from the underlying image. The AUFS
69
+storage driver searches each image layer for the file. The search order is from
70
+ top to bottom. When it is found, the entire file is *copied up* to the
71
+container's top writable layer. From there, it can be opened and modified.
72
+
73
+Larger files obviously take longer to *copy up* than smaller files, and files
74
+that exist in lower image layers take longer to locate than those in higher
75
+layers. However, a *copy up* operation only occurs once per file on any given
76
+container. Subsequent reads and writes happen against the file's copy already
77
+*copied-up* to the container's top layer.
45 78
 
46 79
 ## Deleting files with the AUFS storage driver
47 80
 
48 81
 The AUFS storage driver deletes a file from a container by placing a *whiteout
49 82
 file* in the container's top layer. The whiteout file effectively obscures the
50
-existence of the file in image's lower, read-only layers.  The simplified
83
+existence of the file in the read-only image layers below. The simplified
51 84
 diagram below shows a container based on an image with three image layers.
52 85
 
53 86
 ![](images/aufs_delete.jpg)
54 87
 
55 88
 The `file3` was deleted from the container. So, the AUFS storage driver  placed
56 89
 a whiteout file in the container's top layer. This whiteout file effectively
57
-"deletes"  `file3` from the container by obscuring any of the original file's
58
-existence in the image's read-only base layer. Of course, the image could have
59
-been in any of the other layers instead or in addition depending on how the
60
-layers are built.
90
+"deletes" `file3` from the container by obscuring any of the original file's
91
+existence in the image's read-only layers. This works the same no matter which
92
+of the image's read-only layers the file exists in.
61 93
 
62 94
 ## Configure Docker with AUFS
63 95
 
64
-You can only use the AUFS storage driver on Linux systems with AUFS installed. Use the following command to determine if your system supports AUFS.
96
+You can only use the AUFS storage driver on Linux systems with AUFS installed.
97
+Use the following command to determine if your system supports AUFS.
65 98
 
66
-```bash
67
-$ grep aufs /proc/filesystems
68
-nodev   aufs
69
-```
99
+    $ grep aufs /proc/filesystems
100
+    nodev   aufs
70 101
 
71
-This output indicates the system supports AUFS.  Once you've verified your
102
+This output indicates the system supports AUFS. Once you've verified your
72 103
 system supports AUFS, you can must instruct the Docker daemon to use it. You do
73 104
 this from the command line with the `docker daemon` command:
74 105
 
75
-```bash
76
-$ sudo docker daemon --storage-driver=aufs &
77
-```
106
+    $ sudo docker daemon --storage-driver=aufs &
107
+
78 108
 
79 109
 Alternatively, you can edit the Docker config file and add the
80 110
 `--storage-driver=aufs` option to the `DOCKER_OPTS` line.
81 111
 
82
-```bash
83
-# Use DOCKER_OPTS to modify the daemon startup options.
84
-DOCKER_OPTS="--storage-driver=aufs"
85
-```
112
+    # Use DOCKER_OPTS to modify the daemon startup options.
113
+    DOCKER_OPTS="--storage-driver=aufs"
86 114
 
87
-Once your daemon is running, verify the storage driver with the `docker info` command.
115
+Once your daemon is running, verify the storage driver with the `docker info`
116
+command.
88 117
 
89
-```bash
90
-$ sudo docker info
91
-Containers: 1
92
-Images: 4
93
-Storage Driver: aufs
94
- Root Dir: /var/lib/docker/aufs
95
- Backing Filesystem: extfs
96
- Dirs: 6
97
- Dirperm1 Supported: false
98
-Execution Driver: native-0.2
99
-...output truncated...
100
-```
118
+    $ sudo docker info
119
+    Containers: 1
120
+    Images: 4
121
+    Storage Driver: aufs
122
+     Root Dir: /var/lib/docker/aufs
123
+     Backing Filesystem: extfs
124
+     Dirs: 6
125
+     Dirperm1 Supported: false
126
+    Execution Driver: native-0.2
127
+    ...output truncated...
101 128
 
102
-The output above shows that the Docker daemon is running the AUFS storage driver on top of an existing ext4 backing filesystem.
129
+The output above shows that the Docker daemon is running the AUFS storage
130
+driver on top of an existing `ext4` backing filesystem.
103 131
 
104 132
 ## Local storage and AUFS
105 133
 
106
-As the `docker daemon` runs with the AUFS driver, the driver stores images and containers on within the Docker host's local storage area in the `/var/lib/docker/aufs` directory.
134
+As the `docker daemon` runs with the AUFS driver, the driver stores images and
135
+containers within the Docker host's local storage area under
136
+`/var/lib/docker/aufs/`.
107 137
 
108 138
 ### Images
109 139
 
110 140
 Image layers and their contents are stored under
111
-`/var/lib/docker/aufs/diff/<image-id>` directory. The contents of an image
112
-layer in this location includes all the files and directories belonging in that
113
-image layer.
141
+`/var/lib/docker/aufs/diff/`. With Docker 1.10 and higher, image layer IDs do
142
+not correspond to directory names.
114 143
 
115 144
 The `/var/lib/docker/aufs/layers/` directory contains metadata about how image
116 145
 layers are stacked. This directory contains one file for every image or
117
-container layer on the Docker host. Inside each file are the image layers names
118
-that exist below it. The diagram below shows an image with 4 layers.
119
-
120
-![](images/aufs_metadata.jpg)
121
-
122
-Inspecting the contents of the file relating to the top layer of the image
123
-shows the three image layers below it. They are listed in the order they are
124
-stacked.
146
+container layer on the Docker host (though file names no longer match image
147
+layer IDs). Inside each file are the names of the directories that exist below
148
+it in the stack
125 149
 
126
-```bash
127
-$ cat /var/lib/docker/aufs/layers/91e54dfb11794fad694460162bf0cb0a4fa710cfa3f60979c177d920813e267c
150
+The command below shows the contents of a metadata file in
151
+`/var/lib/docker/aufs/layers/` that lists the the three directories that are
152
+stacked below it in the union mount. Remember, these directory names do no map
153
+to image layer IDs with Docker 1.10 and higher.
128 154
 
129
-d74508fb6632491cea586a1fd7d748dfc5274cd6fdfedee309ecdcbc2bf5cb82
130
-
131
-c22013c8472965aa5b62559f2b540cd440716ef149756e7b958a1b2aba421e87
132
-
133
-d3a1f33e8a5a513092f01bb7eb1c2abf4d711e5105390a3fe1ae2248cfde1391
134
-```
155
+    $ cat /var/lib/docker/aufs/layers/91e54dfb11794fad694460162bf0cb0a4fa710cfa3f60979c177d920813e267c
156
+    d74508fb6632491cea586a1fd7d748dfc5274cd6fdfedee309ecdcbc2bf5cb82
157
+    c22013c8472965aa5b62559f2b540cd440716ef149756e7b958a1b2aba421e87
158
+    d3a1f33e8a5a513092f01bb7eb1c2abf4d711e5105390a3fe1ae2248cfde1391
135 159
 
136 160
 The base layer in an image has no image layers below it, so its file is empty.
137 161
 
138 162
 ### Containers
139 163
 
140
-Running containers are mounted at locations in the
141
-`/var/lib/docker/aufs/mnt/<container-id>` directory. This is the AUFS union
142
-mount point that exposes the container and all underlying image layers as a
143
-single unified view. If a container is not running, its directory still exists
144
-but is empty. This is because containers are only mounted when they are running.
164
+Running containers are mounted below `/var/lib/docker/aufs/mnt/<container-id>`.
165
+ This is where the AUFS union mount point that exposes the container and all
166
+underlying image layers as a single unified view exists. If a container is not
167
+running, it still has a directory here but it is empty. This is because AUFS
168
+only mounts a container when it is running. With Docker 1.10 and higher,
169
+ container IDs no longer correspond to directory names under
170
+`/var/lib/docker/aufs/mnt/<container-id>`.
145 171
 
146 172
 Container metadata and various config files that are placed into the running
147
-container are stored in `/var/lib/containers/<container-id>`. Files in this
148
-directory exist for all containers on the system, including ones that are
149
-stopped. However, when a container is running the container's log files are also
150
-in this directory.
151
-
152
-A container's thin writable layer is stored under
153
-`/var/lib/docker/aufs/diff/<container-id>`. This directory is stacked by AUFS as
154
-the containers top writable layer and is where all changes to the container are
155
-stored. The directory exists even if the container is stopped. This means that
156
-restarting a container will not lose changes made to it. Once a container is
157
-deleted this directory is deleted.
158
-
159
-Information about which image layers are stacked below a container's top
160
-writable layer is stored in the following file
161
-`/var/lib/docker/aufs/layers/<container-id>`. The command below shows that the
162
-container with ID `b41a6e5a508d` has 4 image layers below it:
163
-
164
-```bash
165
-$ cat /var/lib/docker/aufs/layers/b41a6e5a508dfa02607199dfe51ed9345a675c977f2cafe8ef3e4b0b5773404e-init
166
-91e54dfb11794fad694460162bf0cb0a4fa710cfa3f60979c177d920813e267c
167
-d74508fb6632491cea586a1fd7d748dfc5274cd6fdfedee309ecdcbc2bf5cb82
168
-c22013c8472965aa5b62559f2b540cd440716ef149756e7b958a1b2aba421e87
169
-d3a1f33e8a5a513092f01bb7eb1c2abf4d711e5105390a3fe1ae2248cfde1391
170
-```
171
-
172
-The image layers are shown in order. In the output above, the layer starting
173
-with image ID "d3a1..." is the image's base  layer. The image layer starting
174
-with "91e5..." is the image's topmost layer.
175
-
173
+container are stored in `/var/lib/docker/containers/<container-id>`. Files in
174
+this directory exist for all containers on the system, including ones that are
175
+stopped. However, when a container is running the container's log files are
176
+also in this directory.
177
+
178
+A container's thin writable layer is stored in a directory under
179
+`/var/lib/docker/aufs/diff/`. With Docker 1.10 and higher, container IDs no
180
+longer correspond to directory names. However, the containers thin writable
181
+layer still exists under here and is stacked by AUFS as the top writable layer
182
+and is where all changes to the container are stored. The directory exists even
183
+ if the container is stopped. This means that restarting a container will not
184
+lose changes made to it. Once a container is deleted, it's thin writable layer
185
+in this directory is deleted.
176 186
 
177 187
 ## AUFS and Docker performance
178 188
 
179 189
 To summarize some of the performance related aspects already mentioned:
180 190
 
181
-- The AUFS storage driver is a good choice for PaaS and other similar use-cases where container density is important. This is because AUFS efficiently shares images between multiple running containers, enabling fast container start times and minimal use of disk space.
182
-
183
-- The underlying mechanics of how AUFS shares files between image layers and containers uses the systems page cache very efficiently.
184
-
185
-- The AUFS storage driver can introduce significant latencies into container write performance. This is because the first time a container writes to any file, the file has be located and copied into the containers top writable layer. These latencies increase and are compounded when these files exist below many image layers and the files themselves are large.
186
-
187
-One final point. Data volumes provide the best and most predictable performance.
188
-This is because they bypass the storage driver and do not incur any of the
189
-potential overheads introduced by thin provisioning and copy-on-write. For this
190
-reason, you may want to place heavy write workloads on data volumes.
191
+- The AUFS storage driver is a good choice for PaaS and other similar use-cases
192
+ where container density is important. This is because AUFS efficiently shares
193
+images between multiple running containers, enabling fast container start times
194
+ and minimal use of disk space.
195
+
196
+- The underlying mechanics of how AUFS shares files between image layers and
197
+containers uses the systems page cache very efficiently.
198
+
199
+- The AUFS storage driver can introduce significant latencies into container
200
+write performance. This is because the first time a container writes to any
201
+file, the file has be located and copied into the containers top writable
202
+layer. These latencies increase and are compounded when these files exist below
203
+ many image layers and the files themselves are large.
204
+
205
+One final point. Data volumes provide the best and most predictable
206
+performance. This is because they bypass the storage driver and do not incur 
207
+any of the potential overheads introduced by thin provisioning and
208
+copy-on-write. For this reason, you may want to place heavy write workloads on
209
+data volumes.
191 210
 
192 211
 ## Related information
193 212
 
... ...
@@ -13,126 +13,118 @@ parent = "engine_driver"
13 13
 Btrfs is a next generation copy-on-write filesystem that supports many advanced
14 14
 storage technologies that make it a good fit for Docker. Btrfs is included in
15 15
 the mainline Linux kernel and its on-disk-format is now considered stable.
16
-However, many of its features are still under heavy development and users should
17
-consider it a fast-moving target.
16
+However, many of its features are still under heavy development and users 
17
+should consider it a fast-moving target.
18 18
 
19 19
 Docker's `btrfs` storage driver leverages many Btrfs features for image and
20
-container management. Among these features are thin provisioning, copy-on-write,
21
-and snapshotting.
20
+container management. Among these features are thin provisioning, 
21
+copy-on-write, and snapshotting.
22 22
 
23
-This article refers to Docker's Btrfs storage driver as `btrfs` and the overall Btrfs Filesystem as Btrfs.
23
+This article refers to Docker's Btrfs storage driver as `btrfs` and the overall
24
+ Btrfs Filesystem as Btrfs.
24 25
 
25 26
 >**Note**: The [Commercially Supported Docker Engine (CS-Engine)](https://www.docker.com/compatibility-maintenance) does not currently support the `btrfs` storage driver.
26 27
 
27 28
 ## The future of Btrfs
28 29
 
29
-Btrfs has been long hailed as the future of Linux filesystems. With full support in the mainline Linux kernel, a stable on-disk-format, and active development with a focus on stability, this is now becoming more of a reality.
30
+Btrfs has been long hailed as the future of Linux filesystems. With full 
31
+support in the mainline Linux kernel, a stable on-disk-format, and active 
32
+development with a focus on stability, this is now becoming more of a reality.
30 33
 
31
-As far as Docker on the Linux platform goes, many people see the `btrfs` storage driver as a potential long-term replacement for the `devicemapper` storage driver. However, at the time of writing, the `devicemapper` storage driver should be considered safer, more stable, and more *production ready*. You should only consider the `btrfs` driver for production deployments if you understand it well and have existing experience with Btrfs.
34
+As far as Docker on the Linux platform goes, many people see the `btrfs` 
35
+storage driver as a potential long-term replacement for the `devicemapper` 
36
+storage driver. However, at the time of writing, the `devicemapper` storage 
37
+driver should be considered safer, more stable, and more *production ready*. 
38
+You should only consider the `btrfs` driver for production deployments if you 
39
+understand it well and have existing experience with Btrfs.
32 40
 
33 41
 ## Image layering and sharing with Btrfs
34 42
 
35
-Docker leverages Btrfs *subvolumes* and *snapshots* for managing the on-disk components of image and container layers.  Btrfs subvolumes look and feel like a normal Unix filesystem. As such, they can have their own internal directory structure that hooks into the wider Unix filesystem.
43
+Docker leverages Btrfs *subvolumes* and *snapshots* for managing the on-disk 
44
+components of image and container layers.  Btrfs subvolumes look and feel like 
45
+a normal Unix filesystem. As such, they can have their own internal directory 
46
+structure that hooks into the wider Unix filesystem.
36 47
 
37
-Subvolumes are natively copy-on-write and have space allocated to them on-demand
38
-from an underlying storage pool. They can also be nested and snapped. The
39
-diagram blow shows 4 subvolumes. 'Subvolume 2' and 'Subvolume 3' are nested,
40
-whereas 'Subvolume 4' shows its own internal directory tree.
48
+Subvolumes are natively copy-on-write and have space allocated to them 
49
+on-demand from an underlying storage pool. They can also be nested and snapped.
50
+ The diagram blow shows 4 subvolumes. 'Subvolume 2' and 'Subvolume 3' are 
51
+nested, whereas 'Subvolume 4' shows its own internal directory tree.
41 52
 
42 53
 ![](images/btfs_subvolume.jpg)
43 54
 
44
-Snapshots are a point-in-time read-write copy of an entire subvolume. They exist directly below the subvolume they were created from. You can create snapshots of snapshots as shown in the diagram below.
55
+Snapshots are a point-in-time read-write copy of an entire subvolume. They 
56
+exist directly below the subvolume they were created from. You can create 
57
+snapshots of snapshots as shown in the diagram below.
45 58
 
46 59
 ![](images/btfs_snapshots.jpg)
47 60
 
48
-Btfs allocates space to subvolumes and snapshots on demand from an underlying pool of storage. The unit of allocation is referred to as a *chunk* and *chunks* are normally ~1GB in size.
61
+Btfs allocates space to subvolumes and snapshots on demand from an underlying 
62
+pool of storage. The unit of allocation is referred to as a *chunk*, and 
63
+*chunks* are normally ~1GB in size.
49 64
 
50
-Snapshots are first-class citizens in a Btrfs filesystem. This means that they look, feel, and operate just like regular subvolumes. The technology required to create them is built directly into the Btrfs filesystem thanks to its native copy-on-write design. This means that Btrfs snapshots are space efficient with little or no performance overhead. The diagram below shows a subvolume and its snapshot sharing the same data.
65
+Snapshots are first-class citizens in a Btrfs filesystem. This means that they 
66
+look, feel, and operate just like regular subvolumes. The technology required 
67
+to create them is built directly into the Btrfs filesystem thanks to its 
68
+native copy-on-write design. This means that Btrfs snapshots are space 
69
+efficient with little or no performance overhead. The diagram below shows a 
70
+subvolume and its snapshot sharing the same data.
51 71
 
52 72
 ![](images/btfs_pool.jpg)
53 73
 
54
-Docker's `btrfs` storage driver stores every image layer and container in its own Btrfs subvolume or snapshot. The base layer of an image is stored as a subvolume whereas child image layers and containers are stored as snapshots. This is shown in the diagram below.
74
+Docker's `btrfs` storage driver stores every image layer and container in its 
75
+own Btrfs subvolume or snapshot. The base layer of an image is stored as a 
76
+subvolume whereas child image layers and containers are stored as snapshots. 
77
+This is shown in the diagram below.
55 78
 
56 79
 ![](images/btfs_container_layer.jpg)
57 80
 
58
-The high level process for creating images and containers on Docker hosts running the `btrfs` driver is as follows:
81
+The high level process for creating images and containers on Docker hosts 
82
+running the `btrfs` driver is as follows:
59 83
 
60
-1. The image's base layer is stored in a Btrfs subvolume under
84
+1. The image's base layer is stored in a Btrfs *subvolume* under
61 85
 `/var/lib/docker/btrfs/subvolumes`.
62 86
 
63
-    The image ID is used as the subvolume name. E.g., a base layer with image ID
64
-    "f9a9f253f6105141e0f8e091a6bcdb19e3f27af949842db93acba9048ed2410b" will be
65
-    stored in
66
-    `/var/lib/docker/btrfs/subvolumes/f9a9f253f6105141e0f8e091a6bcdb19e3f27af949842db93acba9048ed2410b`
87
+2. Subsequent image layers are stored as a Btrfs *snapshot* of the parent 
88
+layer's subvolume or snapshot.
67 89
 
68
-2. Subsequent image layers are stored as a Btrfs snapshot of the parent layer's subvolume or snapshot.
69
-
70
-    The diagram below shows a three-layer image. The base layer is a subvolume. Layer 1 is a snapshot of the base layer's subvolume. Layer 2 is a snapshot of Layer 1's snapshot.
90
+    The diagram below shows a three-layer image. The base layer is a subvolume.
91
+ Layer 1 is a snapshot of the base layer's subvolume. Layer 2 is a snapshot of 
92
+Layer 1's snapshot.
71 93
 
72 94
     ![](images/btfs_constructs.jpg)
73 95
 
96
+As of Docker 1.10, image layer IDs no longer correspond to directory names 
97
+under `/var/lib/docker/`.
98
+
74 99
 ## Image and container on-disk constructs
75 100
 
76 101
 Image layers and containers are visible in the Docker host's filesystem at
77
-`/var/lib/docker/btrfs/subvolumes/<image-id> OR <container-id>`. Directories for
102
+`/var/lib/docker/btrfs/subvolumes/`. However, as previously stated, directory 
103
+names no longer correspond to image layer IDs. That said, directories for
78 104
 containers are present even for containers with a stopped status. This is
79 105
 because the `btrfs` storage driver mounts a default, top-level subvolume at
80 106
 `/var/lib/docker/subvolumes`. All other subvolumes and snapshots exist below
81 107
 that as Btrfs filesystem objects and not as individual mounts.
82 108
 
83
-The following example shows a single Docker image with four image layers.
84
-
85
-```bash
86
-$ sudo docker images -a
87
-REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
88
-ubuntu              latest              0a17decee413        2 weeks ago         188.3 MB
89
-<none>              <none>              3c9a9d7cc6a2        2 weeks ago         188.3 MB
90
-<none>              <none>              eeb7cb91b09d        2 weeks ago         188.3 MB
91
-<none>              <none>              f9a9f253f610        2 weeks ago         188.1 MB
92
-```
93
-
94
-Each image layer exists as a Btrfs subvolume or snapshot with the same name as its image ID as illustrated by the `btrfs subvolume list` command shown below:
95
-
96
-```bash
97
-$ sudo btrfs subvolume list /var/lib/docker
98
-ID 257 gen 9 top level 5 path btrfs/subvolumes/f9a9f253f6105141e0f8e091a6bcdb19e3f27af949842db93acba9048ed2410b
99
-ID 258 gen 10 top level 5 path btrfs/subvolumes/eeb7cb91b09d5de9edb2798301aeedf50848eacc2123e98538f9d014f80f243c
100
-ID 260 gen 11 top level 5 path btrfs/subvolumes/3c9a9d7cc6a235eb2de58ca9ef3551c67ae42a991933ba4958d207b29142902b
101
-ID 261 gen 12 top level 5 path btrfs/subvolumes/0a17decee4139b0de68478f149cc16346f5e711c5ae3bb969895f22dd6723751
102
-```
103
-
104
-Under the `/var/lib/docker/btrfs/subvolumes` directory, each of these subvolumes and snapshots are visible as a normal Unix directory:
105
-
106
-```bash
107
-$ ls -l /var/lib/docker/btrfs/subvolumes/
108
-total 0
109
-drwxr-xr-x 1 root root 132 Oct 16 14:44 0a17decee4139b0de68478f149cc16346f5e711c5ae3bb969895f22dd6723751
110
-drwxr-xr-x 1 root root 132 Oct 16 14:44 3c9a9d7cc6a235eb2de58ca9ef3551c67ae42a991933ba4958d207b29142902b
111
-drwxr-xr-x 1 root root 132 Oct 16 14:44 eeb7cb91b09d5de9edb2798301aeedf50848eacc2123e98538f9d014f80f243c
112
-drwxr-xr-x 1 root root 132 Oct 16 14:44 f9a9f253f6105141e0f8e091a6bcdb19e3f27af949842db93acba9048ed2410b
113
-```
114
-
115 109
 Because Btrfs works at the filesystem level and not the block level, each image
116
-and container layer can be browsed in the filesystem using normal Unix commands.
117
-The example below shows a truncated output of an `ls -l` command against the
118
-image's top layer:
119
-
120
-```bash
121
-$ ls -l /var/lib/docker/btrfs/subvolumes/0a17decee4139b0de68478f149cc16346f5e711c5ae3bb969895f22dd6723751/
122
-total 0
123
-drwxr-xr-x 1 root root 1372 Oct  9 08:39 bin
124
-drwxr-xr-x 1 root root    0 Apr 10  2014 boot
125
-drwxr-xr-x 1 root root  882 Oct  9 08:38 dev
126
-drwxr-xr-x 1 root root 2040 Oct 12 17:27 etc
127
-drwxr-xr-x 1 root root    0 Apr 10  2014 home
128
-...output truncated...
129
-```
110
+and container layer can be browsed in the filesystem using normal Unix 
111
+commands. The example below shows a truncated output of an `ls -l` command an 
112
+image layer:
113
+
114
+    $ ls -l /var/lib/docker/btrfs/subvolumes/0a17decee4139b0de68478f149cc16346f5e711c5ae3bb969895f22dd6723751/
115
+    total 0
116
+    drwxr-xr-x 1 root root 1372 Oct  9 08:39 bin
117
+    drwxr-xr-x 1 root root    0 Apr 10  2014 boot
118
+    drwxr-xr-x 1 root root  882 Oct  9 08:38 dev
119
+    drwxr-xr-x 1 root root 2040 Oct 12 17:27 etc
120
+    drwxr-xr-x 1 root root    0 Apr 10  2014 home
121
+    ...output truncated...
130 122
 
131 123
 ## Container reads and writes with Btrfs
132 124
 
133 125
 A container is a space-efficient snapshot of an image. Metadata in the snapshot
134
-points to the actual data blocks in the storage pool. This is the same as with a
135
-subvolume. Therefore, reads performed against a snapshot are essentially the
126
+points to the actual data blocks in the storage pool. This is the same as with 
127
+a subvolume. Therefore, reads performed against a snapshot are essentially the
136 128
 same as reads performed against a subvolume. As a result, no performance
137 129
 overhead is incurred from the Btrfs driver.
138 130
 
... ...
@@ -145,28 +137,34 @@ new files to a container's snapshot operate at native Btrfs speeds.
145 145
 Updating an existing file in a container causes a copy-on-write operation
146 146
 (technically *redirect-on-write*). The driver leaves the original data and
147 147
 allocates new space to the snapshot. The updated data is written to this new
148
-space. Then, the driver updates the filesystem metadata in the snapshot to point
149
-to this new data. The original data is preserved in-place for subvolumes and
150
-snapshots further up the tree. This behavior is native to copy-on-write
148
+space. Then, the driver updates the filesystem metadata in the snapshot to 
149
+point to this new data. The original data is preserved in-place for subvolumes 
150
+and snapshots further up the tree. This behavior is native to copy-on-write
151 151
 filesystems like Btrfs and incurs very little overhead.
152 152
 
153
-With Btfs, writing and updating lots of small files can result in slow performance. More on this later.
153
+With Btfs, writing and updating lots of small files can result in slow 
154
+performance. More on this later.
154 155
 
155 156
 ## Configuring Docker with Btrfs
156 157
 
157
-The `btrfs` storage driver only operates on a Docker host where `/var/lib/docker` is mounted as a Btrfs filesystem. The following procedure shows  how to configure Btrfs on Ubuntu 14.04 LTS.
158
+The `btrfs` storage driver only operates on a Docker host where 
159
+`/var/lib/docker` is mounted as a Btrfs filesystem. The following procedure 
160
+shows  how to configure Btrfs on Ubuntu 14.04 LTS.
158 161
 
159 162
 ### Prerequisites
160 163
 
161
-If you have already used the Docker daemon on your Docker host and have images you want to keep, `push` them to Docker Hub or your private Docker Trusted Registry before attempting this procedure.
164
+If you have already used the Docker daemon on your Docker host and have images 
165
+you want to keep, `push` them to Docker Hub or your private Docker Trusted 
166
+Registry before attempting this procedure.
162 167
 
163
-Stop the Docker daemon. Then, ensure that you have a spare block device at `/dev/xvdb`. The device identifier may be different in your environment and you should substitute your own values throughout the procedure.
168
+Stop the Docker daemon. Then, ensure that you have a spare block device at 
169
+`/dev/xvdb`. The device identifier may be different in your environment and you
170
+ should substitute your own values throughout the procedure.
164 171
 
165
-The procedure also assumes your kernel has the appropriate Btrfs modules loaded. To verify this, use the following command:
172
+The procedure also assumes your kernel has the appropriate Btrfs modules 
173
+loaded. To verify this, use the following command:
166 174
 
167
-```bash
168
-$ cat /proc/filesystems | grep btrfs
169
-```
175
+    $ cat /proc/filesystems | grep btrfs
170 176
 
171 177
 ### Configure Btrfs on Ubuntu 14.04 LTS
172 178
 
... ...
@@ -181,7 +179,9 @@ Assuming your system meets the prerequisites, do the following:
181 181
 
182 182
 2. Create the Btrfs storage pool.
183 183
 
184
-    Btrfs storage pools are created with the `mkfs.btrfs` command. Passing multiple devices to the `mkfs.btrfs` command creates a pool across all of those devices. Here you create a pool with a single device at `/dev/xvdb`.
184
+    Btrfs storage pools are created with the `mkfs.btrfs` command. Passing 
185
+multiple devices to the `mkfs.btrfs` command creates a pool across all of those
186
+ devices. Here you create a pool with a single device at `/dev/xvdb`.
185 187
 
186 188
         $ sudo mkfs.btrfs -f /dev/xvdb
187 189
         WARNING! - Btrfs v3.12 IS EXPERIMENTAL
... ...
@@ -199,7 +199,8 @@ Assuming your system meets the prerequisites, do the following:
199 199
     noted earlier, Btrfs is not currently recommended for production deployments
200 200
     unless you already have extensive experience.
201 201
 
202
-3. If it does not already exist, create a directory for the Docker host's local storage area at `/var/lib/docker`.
202
+3. If it does not already exist, create a directory for the Docker host's local
203
+ storage area at `/var/lib/docker`.
203 204
 
204 205
         $ sudo mkdir /var/lib/docker
205 206
 
... ...
@@ -210,7 +211,10 @@ Assuming your system meets the prerequisites, do the following:
210 210
         $ sudo blkid /dev/xvdb
211 211
         /dev/xvdb: UUID="a0ed851e-158b-4120-8416-c9b072c8cf47" UUID_SUB="c3927a64-4454-4eef-95c2-a7d44ac0cf27" TYPE="btrfs"
212 212
 
213
-    b. Create a `/etc/fstab` entry to automatically mount `/var/lib/docker` each time the system boots.
213
+    b. Create an `/etc/fstab` entry to automatically mount `/var/lib/docker` 
214
+each time the system boots. Either of the following lines will work, just 
215
+remember to substitute the UUID value with the value obtained from the previous
216
+ command.
214 217
 
215 218
         /dev/xvdb /var/lib/docker btrfs defaults 0 0
216 219
         UUID="a0ed851e-158b-4120-8416-c9b072c8cf47" /var/lib/docker btrfs defaults 0 0
... ...
@@ -223,10 +227,11 @@ Assuming your system meets the prerequisites, do the following:
223 223
         <output truncated>
224 224
         /dev/xvdb on /var/lib/docker type btrfs (rw)
225 225
 
226
-    The last line in the output above shows the `/dev/xvdb` mounted at `/var/lib/docker` as Btrfs.
227
-
226
+    The last line in the output above shows the `/dev/xvdb` mounted at 
227
+`/var/lib/docker` as Btrfs.
228 228
 
229
-Now that you have a Btrfs filesystem mounted at `/var/lib/docker`, the daemon should automatically load with the `btrfs` storage driver.
229
+Now that you have a Btrfs filesystem mounted at `/var/lib/docker`, the daemon 
230
+should automatically load with the `btrfs` storage driver.
230 231
 
231 232
 1. Start the Docker daemon.
232 233
 
... ...
@@ -236,9 +241,10 @@ Now that you have a Btrfs filesystem mounted at `/var/lib/docker`, the daemon sh
236 236
     The procedure for starting the Docker daemon may differ depending on the
237 237
     Linux distribution you are using.
238 238
 
239
-    You can start the Docker daemon with the `btrfs` storage driver by passing
240
-    the `--storage-driver=btrfs` flag to the `docker daemon` command or you can
241
-    add the `DOCKER_OPTS` line to the Docker config file.
239
+    You can force the the Docker daemon to start with the `btrfs` storage 
240
+driver by either passing the `--storage-driver=btrfs` flag to the `docker 
241
+daemon` at startup, or adding it to the `DOCKER_OPTS` line to the Docker config
242
+ file.
242 243
 
243 244
 2. Verify the storage driver with the `docker info` command.
244 245
 
... ...
@@ -252,25 +258,54 @@ Your Docker host is now configured to use the `btrfs` storage driver.
252 252
 
253 253
 ## Btrfs and Docker performance
254 254
 
255
-There are several factors that influence Docker's performance under the  `btrfs` storage driver.
256
-
257
-- **Page caching**. Btrfs does not support page cache sharing. This means that *n* containers accessing the same file require *n* copies to be cached. As a result, the `btrfs` driver may not be the best choice for PaaS and other high density container use cases.
258
-
259
-- **Small writes**. Containers performing lots of small writes (including Docker hosts that start and stop many containers) can lead to poor use of Btrfs chunks. This can ultimately lead to out-of-space conditions on your Docker host and stop it working. This is currently a major drawback to using current versions of Btrfs.
260
-
261
-    If you use the `btrfs` storage driver, closely monitor the free space on your Btrfs filesystem using the `btrfs filesys show` command. Do not trust the output of normal Unix commands such as `df`; always use the Btrfs native commands.
262
-
263
-- **Sequential writes**. Btrfs writes data to disk via journaling technique. This can impact sequential writes, where performance can be up to half.
264
-
265
-- **Fragmentation**. Fragmentation is a natural byproduct of copy-on-write filesystems like Btrfs. Many small random writes can compound this issue. It can manifest as CPU spikes on Docker hosts using SSD media and head thrashing on Docker hosts using spinning media. Both of these result in poor performance.
266
-
267
-    Recent versions of Btrfs allow you to specify `autodefrag` as a mount option. This mode attempts to detect random writes and defragment them. You should perform your own tests before enabling this option on your Docker hosts. Some tests have shown this option has a negative performance impact on Docker hosts performing lots of small writes (including systems that start and stop many containers).
268
-
269
-- **Solid State Devices (SSD)**. Btrfs has native optimizations for SSD media. To enable these, mount with the `-o ssd` mount option. These optimizations include enhanced SSD write performance by avoiding things like *seek optimizations* that have no use on SSD media.
270
-
271
-    Btfs also supports the TRIM/Discard primitives. However, mounting with the `-o discard` mount option can cause performance issues. Therefore, it is recommended you perform your own tests before using this option.
272
-
273
-- **Use Data Volumes**. Data volumes provide the best and most predictable performance. This is because they bypass the storage driver and do not incur any of the potential overheads introduced by thin provisioning and copy-on-write. For this reason, you may want to place heavy write workloads on data volumes.
255
+There are several factors that influence Docker's performance under the `btrfs`
256
+ storage driver.
257
+
258
+- **Page caching**. Btrfs does not support page cache sharing. This means that 
259
+*n* containers accessing the same file require *n* copies to be cached. As a 
260
+result, the `btrfs` driver may not be the best choice for PaaS and other high 
261
+density container use cases.
262
+
263
+- **Small writes**. Containers performing lots of small writes (including 
264
+Docker hosts that start and stop many containers) can lead to poor use of Btrfs
265
+ chunks. This can ultimately lead to out-of-space conditions on your Docker 
266
+host and stop it working. This is currently a major drawback to using current 
267
+versions of Btrfs.
268
+
269
+    If you use the `btrfs` storage driver, closely monitor the free space on 
270
+your Btrfs filesystem using the `btrfs filesys show` command. Do not trust the 
271
+output of normal Unix commands such as `df`; always use the Btrfs native 
272
+commands.
273
+
274
+- **Sequential writes**. Btrfs writes data to disk via journaling technique. 
275
+This can impact sequential writes, where performance can be up to half.
276
+
277
+- **Fragmentation**. Fragmentation is a natural byproduct of copy-on-write 
278
+filesystems like Btrfs. Many small random writes can compound this issue. It 
279
+can manifest as CPU spikes on Docker hosts using SSD media and head thrashing 
280
+on Docker hosts using spinning media. Both of these result in poor performance.
281
+
282
+    Recent versions of Btrfs allow you to specify `autodefrag` as a mount 
283
+option. This mode attempts to detect random writes and defragment them. You 
284
+should perform your own tests before enabling this option on your Docker hosts.
285
+ Some tests have shown this option has a negative performance impact on Docker 
286
+hosts performing lots of small writes (including systems that start and stop 
287
+many containers).
288
+
289
+- **Solid State Devices (SSD)**. Btrfs has native optimizations for SSD media. 
290
+To enable these, mount with the `-o ssd` mount option. These optimizations 
291
+include enhanced SSD write performance by avoiding things like *seek 
292
+optimizations* that have no use on SSD media.
293
+
294
+    Btfs also supports the TRIM/Discard primitives. However, mounting with the 
295
+`-o discard` mount option can cause performance issues. Therefore, it is 
296
+recommended you perform your own tests before using this option.
297
+
298
+- **Use Data Volumes**. Data volumes provide the best and most predictable 
299
+performance. This is because they bypass the storage driver and do not incur 
300
+any of the potential overheads introduced by thin provisioning and 
301
+copy-on-write. For this reason, you should place heavy write workloads on data 
302
+volumes.
274 303
 
275 304
 ## Related Information
276 305
 
... ...
@@ -51,56 +51,84 @@ Device Mapper technology works at the block level rather than the file level.
51 51
 This means that `devicemapper` storage driver's thin provisioning and
52 52
 copy-on-write operations work with blocks rather than entire files.
53 53
 
54
->**Note**: Snapshots are also referred to as *thin devices* or *virtual devices*. They all mean the same thing in the context of the `devicemapper` storage driver.
54
+>**Note**: Snapshots are also referred to as *thin devices* or *virtual 
55
+>devices*. They all mean the same thing in the context of the `devicemapper` 
56
+>storage driver.
55 57
 
56
-With the `devicemapper` the high level process for creating images is as follows:
58
+With `devicemapper` the high level process for creating images is as follows:
57 59
 
58 60
 1. The `devicemapper` storage driver creates a thin pool.
59 61
 
60
-    The pool is created from block devices or loop mounted sparse files (more on this later).
62
+    The pool is created from block devices or loop mounted sparse files (more 
63
+on this later).
61 64
 
62 65
 2. Next it creates a *base device*.
63 66
 
64
-    A base device is a thin device with a filesystem. You can see which filesystem is in use by running the `docker info` command and checking the `Backing filesystem` value.
67
+    A base device is a thin device with a filesystem. You can see which 
68
+filesystem is in use by running the `docker info` command and checking the 
69
+`Backing filesystem` value.
65 70
 
66 71
 3. Each new image (and image layer) is a snapshot of this base device.
67 72
 
68
-    These are thin provisioned copy-on-write snapshots. This means that they are initially empty and only consume space from the pool when data is written to them.
73
+    These are thin provisioned copy-on-write snapshots. This means that they 
74
+are initially empty and only consume space from the pool when data is written 
75
+to them.
69 76
 
70
-With `devicemapper`, container layers are snapshots of the image they are created from. Just as with images, container snapshots are thin provisioned copy-on-write snapshots. The container snapshot stores all updates to the container. The `devicemapper` allocates space to them on-demand from the pool as and when data is written to the container.
77
+With `devicemapper`, container layers are snapshots of the image they are 
78
+created from. Just as with images, container snapshots are thin provisioned 
79
+copy-on-write snapshots. The container snapshot stores all updates to the 
80
+container. The `devicemapper` allocates space to them on-demand from the pool 
81
+as and when data is written to the container.
71 82
 
72
-The high level diagram below shows a thin pool with a base device and two images.
83
+The high level diagram below shows a thin pool with a base device and two 
84
+images.
73 85
 
74 86
 ![](images/base_device.jpg)
75 87
 
76
-If you look closely at the diagram you'll see that it's snapshots all the way down. Each image layer is a snapshot of the layer below it. The lowest layer of each image is a snapshot of the the base device that exists in the pool. This base device is a `Device Mapper` artifact and not a Docker image layer.
88
+If you look closely at the diagram you'll see that it's snapshots all the way 
89
+down. Each image layer is a snapshot of the layer below it. The lowest layer of
90
+ each image is a snapshot of the the base device that exists in the pool. This 
91
+base device is a `Device Mapper` artifact and not a Docker image layer.
77 92
 
78
-A container is a snapshot of the image it is created from. The diagram below shows two containers - one based on the Ubuntu image and the other based on the Busybox image.
93
+A container is a snapshot of the image it is created from. The diagram below 
94
+shows two containers - one based on the Ubuntu image and the other based on the
95
+ Busybox image.
79 96
 
80 97
 ![](images/two_dm_container.jpg)
81 98
 
82 99
 
83 100
 ## Reads with the devicemapper
84 101
 
85
-Let's look at how reads and writes occur using the `devicemapper` storage driver. The diagram below shows the high level process for reading a single block (`0x44f`) in an example container.
102
+Let's look at how reads and writes occur using the `devicemapper` storage 
103
+driver. The diagram below shows the high level process for reading a single 
104
+block (`0x44f`) in an example container.
86 105
 
87 106
 ![](images/dm_container.jpg)
88 107
 
89
-1. An application makes a read request for block 0x44f in the container.
108
+1. An application makes a read request for block `0x44f` in the container.
90 109
 
91
-    Because the container is a thin snapshot of an image it does not have the data. Instead, it has a pointer (PTR) to where the data is stored in the  image snapshot lower down in the image stack.
110
+    Because the container is a thin snapshot of an image it does not have the 
111
+data. Instead, it has a pointer (PTR) to where the data is stored in the image 
112
+snapshot lower down in the image stack.
92 113
 
93
-2. The storage driver follows the pointer to block `0xf33` in the snapshot relating to image layer `a005...`.
114
+2. The storage driver follows the pointer to block `0xf33` in the snapshot 
115
+relating to image layer `a005...`.
94 116
 
95
-3. The `devicemapper` copies the contents of block `0xf33` from the image snapshot to memory in the container.
117
+3. The `devicemapper` copies the contents of block `0xf33` from the image 
118
+snapshot to memory in the container.
96 119
 
97 120
 4. The storage driver returns the data to the requesting application.
98 121
 
99 122
 ### Write examples
100 123
 
101
-With the `devicemapper` driver, writing new data to a container is accomplished by an *allocate-on-demand* operation. Updating existing data uses a copy-on-write operation. Because Device Mapper is a block-based technology these operations occur at the block level.
124
+With the `devicemapper` driver, writing new data to a container is accomplished
125
+ by an *allocate-on-demand* operation. Updating existing data uses a 
126
+copy-on-write operation. Because Device Mapper is a block-based technology 
127
+these operations occur at the block level.
102 128
 
103
-For example, when  making a small change to a large file in a container, the `devicemapper` storage driver does not copy the entire file. It only copies the blocks to be modified. Each block is 64KB.
129
+For example, when making a small change to a large file in a container, the 
130
+`devicemapper` storage driver does not copy the entire file. It only copies the
131
+ blocks to be modified. Each block is 64KB.
104 132
 
105 133
 #### Writing new data
106 134
 
... ...
@@ -108,9 +136,11 @@ To write 56KB of new data to a container:
108 108
 
109 109
 1. An application makes a request to write 56KB of new data to the container.
110 110
 
111
-2. The allocate-on-demand operation allocates a single new 64KB block to the containers snapshot.
111
+2. The allocate-on-demand operation allocates a single new 64KB block to the 
112
+container's snapshot.
112 113
 
113
-    If the write operation is larger than 64KB, multiple new blocks are allocated to the container snapshot.
114
+    If the write operation is larger than 64KB, multiple new blocks are 
115
+allocated to the container's snapshot.
114 116
 
115 117
 3. The data is written to the newly allocated block.
116 118
 
... ...
@@ -122,7 +152,8 @@ To modify existing data for the first time:
122 122
 
123 123
 2. A copy-on-write operation locates the blocks that need updating.
124 124
 
125
-3. The operation allocates new blocks to the container snapshot and copies the data into those blocks.
125
+3. The operation allocates new empty blocks to the container snapshot and 
126
+copies the data into those blocks.
126 127
 
127 128
 4. The modified data is written into the newly allocated blocks.
128 129
 
... ...
@@ -133,7 +164,8 @@ to the application's read and write operations.
133 133
 ## Configuring Docker with Device Mapper
134 134
 
135 135
 The `devicemapper` is the default Docker storage driver on some Linux
136
-distributions. This includes RHEL and most of its forks. Currently, the following distributions support the driver:
136
+distributions. This includes RHEL and most of its forks. Currently, the 
137
+following distributions support the driver:
137 138
 
138 139
 * RHEL/CentOS/Fedora
139 140
 * Ubuntu 12.04          
... ...
@@ -142,9 +174,9 @@ distributions. This includes RHEL and most of its forks. Currently, the followin
142 142
 
143 143
 Docker hosts running the `devicemapper` storage driver default to a
144 144
 configuration mode known as `loop-lvm`. This mode uses sparse files to build
145
-the thin pool used by image and container snapshots. The mode is designed to work out-of-the-box
146
-with no additional configuration. However, production deployments should not run
147
-under `loop-lvm` mode.
145
+the thin pool used by image and container snapshots. The mode is designed to 
146
+work out-of-the-box with no additional configuration. However, production 
147
+deployments should not run under `loop-lvm` mode.
148 148
 
149 149
 You can detect the mode by viewing the `docker info` command:
150 150
 
... ...
@@ -161,56 +193,84 @@ You can detect the mode by viewing the `docker info` command:
161 161
      Library Version: 1.02.93-RHEL7 (2015-01-28)
162 162
      ...
163 163
 
164
-The output above shows a Docker host running with the `devicemapper` storage driver operating in `loop-lvm` mode. This is indicated by the fact that the `Data loop file` and a `Metadata loop file` are on files under `/var/lib/docker/devicemapper/devicemapper`. These are loopback mounted sparse files.
164
+The output above shows a Docker host running with the `devicemapper` storage 
165
+driver operating in `loop-lvm` mode. This is indicated by the fact that the 
166
+`Data loop file` and a `Metadata loop file` are on files under 
167
+`/var/lib/docker/devicemapper/devicemapper`. These are loopback mounted sparse 
168
+files.
165 169
 
166 170
 ### Configure direct-lvm mode for production
167 171
 
168 172
 The preferred configuration for production deployments is `direct lvm`. This
169 173
 mode uses block devices to create the thin pool. The following procedure shows
170
-you how to configure a Docker host to use the `devicemapper` storage driver in a
171
-`direct-lvm` configuration.
174
+you how to configure a Docker host to use the `devicemapper` storage driver in 
175
+a `direct-lvm` configuration.
172 176
 
173
-> **Caution:** If you have already run the Docker daemon on your Docker host and have images you want to keep, `push` them Docker Hub or your private Docker Trusted Registry before attempting this procedure.
177
+> **Caution:** If you have already run the Docker daemon on your Docker host 
178
+> and have images you want to keep, `push` them Docker Hub or your private 
179
+> Docker Trusted Registry before attempting this procedure.
174 180
 
175
-The procedure below will create a 90GB data volume and 4GB metadata volume to use as backing for the storage pool. It assumes that you have a spare block device at `/dev/xvdf` with enough free space to complete the task. The device identifier and volume sizes may be be different in your environment and you should substitute your own values throughout the procedure. The procedure also assumes that the Docker daemon is in the `stopped` state.
181
+The procedure below will create a 90GB data volume and 4GB metadata volume to 
182
+use as backing for the storage pool. It assumes that you have a spare block 
183
+device at `/dev/xvdf` with enough free space to complete the task. The device 
184
+identifier and volume sizes may be be different in your environment and you 
185
+should substitute your own values throughout the procedure. The procedure also 
186
+assumes that the Docker daemon is in the `stopped` state.
176 187
 
177 188
 1. Log in to the Docker host you want to configure and stop the Docker daemon.
178 189
 
179
-2. If it exists, delete your existing image store by removing the `/var/lib/docker` directory.
190
+2. If it exists, delete your existing image store by removing the 
191
+`/var/lib/docker` directory.
180 192
 
181 193
         $ sudo rm -rf /var/lib/docker
182 194
 
183
-3. Create an LVM physical volume (PV) on your spare block device using the `pvcreate` command.
195
+3. Create an LVM physical volume (PV) on your spare block device using the 
196
+`pvcreate` command.
184 197
 
185 198
         $ sudo pvcreate /dev/xvdf
186 199
         Physical volume `/dev/xvdf` successfully created
187 200
 
188
-    The device identifier may be different on your system. Remember to substitute your value in the command above.
201
+    The device identifier may be different on your system. Remember to 
202
+substitute your value in the command above.
189 203
 
190
-4. Create a new volume group (VG) called `vg-docker` using the PV created in the previous step.
204
+4. Create a new volume group (VG) called `vg-docker` using the PV created in 
205
+the previous step.
191 206
 
192 207
         $ sudo vgcreate vg-docker /dev/xvdf
193 208
         Volume group `vg-docker` successfully created
194 209
 
195
-5. Create a new 90GB logical volume (LV) called `data` from space in the `vg-docker` volume group.
210
+5. Create a new 90GB logical volume (LV) called `data` from space in the 
211
+`vg-docker` volume group.
196 212
 
197 213
         $ sudo lvcreate -L 90G -n data vg-docker
198 214
         Logical volume `data` created.
199 215
 
200
-    The command creates an LVM logical volume called `data` and an associated block device file at `/dev/vg-docker/data`. In a later step, you instruct the `devicemapper` storage driver to use this block device to store image and container data.
216
+    The command creates an LVM logical volume called `data` and an associated 
217
+block device file at `/dev/vg-docker/data`. In a later step, you instruct the 
218
+`devicemapper` storage driver to use this block device to store image and 
219
+container data.
201 220
 
202
-    If you receive a signature detection warning, make sure you are working on the correct devices before continuing. Signature warnings indicate that the device you're working on is currently in use by LVM or has been used by LVM in the past.
221
+    If you receive a signature detection warning, make sure you are working on 
222
+the correct devices before continuing. Signature warnings indicate that the 
223
+device you're working on is currently in use by LVM or has been used by LVM in 
224
+the past.
203 225
 
204
-6. Create a new logical volume (LV) called `metadata` from space in the `vg-docker` volume group.
226
+6. Create a new logical volume (LV) called `metadata` from space in the 
227
+`vg-docker` volume group.
205 228
 
206 229
         $ sudo lvcreate -L 4G -n metadata vg-docker
207 230
         Logical volume `metadata` created.
208 231
 
209
-    This creates an LVM logical volume called `metadata` and an associated block device file at `/dev/vg-docker/metadata`. In the next step you instruct the `devicemapper` storage driver to use this block device to store image and container metadata.
232
+    This creates an LVM logical volume called `metadata` and an associated 
233
+block device file at `/dev/vg-docker/metadata`. In the next step you instruct 
234
+the `devicemapper` storage driver to use this block device to store image and 
235
+container metadata.
210 236
 
211
-5. Start the Docker daemon with the `devicemapper` storage driver and the `--storage-opt` flags.
237
+7. Start the Docker daemon with the `devicemapper` storage driver and the 
238
+`--storage-opt` flags.
212 239
 
213
-    The `data` and `metadata` devices that you pass to the `--storage-opt` options were created in the previous steps.
240
+    The `data` and `metadata` devices that you pass to the `--storage-opt` 
241
+options were created in the previous steps.
214 242
 
215 243
           $ sudo docker daemon --storage-driver=devicemapper --storage-opt dm.datadev=/dev/vg-docker/data --storage-opt dm.metadatadev=/dev/vg-docker/metadata &
216 244
           [1] 2163
... ...
@@ -221,11 +281,12 @@ The procedure below will create a 90GB data volume and 4GB metadata volume to us
221 221
           INFO[0027] Daemon has completed initialization
222 222
           INFO[0027] Docker daemon commit=0a8c2e3 execdriver=native-0.2 graphdriver=devicemapper version=1.8.2
223 223
 
224
-    It is also possible to set the `--storage-driver` and `--storage-opt` flags in
225
-    the Docker config file and start the daemon normally using the `service` or
226
-    `systemd` commands.
224
+    It is also possible to set the `--storage-driver` and `--storage-opt` flags
225
+ in the Docker config file and start the daemon normally using the `service` or
226
+ `systemd` commands.
227 227
 
228
-6. Use the `docker info` command to verify that the daemon is using `data` and `metadata` devices you created.
228
+8. Use the `docker info` command to verify that the daemon is using `data` and 
229
+`metadata` devices you created.
229 230
 
230 231
         $ sudo docker info
231 232
         INFO[0180] GET /v1.20/info
... ...
@@ -239,11 +300,14 @@ The procedure below will create a 90GB data volume and 4GB metadata volume to us
239 239
          Metadata file: /dev/vg-docker/metadata
240 240
         [...]
241 241
 
242
-    The output of the command above shows the storage driver as `devicemapper`. The last two lines also confirm that the correct devices are being used for the `Data file` and the `Metadata file`.
242
+    The output of the command above shows the storage driver as `devicemapper`.
243
+ The last two lines also confirm that the correct devices are being used for 
244
+the `Data file` and the `Metadata file`.
243 245
 
244 246
 ### Examine devicemapper structures on the host
245 247
 
246
-You can use the `lsblk` command to see the device files created above and the `pool` that the `devicemapper` storage driver creates on top of them.
248
+You can use the `lsblk` command to see the device files created above and the 
249
+`pool` that the `devicemapper` storage driver creates on top of them.
247 250
 
248 251
     $ sudo lsblk
249 252
     NAME                       MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
... ...
@@ -255,11 +319,14 @@ You can use the `lsblk` command to see the device files created above and the `p
255 255
     └─vg--docker-metadata      253:1    0    4G  0 lvm
256 256
       └─docker-202:1-1032-pool 253:2    0   10G  0 dm
257 257
 
258
-The diagram below shows the image from prior examples updated with the detail from the `lsblk` command above.
258
+The diagram below shows the image from prior examples updated with the detail 
259
+from the `lsblk` command above.
259 260
 
260 261
 ![](http://farm1.staticflickr.com/703/22116692899_0471e5e160_b.jpg)
261 262
 
262
-In the diagram, the pool is named `Docker-202:1-1032-pool` and spans the `data` and `metadata` devices created earlier. The `devicemapper` constructs the pool name as follows:
263
+In the diagram, the pool is named `Docker-202:1-1032-pool` and spans the `data`
264
+ and `metadata` devices created earlier. The `devicemapper` constructs the pool
265
+ name as follows:
263 266
 
264 267
 ```
265 268
 Docker-MAJ:MIN-INO-pool
... ...
@@ -268,41 +335,74 @@ Docker-MAJ:MIN-INO-pool
268 268
 `MAJ`, `MIN` and `INO` refer to the major and minor device numbers and inode.
269 269
 
270 270
 Because Device Mapper operates at the block level it is more difficult to see
271
-diffs between image layers and containers. However, there are two key
272
-directories. The `/var/lib/docker/devicemapper/mnt` directory contains the mount
273
-points for images and containers. The `/var/lib/docker/devicemapper/metadata`
274
-directory contains one file for every image and container snapshot. The files
275
-contain metadata about each snapshot in JSON format.
271
+diffs between image layers and containers. Docker 1.10 and later no longer 
272
+matches image layer IDs with directory names in `/var/lib/docker`.  However, 
273
+there are two key directories. The `/var/lib/docker/devicemapper/mnt` directory
274
+ contains the mount points for image and container layers. The 
275
+`/var/lib/docker/devicemapper/metadata`directory contains one file for every 
276
+image layer and container snapshot. The files contain metadata about each 
277
+snapshot in JSON format.
276 278
 
277 279
 ## Device Mapper and Docker performance
278 280
 
279
-It is important to understand the impact that allocate-on-demand and copy-on-write operations can have on overall container performance.
281
+It is important to understand the impact that allocate-on-demand and 
282
+copy-on-write operations can have on overall container performance.
280 283
 
281 284
 ### Allocate-on-demand performance impact
282 285
 
283
-The `devicemapper` storage driver allocates new blocks to a container via an allocate-on-demand operation. This means that each time an app writes to somewhere new inside a container, one or more empty blocks has to be located from the pool and mapped into the container.
286
+The `devicemapper` storage driver allocates new blocks to a container via an 
287
+allocate-on-demand operation. This means that each time an app writes to 
288
+somewhere new inside a container, one or more empty blocks has to be located 
289
+from the pool and mapped into the container.
284 290
 
285
-All blocks are 64KB. A write that uses less than 64KB still results in a single 64KB block being allocated. Writing more than 64KB of data uses multiple 64KB blocks. This can impact container performance, especially in containers that perform lots of small writes. However, once a block is allocated to a container subsequent reads and writes can operate directly on that block.
291
+All blocks are 64KB. A write that uses less than 64KB still results in a single
292
+ 64KB block being allocated. Writing more than 64KB of data uses multiple 64KB 
293
+blocks. This can impact container performance, especially in containers that 
294
+perform lots of small writes. However, once a block is allocated to a container
295
+ subsequent reads and writes can operate directly on that block.
286 296
 
287 297
 ### Copy-on-write performance impact
288 298
 
289
-Each time a container updates existing data for the first time, the `devicemapper` storage driver has to perform a copy-on-write operation. This copies the data from the image snapshot to the container's snapshot. This process can have a noticeable impact on container performance.
299
+Each time a container updates existing data for the first time, the 
300
+`devicemapper` storage driver has to perform a copy-on-write operation. This 
301
+copies the data from the image snapshot to the container's snapshot. This 
302
+process can have a noticeable impact on container performance.
290 303
 
291
-All copy-on-write operations have a 64KB granularity. As a results, updating 32KB of a 1GB file causes the driver to copy a single 64KB block into the container's snapshot. This has obvious performance advantages over file-level copy-on-write operations which would require copying the entire 1GB file into the container layer.
304
+All copy-on-write operations have a 64KB granularity. As a results, updating 
305
+32KB of a 1GB file causes the driver to copy a single 64KB block into the 
306
+container's snapshot. This has obvious performance advantages over file-level 
307
+copy-on-write operations which would require copying the entire 1GB file into 
308
+the container layer.
292 309
 
293
-In practice, however, containers that perform lots of small block writes (<64KB) can perform worse with `devicemapper` than with AUFS.
310
+In practice, however, containers that perform lots of small block writes 
311
+(<64KB) can perform worse with `devicemapper` than with AUFS.
294 312
 
295 313
 ### Other device mapper performance considerations
296 314
 
297
-There are several other things that impact the performance of the `devicemapper` storage driver..
298
-
299
-- **The mode.** The default mode for Docker running the `devicemapper` storage driver is `loop-lvm`. This mode uses sparse files and suffers from poor performance. It is **not recommended for production**. The recommended mode for production environments is `direct-lvm` where the storage driver writes directly to raw block devices.
300
-
301
-- **High speed storage.** For best performance you should place the `Data file` and `Metadata file` on high speed storage such as SSD. This can be direct attached storage or from a SAN or NAS array.
302
-
303
-- **Memory usage.** `devicemapper` is not the most memory efficient Docker storage driver. Launching *n* copies of the same container loads *n* copies of its files into memory. This can have a memory impact on your Docker host. As a result, the `devicemapper` storage driver may not be the best choice for PaaS and other high density use cases.
304
-
305
-One final point, data volumes provide the best and most predictable performance. This is because they bypass the storage driver and do not incur any of the potential overheads introduced by thin provisioning and copy-on-write. For this reason, you may want to place heavy write workloads on data volumes.
315
+There are several other things that impact the performance of the 
316
+`devicemapper` storage driver.
317
+
318
+- **The mode.** The default mode for Docker running the `devicemapper` storage 
319
+driver is `loop-lvm`. This mode uses sparse files and suffers from poor 
320
+performance. It is **not recommended for production**. The recommended mode for
321
+ production environments is `direct-lvm` where the storage driver writes 
322
+directly to raw block devices.
323
+
324
+- **High speed storage.** For best performance you should place the `Data file`
325
+ and `Metadata file` on high speed storage such as SSD. This can be direct 
326
+attached storage or from a SAN or NAS array.
327
+
328
+- **Memory usage.** `devicemapper` is not the most memory efficient Docker 
329
+storage driver. Launching *n* copies of the same container loads *n* copies of 
330
+its files into memory. This can have a memory impact on your Docker host. As a 
331
+result, the `devicemapper` storage driver may not be the best choice for PaaS 
332
+and other high density use cases.
333
+
334
+One final point, data volumes provide the best and most predictable 
335
+performance. This is because they bypass the storage driver and do not incur 
336
+any of the potential overheads introduced by thin provisioning and 
337
+copy-on-write. For this reason, you should to place heavy write workloads on 
338
+data volumes.
306 339
 
307 340
 ## Related Information
308 341
 
309 342
Binary files a/docs/userguide/storagedriver/images/aufs_layers.jpg and b/docs/userguide/storagedriver/images/aufs_layers.jpg differ
310 343
Binary files a/docs/userguide/storagedriver/images/btfs_constructs.jpg and b/docs/userguide/storagedriver/images/btfs_constructs.jpg differ
311 344
Binary files a/docs/userguide/storagedriver/images/btfs_container_layer.jpg and b/docs/userguide/storagedriver/images/btfs_container_layer.jpg differ
312 345
new file mode 100644
313 346
Binary files /dev/null and b/docs/userguide/storagedriver/images/container-layers-cas.jpg differ
314 347
new file mode 100644
315 348
Binary files /dev/null and b/docs/userguide/storagedriver/images/driver-pros-cons.png differ
316 349
Binary files a/docs/userguide/storagedriver/images/saving-space.jpg and b/docs/userguide/storagedriver/images/saving-space.jpg differ
317 350
Binary files a/docs/userguide/storagedriver/images/shared-uuid.jpg and b/docs/userguide/storagedriver/images/shared-uuid.jpg differ
... ...
@@ -13,25 +13,159 @@ weight = -2
13 13
 # Understand images, containers, and storage drivers
14 14
 
15 15
 To use storage drivers effectively, you must understand how Docker builds and
16
-stores images. Then, you need an understanding of how these images are used in  containers. Finally, you'll need a short introduction to the technologies that enable both images and container operations.
16
+stores images. Then, you need an understanding of how these images are used by 
17
+containers. Finally, you'll need a short introduction to the technologies that 
18
+enable both images and container operations.
17 19
 
18
-## Images and containers rely on layers
20
+## Images and layers
19 21
 
20
-Each Docker image references a list of read-only layers that represent filesystem differences. Layers are stacked on top of each other to form a base for a container's root filesystem. The diagram below shows the Ubuntu 15.04 image comprising 4 stacked image layers.
22
+Each Docker image references a list of read-only layers that represent 
23
+filesystem differences. Layers are stacked on top of each other to form a base 
24
+for a container's root filesystem. The diagram below shows the Ubuntu 15.04 
25
+image comprising 4 stacked image layers.
21 26
 
22 27
 ![](images/image-layers.jpg)
23 28
 
24
-When you make a change inside a container by, for example, adding a new file to a container created from Ubuntu 15.04 image, you add a new layer on top of the underlying stack. This change creates a new writable layer containing the newly added file on top of the image layers. Each image layer is stored by a cryptographic hash over its contents and multiple images can share the same layers. The diagram below shows a container running the Ubuntu 15.04 image.
29
+The Docker storage driver is responsible for stacking these layers and 
30
+providing a single unified view.
31
+ 
32
+When you create a new container, you add a new, thin, writable layer on top of 
33
+the underlying stack. This layer is often called the "container layer". All 
34
+changes made to the running container - such as writing new files, modifying 
35
+existing files, and deleting files - are written to this thin writable 
36
+container layer. The diagram below shows a container based on the Ubuntu 15.04 
37
+image.
25 38
 
26 39
 ![](images/container-layers.jpg)
27 40
 
28
-The major difference between a container and an image is this writable layer. All writes to the container that add new or modifying existing data are stored in this writable layer. When the container is deleted the writeable layer is also deleted. The image remains unchanged.
29
-
30
-Because each container has its own thin writable container layer and all data is stored this container layer, this means that multiple containers can share access to the same underlying image and yet have their own data state. The diagram below shows multiple containers sharing the same Ubuntu 15.04 image.
41
+### Content addressable storage
42
+
43
+Docker 1.10 introduced a new content addressable storage model. This is a 
44
+completely new way to address image and layer data on disk. Previously, image 
45
+and layer data was referenced and stored using a a randomly generated UUID. In 
46
+the new model this is replaced by a secure *content hash*.
47
+
48
+The new model improves security, provides a built-in way to avoid ID 
49
+collisions, and guarantees data integrity after pull, push, load, and save 
50
+operations. It also enables better sharing of layers by allowing many images to
51
+ freely share their layers even if they didn’t come from the same build.
52
+
53
+The diagram below shows an updated version of the previous diagram, 
54
+highlighting the changes implemented by Docker 1.10. 
55
+
56
+![](images/container-layers-cas.jpg)
57
+
58
+As can be seen, all image layer IDs are cryptographic hashes, whereas the 
59
+container ID is still a randomly generated UUID.
60
+
61
+There are several things to note regarding the new model. These include:
62
+
63
+1. Migration of existing images
64
+2. Image and layer filesystem structures
65
+
66
+Existing images, those created and pulled by earlier versions of Docker, need 
67
+to be migrated before they can be used with the new model. This migration 
68
+involves calculating new secure checksums and is performed automatically the 
69
+first time you start an updated Docker daemon. After the migration is complete,
70
+ all images and tags will have brand new secure IDs. 
71
+
72
+Although the migration is automatic and transparent, it is computationally 
73
+intensive. This means it and can take time if you have lots of image data. 
74
+During this time your Docker daemon will not respond to other requests.
75
+
76
+A migration tool exists that allows you to migrate existing images to the new 
77
+format before upgrading your Docker daemon. This means that upgraded Docker 
78
+daemons do not need to perform the migration in-band, and therefore avoids any 
79
+associated downtime. It also provides a way to manually migrate existing images
80
+ so that they can be distributed to other Docker daemons in your environment 
81
+that are already running the latest versions of Docker.
82
+
83
+The migration tool is provided by Docker, Inc., and runs as a container. You 
84
+can download it from [https://github.com/docker/v1.10-migrator/releases](https://github.com/docker/v1.10-migrator/releases).
85
+
86
+While running the "migrator" image you need to expose your Docker host's data 
87
+directory to the container. If you are using the default Docker data path, the 
88
+command to run the container will look like this 
89
+
90
+    $ sudo docker run --rm -v /var/lib/docker:/var/lib/docker docker/v1.10-migrator
91
+
92
+If you use the `devicemapper` storage driver, you will need to include the 
93
+`--privileged` option so that the container has access to your storage devices.
94
+
95
+#### Migration example
96
+
97
+The following example shows the migration tool in use on a Docker host running
98
+version 1.9.1 of the Docker daemon and the AUFS storage driver. The Docker host
99
+ is running on a **t2.micro** AWS EC2 instance with 1 vCPU, 1GB RAM, and a 
100
+single 8GB general purpose SSD EBS volume. The Docker data directory 
101
+(`/var/lib/docker`) was consuming 2GB of space.
102
+
103
+    $ docker images
104
+    REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
105
+    jenkins             latest              285c9f0f9d3d        17 hours ago        708.5 MB
106
+    mysql               latest              d39c3fa09ced        8 days ago          360.3 MB
107
+    mongo               latest              a74137af4532        13 days ago         317.4 MB
108
+    postgres            latest              9aae83d4127f        13 days ago         270.7 MB
109
+    redis               latest              8bccd73928d9        2 weeks ago         151.3 MB
110
+    centos              latest              c8a648134623        4 weeks ago         196.6 MB
111
+    ubuntu              15.04               c8be1ac8145a        7 weeks ago         131.3 MB
112
+    
113
+    $ du -hs /var/lib/docker
114
+    2.0G    /var/lib/docker
115
+    
116
+    $ time docker run --rm -v /var/lib/docker:/var/lib/docker docker/v1.10-migrator
117
+    Unable to find image 'docker/v1.10-migrator:latest' locally
118
+    latest: Pulling from docker/v1.10-migrator
119
+    ed1f33c5883d: Pull complete
120
+    b3ca410aa2c1: Pull complete
121
+    2b9c6ed9099e: Pull complete
122
+    dce7e318b173: Pull complete
123
+    Digest: sha256:bd2b245d5d22dd94ec4a8417a9b81bb5e90b171031c6e216484db3fe300c2097
124
+    Status: Downloaded newer image for docker/v1.10-migrator:latest
125
+    time="2016-01-27T12:31:06Z" level=debug msg="Assembling tar data for 01e70da302a553ba13485ad020a0d77dbb47575a31c4f48221137bb08f45878d from /var/lib/docker/aufs/diff/01e70da302a553ba13485ad020a0d77dbb47575a31c4f48221137bb08f45878d"
126
+    time="2016-01-27T12:31:06Z" level=debug msg="Assembling tar data for 07ac220aeeef9febf1ac16a9d1a4eff7ef3c8cbf5ed0be6b6f4c35952ed7920d from /var/lib/docker/aufs/diff/07ac220aeeef9febf1ac16a9d1a4eff7ef3c8cbf5ed0be6b6f4c35952ed7920d"
127
+    <snip>
128
+    time="2016-01-27T12:32:00Z" level=debug msg="layer dbacfa057b30b1feaf15937c28bd8ca0d6c634fc311ccc35bd8d56d017595d5b took 10.80 seconds"
129
+
130
+    real    0m59.583s
131
+    user    0m0.046s
132
+    sys     0m0.008s
133
+
134
+The Unix `time` command prepends the `docker run` command to produce timings 
135
+for the operation. As can be seen, the overall time taken to migrate 7 images 
136
+comprising 2GB of disk space took approximately 1 minute. However, this 
137
+included the time taken to pull the `docker/v1.10-migrator` image 
138
+(approximately 3.5 seconds). The same operation on an m4.10xlarge EC2 instance 
139
+with 40 vCPUs, 160GB RAM and an 8GB provisioned IOPS EBS volume resulted in the
140
+ following improved timings:
141
+
142
+    real    0m9.871s
143
+    user    0m0.094s
144
+    sys     0m0.021s
145
+
146
+This shows that the migration operation is affected by the hardware spec of the
147
+ machine performing the migration.
148
+
149
+## Container and layers
150
+
151
+The major difference between a container and an image is the top writable 
152
+layer. All writes to the container that add new or modify existing data are 
153
+stored in this writable layer. When the container is deleted the writable layer
154
+ is also deleted. The underlying image remains unchanged.
155
+
156
+Because each container has its own thin writable container layer, and all 
157
+changes are stored this container layer, this means that multiple containers 
158
+can share access to the same underlying image and yet have their own data 
159
+state. The diagram below shows multiple containers sharing the same Ubuntu 
160
+15.04 image.
31 161
 
32 162
 ![](images/sharing-layers.jpg)
33 163
 
34
-A storage driver is responsible for enabling and managing both the image layers and the writeable container layer. How a storage driver accomplishes these behaviors can vary. Two key technologies behind Docker image and container management are stackable image layers and copy-on-write (CoW).
164
+The Docker storage driver is responsible for enabling and managing both the 
165
+image layers and the writable container layer. How a storage driver 
166
+accomplishes these can vary between drivers. Two key technologies behind Docker
167
+ image and container management are stackable image layers and copy-on-write 
168
+(CoW).
35 169
 
36 170
 
37 171
 ## The copy-on-write strategy
... ...
@@ -40,24 +174,29 @@ Sharing is a good way to optimize resources. People do this instinctively in
40 40
 daily life. For example, twins Jane and Joseph taking an Algebra class at
41 41
 different times from different teachers can share the same exercise book by
42 42
 passing it between each other. Now, suppose Jane gets an assignment to complete
43
-the homework on page 11 in the book. At that point, Jane copies page 11, completes the homework, and hands in her copy. The original exercise book is unchanged and only Jane has a copy of the changed page 11.
43
+the homework on page 11 in the book. At that point, Jane copies page 11, 
44
+completes the homework, and hands in her copy. The original exercise book is 
45
+unchanged and only Jane has a copy of the changed page 11.
44 46
 
45 47
 Copy-on-write is a similar strategy of sharing and copying. In this strategy,
46 48
 system processes that need the same data share the same instance of that data
47
-rather than having their own copy. At some point, if one process needs to modify
48
-or write to the data, only then does the operating system make a copy of the
49
-data for that process to use. Only the process that needs to write has access to
50
-the data copy. All the other processes continue to use the original data.
49
+rather than having their own copy. At some point, if one process needs to 
50
+modify or write to the data, only then does the operating system make a copy of
51
+ the data for that process to use. Only the process that needs to write has 
52
+access to the data copy. All the other processes continue to use the original 
53
+data.
51 54
 
52
-Docker uses a copy-on-write technology with both images and containers. This CoW
53
-strategy optimizes both image disk space usage and the performance of container
54
-start times. The next sections look at how copy-on-write is leveraged with
55
-images and containers thru sharing and copying.
55
+Docker uses a copy-on-write technology with both images and containers. This 
56
+CoW strategy optimizes both image disk space usage and the performance of 
57
+container start times. The next sections look at how copy-on-write is leveraged
58
+ with images and containers through sharing and copying.
56 59
 
57 60
 ### Sharing promotes smaller images
58 61
 
59
-This section looks at image layers and copy-on-write technology.  All image and container layers exist inside the Docker host's *local storage area* and are managed by the storage driver. It is a location on the host's
60
-filesystem.
62
+This section looks at image layers and copy-on-write technology.  All image and
63
+ container layers exist inside the Docker host's *local storage area* and are 
64
+managed by the storage driver. On Linux-based Docker hosts this is usually 
65
+located under `/var/lib/docker/`.
61 66
 
62 67
 The Docker client reports on image layers when instructed to pull and push
63 68
 images with `docker pull` and `docker push`. The command below pulls the
... ...
@@ -65,38 +204,85 @@ images with `docker pull` and `docker push`. The command below pulls the
65 65
 
66 66
     $ docker pull ubuntu:15.04
67 67
     15.04: Pulling from library/ubuntu
68
-    6e6a100fa147: Pull complete
69
-    13c0c663a321: Pull complete
70
-    2bd276ed39d5: Pull complete
71
-    013f3d01d247: Pull complete
72
-    Digest: sha256:c7ecf33cef00ae34b131605c31486c91f5fd9a76315d075db2afd39d1ccdf3ed
68
+    1ba8ac955b97: Pull complete
69
+    f157c4e5ede7: Pull complete
70
+    0b7e98f84c4c: Pull complete
71
+    a3ed95caeb02: Pull complete
72
+    Digest: sha256:5e279a9df07990286cce22e1b0f5b0490629ca6d187698746ae5e28e604a640e
73 73
     Status: Downloaded newer image for ubuntu:15.04
74 74
 
75 75
 From the output, you'll see  that the command actually pulls 4 image layers.
76
-Each of the above lines lists an image layer and its UUID. The combination of
77
-these four layers makes up the `ubuntu:15.04` Docker image.
76
+Each of the above lines lists an image layer and its UUID or cryptographic 
77
+hash. The combination of these four layers makes up the `ubuntu:15.04` Docker 
78
+image.
79
+
80
+Each of these layers is stored in its own directory inside the Docker host's 
81
+local storage are. 
82
+
83
+Versions of Docker prior to 1.10 stored each layer in a directory with the same
84
+ name as the image layer ID. However, this is not the case for images pulled 
85
+with Docker version 1.10 and later. For example, the command below shows an 
86
+image being pulled from Docker Hub, followed by a directory listing on a host 
87
+running version 1.9.1 of the Docker Engine.
88
+
89
+    $  docker pull ubuntu:15.04
90
+    15.04: Pulling from library/ubuntu
91
+    47984b517ca9: Pull complete
92
+    df6e891a3ea9: Pull complete
93
+    e65155041eed: Pull complete
94
+    c8be1ac8145a: Pull complete
95
+    Digest: sha256:5e279a9df07990286cce22e1b0f5b0490629ca6d187698746ae5e28e604a640e
96
+    Status: Downloaded newer image for ubuntu:15.04
97
+
98
+    $ ls /var/lib/docker/aufs/layers
99
+    47984b517ca9ca0312aced5c9698753ffa964c2015f2a5f18e5efa9848cf30e2
100
+    c8be1ac8145a6e59a55667f573883749ad66eaeef92b4df17e5ea1260e2d7356
101
+    df6e891a3ea9cdce2a388a2cf1b1711629557454fd120abd5be6d32329a0e0ac
102
+    e65155041eed7ec58dea78d90286048055ca75d41ea893c7246e794389ecf203
78 103
 
79
-The image layers are stored in the Docker host's local storage area. Typically,
80
-the local storage area is in the host's `/var/lib/docker` directory. Depending
81
-on which storage driver the local storage area may be in a different location.  You can list the layers in the local storage area. The following example shows the storage as it appears under the AUFS storage driver:
104
+Notice how the four directories match up with the layer IDs of the downloaded 
105
+image. Now compare this with the same operations performed on a host running 
106
+version 1.10 of the Docker Engine.
82 107
 
83
-    $ sudo ls /var/lib/docker/aufs/layers
84
-    013f3d01d24738964bb7101fa83a926181d600ebecca7206dced59669e6e6778  2bd276ed39d5fcfd3d00ce0a190beeea508332f5aec3c6a125cc619a3fdbade6
85
-    13c0c663a321cd83a97f4ce1ecbaf17c2ba166527c3b06daaefe30695c5fcb8c  6e6a100fa147e6db53b684c8516e3e2588b160fd4898b6265545d5d4edb6796d
108
+    $ docker pull ubuntu:15.04
109
+    15.04: Pulling from library/ubuntu
110
+    1ba8ac955b97: Pull complete
111
+    f157c4e5ede7: Pull complete
112
+    0b7e98f84c4c: Pull complete
113
+    a3ed95caeb02: Pull complete
114
+    Digest: sha256:5e279a9df07990286cce22e1b0f5b0490629ca6d187698746ae5e28e604a640e
115
+    Status: Downloaded newer image for ubuntu:15.04
86 116
 
87
-If you `pull` another image that shares some of the same image layers as the `ubuntu:15.04` image, the Docker daemon recognize this, and only pull the layers it hasn't already stored. After the second pull, the two images will share any common image layers.
117
+    $ ls /var/lib/docker/aufs/layers/
118
+    1d6674ff835b10f76e354806e16b950f91a191d3b471236609ab13a930275e24
119
+    5dbb0cbe0148cf447b9464a358c1587be586058d9a4c9ce079320265e2bb94e7
120
+    bef7199f2ed8e86fa4ada1309cfad3089e0542fec8894690529e4c04a7ca2d73
121
+    ebf814eccfe98f2704660ca1d844e4348db3b5ccc637eb905d4818fbfb00a06a
88 122
 
89
-You can illustrate this now for yourself. Starting the `ubuntu:15.04` image that
90
-you just pulled, make a change to it, and build a new image based on the change.
91
-One way to do this is using a Dockerfile and the `docker build` command.
123
+See how the four directories do not match up with the image layer IDs pulled in
124
+ the previous step.
92 125
 
93
-1. In an empty directory, create a simple `Dockerfile` that starts with the ubuntu:15.04 image.
126
+Despite the differences between image management before and after version 1.10,
127
+all versions of Docker still allow images to share layers. For example, If you 
128
+`pull` an image that shares some of the same image layers as an image that has 
129
+already been pulled, the Docker daemon recognizes this, and only pulls the 
130
+layers it doesn't already have stored locally. After the second pull, the two 
131
+images will share any common image layers.
132
+
133
+You can illustrate this now for yourself. Starting with the `ubuntu:15.04` 
134
+image that you just pulled, make a change to it, and build a new image based on
135
+ the change. One way to do this is using a `Dockerfile` and the `docker build` 
136
+command.
137
+
138
+1. In an empty directory, create a simple `Dockerfile` that starts with the 
139
+2. ubuntu:15.04 image.
94 140
 
95 141
         FROM ubuntu:15.04
96 142
 
97
-2. Add a new file called "newfile" in the image's `/tmp` directory with the text "Hello world" in it.
143
+2. Add a new file called "newfile" in the image's `/tmp` directory with the 
144
+3. text "Hello world" in it.
98 145
 
99
-  When you are done, the `Dockerfile` contains two lines:
146
+    When you are done, the `Dockerfile` contains two lines:
100 147
 
101 148
         FROM ubuntu:15.04
102 149
 
... ...
@@ -104,78 +290,125 @@ One way to do this is using a Dockerfile and the `docker build` command.
104 104
 
105 105
 3. Save and close the file.
106 106
 
107
-2. From a terminal in the same folder as your Dockerfile, run the following command:
107
+4. From a terminal in the same folder as your `Dockerfile`, run the following 
108
+5. command:
108 109
 
109 110
         $ docker build -t changed-ubuntu .
110 111
         Sending build context to Docker daemon 2.048 kB
111
-        Step 0 : FROM ubuntu:15.04
112
-         ---> 013f3d01d247
113
-        Step 1 : RUN echo "Hello world" > /tmp/newfile
114
-         ---> Running in 2023460815df
115
-         ---> 03b964f68d06
116
-        Removing intermediate container 2023460815df
117
-        Successfully built 03b964f68d06
112
+        Step 1 : FROM ubuntu:15.04
113
+         ---> 3f7bcee56709
114
+        Step 2 : RUN echo "Hello world" > /tmp/newfile
115
+         ---> Running in d14acd6fad4e
116
+         ---> 94e6b7d2c720
117
+        Removing intermediate container d14acd6fad4e
118
+        Successfully built 94e6b7d2c720
118 119
 
119
-    > **Note:** The period (.) at the end of the above command is important. It tells the `docker build` command to use the current working directory as its build context.
120
+    > **Note:** The period (.) at the end of the above command is important. It
121
+    >  tells the `docker build` command to use the current working directory as
122
+    >   its build context.
120 123
 
121
-    The output above shows a new image with image ID `03b964f68d06`.
124
+    The output above shows a new image with image ID `94e6b7d2c720`.
122 125
 
123
-3. Run the `docker images` command to verify the new image is in the Docker host's local storage area.
126
+5. Run the `docker images` command to verify the new `changed-ubuntu` image is 
127
+6. in the Docker host's local storage area.
124 128
 
125
-        REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
126
-        changed-ubuntu      latest              03b964f68d06        33 seconds ago      131.4 MB
127
-        ubuntu  
129
+        REPOSITORY       TAG      IMAGE ID       CREATED           VIRTUAL SIZE
130
+        changed-ubuntu   latest   03b964f68d06   33 seconds ago    131.4 MB
131
+        ubuntu           15.04    013f3d01d247   6 weeks ago       131.3 MB
128 132
 
129
-4. Run the `docker history` command to see which image layers were used to create the new `changed-ubuntu` image.
133
+6. Run the `docker history` command to see which image layers were used to 
134
+7. create the new `changed-ubuntu` image.
130 135
 
131 136
         $ docker history changed-ubuntu
132
-        IMAGE               CREATED              CREATED BY                                      SIZE                COMMENT
133
-        03b964f68d06        About a minute ago   /bin/sh -c echo "Hello world" > /tmp/newfile    12 B                
134
-        013f3d01d247        6 weeks ago          /bin/sh -c #(nop) CMD ["/bin/bash"]             0 B                 
135
-        <missing>           6 weeks ago          /bin/sh -c sed -i 's/^#\s*\(deb.*universe\)$/   1.879 kB            
136
-        <missing>           6 weeks ago          /bin/sh -c echo '#!/bin/sh' > /usr/sbin/polic   701 B               
137
-        <missing>           6 weeks ago          /bin/sh -c #(nop) ADD file:49710b44e2ae0edef4   131.4 MB            
138
-
139
-    The `docker history` output shows the new `03b964f68d06` image layer at the
140
-    top. You know that the `03b964f68d06` layer was added because it was created
141
-    by the `echo "Hello world" > /tmp/newfile` command in your `Dockerfile`.
142
-    The 4 image layers below it are the exact same image layers the make up the
143
-    ubuntu:15.04 image as their UUIDs match.
144
-
145
-Notice the new `changed-ubuntu` image does not have its own copies of every layer. As can be seen in the diagram below, the new image is sharing it's four underlying layers with the `ubuntu:15.04` image.
137
+        IMAGE               CREATED              CREATED BY                                      SIZE        COMMENT
138
+        94e6b7d2c720        2 minutes ago       /bin/sh -c echo "Hello world" > /tmp/newfile    12 B 
139
+        3f7bcee56709        6 weeks ago         /bin/sh -c #(nop) CMD ["/bin/bash"]             0 B  
140
+        <missing>           6 weeks ago         /bin/sh -c sed -i 's/^#\s*\(deb.*universe\)$/   1.879 kB
141
+        <missing>           6 weeks ago         /bin/sh -c echo '#!/bin/sh' > /usr/sbin/polic   701 B
142
+        <missing>           6 weeks ago         /bin/sh -c #(nop) ADD file:8e4943cd86e9b2ca13   131.3 MB
143
+
144
+    The `docker history` output shows the new `94e6b7d2c720` image layer at the
145
+    top. You know that this is the new image layer added because it was created
146
+     by the `echo "Hello world" > /tmp/newfile` command in your `Dockerfile`. 
147
+    The 4 image layers below it are the exact same image layers 
148
+    that make up the `ubuntu:15.04` image.
149
+
150
+> **Note:** Under the content addressable storage model introduced with Docker 
151
+> 1.10, image history data is no longer stored in a config file with each image
152
+> layer. It is now stored as a string of text in a single config file that 
153
+> relates to the overall image. This can result in some image layers showing as
154
+>  "missing" in the output of the `docker history` command. This is normal 
155
+>  behaviour and can be ignored.
156
+>
157
+> You may hear images like these referred to as *flat images*.
158
+
159
+Notice the new `changed-ubuntu` image does not have its own copies of every 
160
+layer. As can be seen in the diagram below, the new image is sharing its four 
161
+underlying layers with the `ubuntu:15.04` image.
146 162
 
147 163
 ![](images/saving-space.jpg)
148 164
 
149
-The `docker history` command also shows the size of each image layer. The `03b964f68d06` is only consuming 13 Bytes of disk space. Because all of the layers below it already exist on the Docker host and are shared with the `ubuntu15:04` image, this means the entire `changed-ubuntu` image only consumes 13 Bytes of disk space.
165
+The `docker history` command also shows the size of each image layer. As you 
166
+can see, the `94e6b7d2c720` layer is only consuming 12 Bytes of disk space. 
167
+This means that the `changed-ubuntu` image we just created is only consuming an
168
+ additional 12 Bytes of disk space on the Docker host - all layers below the 
169
+`94e6b7d2c720` layer already exist on the Docker host and are shared by other 
170
+images.
150 171
 
151
-This sharing of image layers is what makes Docker images and containers so space
152
-efficient.
172
+This sharing of image layers is what makes Docker images and containers so 
173
+space efficient.
153 174
 
154 175
 ### Copying makes containers efficient
155 176
 
156
-You learned earlier that a container a Docker image with a thin writable, container layer added. The diagram below shows the layers of a container based on the `ubuntu:15.04` image:
177
+You learned earlier that a container is a Docker image with a thin writable, 
178
+container layer added. The diagram below shows the layers of a container based 
179
+on the `ubuntu:15.04` image:
157 180
 
158
-![](images/container-layers.jpg)
181
+![](images/container-layers-cas.jpg)
159 182
 
160
-All writes made to a container are stored in the thin writable container layer. The other layers are read-only (RO) image layers and can't be changed. This means that multiple containers can safely share a single underlying image. The diagram below shows multiple containers sharing a single copy of the `ubuntu:15.04` image. Each container has its own thin RW layer, but they all share a single instance of the ubuntu:15.04 image:
183
+All writes made to a container are stored in the thin writable container layer.
184
+ The other layers are read-only (RO) image layers and can't be changed. This 
185
+means that multiple containers can safely share a single underlying image. The 
186
+diagram below shows multiple containers sharing a single copy of the 
187
+`ubuntu:15.04` image. Each container has its own thin RW layer, but they all 
188
+share a single instance of the ubuntu:15.04 image:
161 189
 
162 190
 ![](images/sharing-layers.jpg)
163 191
 
164
-When a write operation occurs in a container, Docker uses the storage driver to perform a copy-on-write operation. The type of operation depends on the storage driver. For AUFS and OverlayFS storage drivers the copy-on-write operation is pretty much as follows:
192
+When an existing file in a container is modified, Docker uses the storage 
193
+driver to perform a copy-on-write operation. The specifics of operation depends
194
+ on the storage driver. For the AUFS and OverlayFS storage drivers, the 
195
+copy-on-write operation is pretty much as follows:
165 196
 
166
-*  Search through the layers for the file to update. The process starts at the top, newest layer and works down to the base layer one-at-a-time.
167
-*  Perform a "copy-up" operation on the first copy of the file that is found. A "copy up" copies the file up to the container's own thin writable layer.
197
+*  Search through the image layers for the file to update. The process starts 
198
+at the top, newest layer and works down to the base layer one layer at a 
199
+time.
200
+*  Perform a "copy-up" operation on the first copy of the file that is found. A
201
+ "copy up" copies the file up to the container's own thin writable layer.
168 202
 * Modify the *copy of the file* in container's thin writable layer.
169 203
 
170
-BTFS, ZFS, and other drivers handle the copy-on-write differently. You can read more about the methods of these drivers later in their detailed descriptions.
204
+Btrfs, ZFS, and other drivers handle the copy-on-write differently. You can 
205
+read more about the methods of these drivers later in their detailed 
206
+descriptions.
171 207
 
172
-Containers that write a lot of data will consume more space than containers that do not. This is because most write operations consume new space in the containers thin writable top layer. If your container needs to write a lot of data, you can use a data volume.
208
+Containers that write a lot of data will consume more space than containers 
209
+that do not. This is because most write operations consume new space in the 
210
+container's thin writable top layer. If your container needs to write a lot of 
211
+data, you should consider using a data volume.
173 212
 
174
-A copy-up operation can incur a noticeable performance overhead. This overhead is different depending on which storage driver is in use. However, large files, lots of layers, and deep directory trees can make the impact more noticeable. Fortunately, the operation only occurs the first time any particular file is modified. Subsequent modifications to the same file do not cause a copy-up operation and can operate directly on the file's existing copy already present in container layer.
213
+A copy-up operation can incur a noticeable performance overhead. This overhead 
214
+is different depending on which storage driver is in use. However, large files,
215
+ lots of layers, and deep directory trees can make the impact more noticeable. 
216
+Fortunately, the operation only occurs the first time any particular file is 
217
+modified. Subsequent modifications to the same file do not cause a copy-up 
218
+operation and can operate directly on the file's existing copy already present 
219
+in the container layer.
175 220
 
176
-Let's see what happens if we spin up 5 containers based on our `changed-ubuntu` image we built earlier:
221
+Let's see what happens if we spin up 5 containers based on our `changed-ubuntu`
222
+ image we built earlier:
177 223
 
178
-1. From a terminal on your Docker host, run the following `docker run` command 5 times.
224
+1. From a terminal on your Docker host, run the following `docker run` command 
225
+5 times.
179 226
 
180 227
         $ docker run -dit changed-ubuntu bash
181 228
         75bab0d54f3cf193cfdc3a86483466363f442fba30859f7dcd1b816b6ede82d4
... ...
@@ -188,28 +421,38 @@ Let's see what happens if we spin up 5 containers based on our `changed-ubuntu`
188 188
         $ docker run -dit changed-ubuntu bash
189 189
         0ad25d06bdf6fca0dedc38301b2aff7478b3e1ce3d1acd676573bba57cb1cfef
190 190
 
191
-  This launches 5 containers based on the `changed-ubuntu` image.  As the container is created, Docker adds a writable layer and assigns it a UUID. This is the value returned from the `docker run` command.
191
+    This launches 5 containers based on the `changed-ubuntu` image.  As each 
192
+container is created, Docker adds a writable layer and assigns it a random 
193
+UUID. This is the value returned from the `docker run` command.
192 194
 
193 195
 2. Run the `docker ps` command to verify the 5 containers are running.
194 196
 
195 197
         $ docker ps
196
-        CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS               NAMES
197
-        0ad25d06bdf6        changed-ubuntu      "bash"              About a minute ago   Up About a minute                       stoic_ptolemy
198
-        8eb24b3b2d24        changed-ubuntu      "bash"              About a minute ago   Up About a minute                       pensive_bartik
199
-        a651680bd6c2        changed-ubuntu      "bash"              2 minutes ago        Up 2 minutes                            hopeful_turing
200
-        9280e777d109        changed-ubuntu      "bash"              2 minutes ago        Up 2 minutes                            backstabbing_mahavira
201
-        75bab0d54f3c        changed-ubuntu      "bash"              2 minutes ago        Up 2 minutes                            boring_pasteur
198
+        CONTAINER ID    IMAGE             COMMAND    CREATED              STATUS              PORTS    NAMES
199
+        0ad25d06bdf6    changed-ubuntu    "bash"     About a minute ago   Up About a minute            stoic_ptolemy
200
+        8eb24b3b2d24    changed-ubuntu    "bash"     About a minute ago   Up About a minute            pensive_bartik
201
+        a651680bd6c2    changed-ubuntu    "bash"     2 minutes ago        Up 2 minutes                 hopeful_turing
202
+        9280e777d109    changed-ubuntu    "bash"     2 minutes ago        Up 2 minutes                 backstabbing_mahavira
203
+        75bab0d54f3c    changed-ubuntu    "bash"     2 minutes ago        Up 2 minutes                 boring_pasteur
202 204
 
203
-    The output above shows 5 running containers, all sharing the `changed-ubuntu` image. Each `CONTAINER ID` is derived from the UUID when creating each container.
205
+    The output above shows 5 running containers, all sharing the 
206
+`changed-ubuntu` image. Each `CONTAINER ID` is derived from the UUID when 
207
+creating each container.
204 208
 
205 209
 3. List the contents of the local storage area.
206 210
 
207
-        $ sudo ls containers
208
-        0ad25d06bdf6fca0dedc38301b2aff7478b3e1ce3d1acd676573bba57cb1cfef  9280e777d109e2eb4b13ab211553516124a3d4d4280a0edfc7abf75c59024d47
209
-        75bab0d54f3cf193cfdc3a86483466363f442fba30859f7dcd1b816b6ede82d4  a651680bd6c2ef64902e154eeb8a064b85c9abf08ac46f922ad8dfc11bb5cd8a
211
+        $ sudo ls /var/lib/docker/containers
212
+        0ad25d06bdf6fca0dedc38301b2aff7478b3e1ce3d1acd676573bba57cb1cfef
213
+        9280e777d109e2eb4b13ab211553516124a3d4d4280a0edfc7abf75c59024d47
214
+        75bab0d54f3cf193cfdc3a86483466363f442fba30859f7dcd1b816b6ede82d4
215
+        a651680bd6c2ef64902e154eeb8a064b85c9abf08ac46f922ad8dfc11bb5cd8a
210 216
         8eb24b3b2d246f225b24f2fca39625aaad71689c392a7b552b78baf264647373
211 217
 
212
-Docker's copy-on-write strategy not only reduces the amount of space consumed by containers, it also reduces the time required to start a container. At start time, Docker only has to create the thin writable layer for each container. The diagram below shows these 5 containers sharing a single read-only (RO) copy of the `changed-ubuntu` image.
218
+Docker's copy-on-write strategy not only reduces the amount of space consumed 
219
+by containers, it also reduces the time required to start a container. At start
220
+ time, Docker only has to create the thin writable layer for each container. 
221
+The diagram below shows these 5 containers sharing a single read-only (RO) 
222
+copy of the `changed-ubuntu` image.
213 223
 
214 224
 ![](images/shared-uuid.jpg)
215 225
 
... ...
@@ -219,18 +462,30 @@ significantly increased.
219 219
 
220 220
 ## Data volumes and the storage driver
221 221
 
222
-When a container is deleted, any data written to the container that is not stored in a *data volume* is deleted along with the container. A data volume is directory or file that is mounted directly into a container.
222
+When a container is deleted, any data written to the container that is not 
223
+stored in a *data volume* is deleted along with the container. 
223 224
 
224
-Data volumes are not controlled by the storage driver. Reads and writes to data
225
-volumes bypass the storage driver and operate at native host speeds. You can mount any number of data volumes into a container. Multiple containers can also share one or more data volumes.
225
+A data volume is a directory or file in the Docker host's filesystem that is 
226
+mounted directly into a container. Data volumes are not controlled by the 
227
+storage driver. Reads and writes to data volumes bypass the storage driver and 
228
+operate at native host speeds. You can mount any number of data volumes into a 
229
+container. Multiple containers can also share one or more data volumes.
226 230
 
227
-The diagram below shows a single Docker host running two containers. Each container exists inside of its own address space within the Docker host's local storage area. There is also a single shared data volume located at `/data` on the Docker host. This is mounted directly into both containers.
231
+The diagram below shows a single Docker host running two containers. Each 
232
+container exists inside of its own address space within the Docker host's local
233
+ storage area (`/var/lib/docker/...`). There is also a single shared data 
234
+volume located at `/data` on the Docker host. This is mounted directly into 
235
+both containers.
228 236
 
229 237
 ![](images/shared-volume.jpg)
230 238
 
231
-The data volume resides outside of the local storage area on the Docker host further reinforcing its independence from the storage driver's control. When a container is deleted, any data stored in shared data volumes persists on the Docker host.
239
+Data volumes reside outside of the local storage area on the Docker host, 
240
+further reinforcing their independence from the storage driver's control. When 
241
+a container is deleted, any data stored in data volumes persists on the Docker 
242
+host.
232 243
 
233
-For detailed information about data volumes [Managing data in containers](https://docs.docker.com/userguide/dockervolumes/).
244
+For detailed information about data volumes 
245
+[Managing data in containers](https://docs.docker.com/userguide/dockervolumes/).
234 246
 
235 247
 ## Related information
236 248
 
... ...
@@ -10,47 +10,83 @@ parent = "engine_driver"
10 10
 
11 11
 # Docker and OverlayFS in practice
12 12
 
13
-OverlayFS is a modern *union filesystem* that is similar to AUFS. In comparison to AUFS, OverlayFS:
13
+OverlayFS is a modern *union filesystem* that is similar to AUFS. In comparison
14
+ to AUFS, OverlayFS:
14 15
 
15 16
 * has a simpler design
16 17
 * has been in the mainline Linux kernel since version 3.18
17 18
 * is potentially faster
18 19
 
19
-As a result, OverlayFS is rapidly gaining popularity in the Docker community and is seen by many as a natural successor to AUFS. As promising as OverlayFS is, it is still relatively young. Therefore caution should be taken before using it in production Docker environments.
20
+As a result, OverlayFS is rapidly gaining popularity in the Docker community 
21
+and is seen by many as a natural successor to AUFS. As promising as OverlayFS 
22
+is, it is still relatively young. Therefore caution should be taken before 
23
+using it in production Docker environments.
20 24
 
21
-Docker's `overlay` storage driver leverages several OverlayFS features to build and manage the on-disk structures of images and containers.
22
-
23
->**Note**: Since it was merged into the mainline kernel, the OverlayFS *kernel module* was renamed from "overlayfs" to "overlay". As a result you may see the two terms used interchangeably in some documentation. However, this document uses  "OverlayFS" to refer to the overall filesystem, and `overlay` to refer to Docker's storage-driver.
25
+Docker's `overlay` storage driver leverages several OverlayFS features to build
26
+ and manage the on-disk structures of images and containers.
24 27
 
28
+>**Note**: Since it was merged into the mainline kernel, the OverlayFS *kernel 
29
+>module* was renamed from "overlayfs" to "overlay". As a result you may see the
30
+> two terms used interchangeably in some documentation. However, this document 
31
+> uses  "OverlayFS" to refer to the overall filesystem, and `overlay` to refer 
32
+> to Docker's storage-driver.
25 33
 
26 34
 ## Image layering and sharing with OverlayFS
27 35
 
28
-OverlayFS takes two directories on a single Linux host, layers one on top of the other, and provides a single unified view. These directories are often referred to as *layers* and the technology used to layer them is known as a *union mount*. The OverlayFS terminology is "lowerdir" for the bottom layer and "upperdir" for the top layer. The unified view is exposed through its own directory called "merged".
36
+OverlayFS takes two directories on a single Linux host, layers one on top of 
37
+the other, and provides a single unified view. These directories are often 
38
+referred to as *layers* and the technology used to layer them is known as a 
39
+*union mount*. The OverlayFS terminology is "lowerdir" for the bottom layer and
40
+ "upperdir" for the top layer. The unified view is exposed through its own 
41
+directory called "merged".
29 42
 
30
-The diagram below shows how a Docker image and a Docker container are layered. The image layer is the "lowerdir" and the container layer is the "upperdir". The unified view is exposed through a directory called "merged" which is effectively the containers mount point. The diagram shows how Docker constructs map to OverlayFS constructs.
43
+The diagram below shows how a Docker image and a Docker container are layered. 
44
+The image layer is the "lowerdir" and the container layer is the "upperdir". 
45
+The unified view is exposed through a directory called "merged" which is 
46
+effectively the containers mount point. The diagram shows how Docker constructs
47
+ map to OverlayFS constructs.
31 48
 
32 49
 ![](images/overlay_constructs.jpg)
33 50
 
34
-Notice how the image layer and container layer can contain the same files. When this happens, the files in the container layer ("upperdir") are dominant and obscure the existence of the same files in the image layer ("lowerdir"). The container mount ("merged") presents the unified view.
35
-
36
-OverlayFS only works with two layers. This means that multi-layered images cannot be implemented as multiple OverlayFS layers. Instead, each image layer is implemented as its own directory under `/var/lib/docker/overlay`. Hard links are then used as a space-efficient way to reference data shared with lower layers. The diagram below shows a four-layer image and how it is represented in the Docker host's filesystem.
51
+Notice how the image layer and container layer can contain the same files. When
52
+ this happens, the files in the container layer ("upperdir") are dominant and 
53
+obscure the existence of the same files in the image layer ("lowerdir"). The 
54
+container mount ("merged") presents the unified view.
37 55
 
38
-![](images/overlay_constructs2.jpg)
56
+OverlayFS only works with two layers. This means that multi-layered images 
57
+cannot be implemented as multiple OverlayFS layers. Instead, each image layer 
58
+is implemented as its own directory under `/var/lib/docker/overlay`. 
59
+Hard links are then used as a space-efficient way to reference data shared with
60
+ lower layers. As of Docker 1.10, image layer IDs no longer correspond to 
61
+directory names in `/var/lib/docker/`
39 62
 
40
-To create a container, the `overlay` driver combines the directory representing the image's top layer plus a new directory for the container. The image's top layer is the "lowerdir" in the overlay and read-only. The new directory for the container is the "upperdir" and is writable.
63
+To create a container, the `overlay` driver combines the directory representing
64
+ the image's top layer plus a new directory for the container. The image's top 
65
+layer is the "lowerdir" in the overlay and read-only. The new directory for the
66
+ container is the "upperdir" and is writable.
41 67
 
42 68
 ## Example: Image and container on-disk constructs
43 69
 
44
-The following `docker images -a` command shows a Docker host with a single image. As can be seen, the image consists of four layers.
70
+The following `docker pull` command shows a Docker host with downloading a 
71
+Docker image comprising four layers.
72
+
73
+    $ sudo docker pull ubuntu
74
+    Using default tag: latest
75
+    latest: Pulling from library/ubuntu
76
+    8387d9ff0016: Pull complete
77
+    3b52deaaf0ed: Pull complete
78
+    4bd501fad6de: Pull complete
79
+    a3ed95caeb02: Pull complete
80
+    Digest: sha256:457b05828bdb5dcc044d93d042863fba3f2158ae249a6db5ae3934307c757c54
81
+    Status: Downloaded newer image for ubuntu:latest
45 82
 
46
-    $ docker images -a
47
-    REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
48
-    ubuntu              latest              1d073211c498        7 days ago          187.9 MB
49
-    <none>              <none>              5a4526e952f0        7 days ago          187.9 MB
50
-    <none>              <none>              99fcaefe76ef        7 days ago          187.9 MB
51
-    <none>              <none>              c63fb41c2213        7 days ago          187.7 MB
83
+Each image layer has it's own directory under `/var/lib/docker/overlay/`. This 
84
+is where the the contents of each image layer are stored. 
52 85
 
53
-Below, the command's output illustrates that each of the four image layers has it's own directory under `/var/lib/docker/overlay/`.
86
+The output of the command below shows the four directories that store the 
87
+contents of each image layer just pulled. However, as can be seen, the image 
88
+layer IDs do not match the directory names in `/var/lib/docker/overlay`. This 
89
+is normal behavior in Docker 1.10 and later.
54 90
 
55 91
     $ ls -l /var/lib/docker/overlay/
56 92
     total 24
... ...
@@ -59,35 +95,42 @@ Below, the command's output illustrates that each of the four image layers has i
59 59
     drwx------ 5 root root 4096 Oct 28 11:06 99fcaefe76ef1aa4077b90a413af57fd17d19dce4e50d7964a273aae67055235
60 60
     drwx------ 3 root root 4096 Oct 28 11:01 c63fb41c2213f511f12f294dd729b9903a64d88f098c20d2350905ac1fdbcbba
61 61
 
62
-Each directory is named after the image layer IDs in the previous `docker images -a` command. The image layer directories contain the files unique to that layer as well as hard links to the data that is shared with lower layers. This allows for efficient use of disk space.
62
+The image layer directories contain the files unique to that layer as well as 
63
+hard links to the data that is shared with lower layers. This allows for 
64
+efficient use of disk space.
63 65
 
64
-The following `docker ps` command shows the same Docker host running a single container. The container ID is "73de7176c223".
66
+Containers also exist on-disk in the Docker host's filesystem under 
67
+`/var/lib/docker/overlay/`. If you inspect the directory relating to a running 
68
+container using the `ls -l` command, you find the following file and 
69
+directories.
65 70
 
66
-    $ docker ps
67
-    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
68
-    73de7176c223        ubuntu              "bash"              2 days ago          Up 2 days                               stupefied_nobel
69
-
70
-This container exists on-disk in the Docker host's filesystem under `/var/lib/docker/overlay/73de7176c223...`.  If you inspect this directory using the `ls -l` command you find the following file and directories.
71
-
72
-    $ ls -l /var/lib/docker/overlay/73de7176c223a6c82fd46c48c5f152f2c8a7e49ecb795a7197c3bb795c4d879e
71
+    $ ls -l /var/lib/docker/overlay/<directory-of-running-container>
73 72
     total 16
74 73
     -rw-r--r-- 1 root root   64 Oct 28 11:06 lower-id
75 74
     drwxr-xr-x 1 root root 4096 Oct 28 11:06 merged
76 75
     drwxr-xr-x 4 root root 4096 Oct 28 11:06 upper
77 76
     drwx------ 3 root root 4096 Oct 28 11:06 work
78 77
 
79
-These four filesystem objects are all artifacts of OverlayFS. The "lower-id" file contains the ID of the top layer of the image the container is based on. This is used by OverlayFS as the "lowerdir".
78
+These four filesystem objects are all artefacts of OverlayFS. The "lower-id" 
79
+file contains the ID of the top layer of the image the container is based on. 
80
+This is used by OverlayFS as the "lowerdir".
80 81
 
81 82
     $ cat /var/lib/docker/overlay/73de7176c223a6c82fd46c48c5f152f2c8a7e49ecb795a7197c3bb795c4d879e/lower-id
82 83
     1d073211c498fd5022699b46a936b4e4bdacb04f637ad64d3475f558783f5c3e
83 84
 
84
-The "upper" directory is the containers read-write layer. Any changes made to the container are written to this directory.
85
+The "upper" directory is the containers read-write layer. Any changes made to 
86
+the container are written to this directory.
85 87
 
86
-The "merged" directory is effectively the containers mount point. This is where the unified view of the image ("lowerdir") and container ("upperdir") is exposed. Any changes written to the container are immediately reflected in this directory.
88
+The "merged" directory is effectively the containers mount point. This is where
89
+ the unified view of the image ("lowerdir") and container ("upperdir") is 
90
+exposed. Any changes written to the container are immediately reflected in this
91
+ directory.
87 92
 
88
-The "work" directory is required for OverlayFS to function. It is used for things such as *copy_up* operations.
93
+The "work" directory is required for OverlayFS to function. It is used for 
94
+things such as *copy_up* operations.
89 95
 
90
-You can verify all of these constructs from the output of the `mount` command. (Ellipses and line breaks are used in the output below to enhance readability.)
96
+You can verify all of these constructs from the output of the `mount` command. 
97
+(Ellipses and line breaks are used in the output below to enhance readability.)
91 98
 
92 99
     $ mount | grep overlay
93 100
     overlay on /var/lib/docker/overlay/73de7176c223.../merged
... ...
@@ -95,39 +138,73 @@ You can verify all of these constructs from the output of the `mount` command. (
95 95
     upperdir=/var/lib/docker/overlay/73de7176c223.../upper,
96 96
     workdir=/var/lib/docker/overlay/73de7176c223.../work)
97 97
 
98
-The output reflects the overlay is mounted as read-write ("rw").
98
+The output reflects that the overlay is mounted as read-write ("rw").
99 99
 
100 100
 ## Container reads and writes with overlay
101 101
 
102
-Consider three scenarios where a container opens a file for read access with overlay.
102
+Consider three scenarios where a container opens a file for read access with 
103
+overlay.
103 104
 
104
-- **The file does not exist in the container layer**. If a container opens a file for read access and the file does not already exist in the container ("upperdir") it is read from the image ("lowerdir"). This should incur very little performance overhead.
105
+- **The file does not exist in the container layer**. If a container opens a 
106
+file for read access and the file does not already exist in the container 
107
+("upperdir") it is read from the image ("lowerdir"). This should incur very 
108
+little performance overhead.
105 109
 
106
-- **The file only exists in the container layer**. If a container opens a file for read access and the file exists in the container ("upperdir") and not in the image ("lowerdir"), it is read directly from the container.
110
+- **The file only exists in the container layer**. If a container opens a file 
111
+for read access and the file exists in the container ("upperdir") and not in 
112
+the image ("lowerdir"), it is read directly from the container.
107 113
 
108
-- **The file exists in the container layer and the image layer**. If a container opens a file for read access and the file exists in the image layer and the container layer, the file's version in the container layer is read. This is because files in the container layer ("upperdir") obscure files with the same name in the image layer ("lowerdir").
114
+- **The file exists in the container layer and the image layer**. If a 
115
+container opens a file for read access and the file exists in the image layer 
116
+and the container layer, the file's version in the container layer is read. 
117
+This is because files in the container layer ("upperdir") obscure files with 
118
+the same name in the image layer ("lowerdir").
109 119
 
110 120
 Consider some scenarios where files in a container are modified.
111 121
 
112
-- **Writing to a file for the first time**. The first time a container writes to an existing file, that file does not exist in the container ("upperdir"). The `overlay` driver performs a *copy_up* operation to copy the file from the image ("lowerdir") to the container ("upperdir"). The container then writes the changes to the new copy of the file in the container layer.
122
+- **Writing to a file for the first time**. The first time a container writes 
123
+to an existing file, that file does not exist in the container ("upperdir"). 
124
+The `overlay` driver performs a *copy_up* operation to copy the file from the 
125
+image ("lowerdir") to the container ("upperdir"). The container then writes the
126
+ changes to the new copy of the file in the container layer.
113 127
 
114
-    However, OverlayFS works at the file level not the block level. This means that all OverlayFS copy-up operations copy entire files, even if the file is very large and only a small part of it is being modified. This can have a noticeable impact on container write performance. However, two things are worth noting:
128
+    However, OverlayFS works at the file level not the block level. This means 
129
+that all OverlayFS copy-up operations copy entire files, even if the file is 
130
+very large and only a small part of it is being modified. This can have a 
131
+noticeable impact on container write performance. However, two things are 
132
+worth noting:
115 133
 
116
-    * The copy_up operation only occurs the first time any given file is written to. Subsequent writes to the same file will operate against the copy of the file already copied up to the container.
134
+    * The copy_up operation only occurs the first time any given file is 
135
+written to. Subsequent writes to the same file will operate against the copy of
136
+ the file already copied up to the container.
117 137
 
118
-    * OverlayFS only works with two layers. This means that performance should be better than AUFS which can suffer noticeable latencies when searching for files in images with many layers.
138
+    * OverlayFS only works with two layers. This means that performance should 
139
+be better than AUFS which can suffer noticeable latencies when searching for 
140
+files in images with many layers.
119 141
 
120
-- **Deleting files and directories**. When files are deleted within a container a *whiteout* file is created in the containers "upperdir". The version of the file in the image layer ("lowerdir") is not deleted. However, the whiteout file in the container obscures it.
142
+- **Deleting files and directories**. When files are deleted within a container
143
+ a *whiteout* file is created in the containers "upperdir". The version of the 
144
+file in the image layer ("lowerdir") is not deleted. However, the whiteout file
145
+ in the container obscures it.
121 146
 
122
-    Deleting a directory in a container results in *opaque directory* being created in the "upperdir". This has the same effect as a whiteout file and effectively masks the existence of the directory in the image's "lowerdir".
147
+    Deleting a directory in a container results in *opaque directory* being 
148
+created in the "upperdir". This has the same effect as a whiteout file and 
149
+effectively masks the existence of the directory in the image's "lowerdir".
123 150
 
124 151
 ## Configure Docker with the overlay storage driver
125 152
 
126
-To configure Docker to use the overlay storage driver your Docker host must be running version 3.18 of the Linux kernel (preferably newer) with the overlay kernel module loaded.  OverlayFS can operate on top of most supported Linux filesystems. However, ext4 is currently recommended for use in production environments.
153
+To configure Docker to use the overlay storage driver your Docker host must be 
154
+running version 3.18 of the Linux kernel (preferably newer) with the overlay 
155
+kernel module loaded. OverlayFS can operate on top of most supported Linux 
156
+filesystems. However, ext4 is currently recommended for use in production 
157
+environments.
127 158
 
128
-The following procedure shows you how to configure your Docker host to use OverlayFS. The procedure assumes that the Docker daemon is in a stopped state.
159
+The following procedure shows you how to configure your Docker host to use 
160
+OverlayFS. The procedure assumes that the Docker daemon is in a stopped state.
129 161
 
130
-> **Caution:** If you have already run the Docker daemon on your Docker host and have images you want to keep, `push` them Docker Hub or your private Docker Trusted Registry before attempting this procedure.
162
+> **Caution:** If you have already run the Docker daemon on your Docker host 
163
+> and have images you want to keep, `push` them Docker Hub or your private 
164
+> Docker Trusted Registry before attempting this procedure.
131 165
 
132 166
 1. If it is running, stop the Docker `daemon`.
133 167
 
... ...
@@ -163,28 +240,60 @@ The following procedure shows you how to configure your Docker host to use Overl
163 163
          Backing Filesystem: extfs
164 164
         <output truncated>
165 165
 
166
-    Notice that the *Backing filesystem* in the output above is showing as `extfs`. Multiple backing filesystems are supported but `extfs` (ext4) is recommended for production use cases.
166
+    Notice that the *Backing filesystem* in the output above is showing as 
167
+`extfs`. Multiple backing filesystems are supported but `extfs` (ext4) is 
168
+recommended for production use cases.
167 169
 
168
-Your Docker host is now using the `overlay` storage driver. If you run the `mount` command, you'll find Docker has automatically created the `overlay` mount with the required "lowerdir", "upperdir", "merged" and "workdir" constructs.
170
+Your Docker host is now using the `overlay` storage driver. If you run the 
171
+`mount` command, you'll find Docker has automatically created the `overlay` 
172
+mount with the required "lowerdir", "upperdir", "merged" and "workdir" 
173
+constructs.
169 174
 
170 175
 ## OverlayFS and Docker Performance
171 176
 
172
-As a general rule, the `overlay` driver should be fast. Almost certainly faster than `aufs` and `devicemapper`. In certain circumstances it may also be faster than `btrfs`. That said, there are a few things to be aware of relative to the performance of Docker using the `overlay` storage driver.
173
-
174
-- **Page Caching**. OverlayFS supports page cache sharing. This means multiple containers accessing the same file can share a single page cache entry (or entries). This makes the `overlay` driver efficient with memory and a good option for PaaS and other high density use cases.
175
-
176
-- **copy_up**. As with AUFS, OverlayFS has to perform copy-up operations any time a container writes to a file for the first time. This can insert latency into the write operation &mdash; especially if the file being copied up is large. However, once the file has been copied up, all subsequent writes to that file occur without the need for further copy-up operations.
177
-
178
-    The OverlayFS copy_up operation should be faster than the same operation with AUFS. This is because AUFS supports more layers than OverlayFS and it is possible to incur far larger latencies if searching through many AUFS layers.
179
-
180
-- **RPMs and Yum**. OverlayFS only implements a subset of the POSIX standards. This can result in certain OverlayFS operations breaking POSIX standards. One such operation is the *copy-up* operation. Therefore, using `yum` inside of a container on a Docker host using the `overlay` storage driver is unlikely to work without implementing workarounds.
181
-
182
-- **Inode limits**. Use of the `overlay` storage driver can cause excessive inode consumption. This is especially so as the number of images and containers on the Docker host grows. A Docker host with a large number of images and lots of started and stopped containers can quickly run out of inodes.
183
-
184
-  Unfortunately you can only specify the number of inodes in a filesystem at the time of creation. For this reason, you may wish to consider putting `/var/lib/docker` on a separate device with its own filesystem or manually specifying the number of inodes when creating the filesystem.
177
+As a general rule, the `overlay` driver should be fast. Almost certainly faster
178
+ than `aufs` and `devicemapper`. In certain circumstances it may also be faster
179
+ than `btrfs`. That said, there are a few things to be aware of relative to the
180
+ performance of Docker using the `overlay` storage driver.
181
+
182
+- **Page Caching**. OverlayFS supports page cache sharing. This means multiple 
183
+containers accessing the same file can share a single page cache entry (or 
184
+entries). This makes the `overlay` driver efficient with memory and a good 
185
+option for PaaS and other high density use cases.
186
+
187
+- **copy_up**. As with AUFS, OverlayFS has to perform copy-up operations any 
188
+time a container writes to a file for the first time. This can insert latency 
189
+into the write operation &mdash; especially if the file being copied up is 
190
+large. However, once the file has been copied up, all subsequent writes to that
191
+ file occur without the need for further copy-up operations.
192
+
193
+    The OverlayFS copy_up operation should be faster than the same operation 
194
+with AUFS. This is because AUFS supports more layers than OverlayFS and it is 
195
+possible to incur far larger latencies if searching through many AUFS layers.
196
+
197
+- **RPMs and Yum**. OverlayFS only implements a subset of the POSIX standards. 
198
+This can result in certain OverlayFS operations breaking POSIX standards. One 
199
+such operation is the *copy-up* operation. Therefore, using `yum` inside of a 
200
+container on a Docker host using the `overlay` storage driver is unlikely to 
201
+work without implementing workarounds.
202
+
203
+- **Inode limits**. Use of the `overlay` storage driver can cause excessive 
204
+inode consumption. This is especially so as the number of images and containers
205
+ on the Docker host grows. A Docker host with a large number of images and lots
206
+ of started and stopped containers can quickly run out of inodes.
207
+
208
+Unfortunately you can only specify the number of inodes in a filesystem at the 
209
+time of creation. For this reason, you may wish to consider putting 
210
+`/var/lib/docker` on a separate device with its own filesystem, or manually 
211
+specifying the number of inodes when creating the filesystem.
185 212
 
186 213
 The following generic performance best practices also apply to OverlayFS.
187 214
 
188
-- **Solid State Devices (SSD)**. For best performance it is always a good idea to use fast storage media such as solid state devices (SSD).
215
+- **Solid State Devices (SSD)**. For best performance it is always a good idea 
216
+to use fast storage media such as solid state devices (SSD).
189 217
 
190
-- **Use Data Volumes**. Data volumes provide the best and most predictable performance. This is because they bypass the storage driver and do not incur any of the potential overheads introduced by thin provisioning and copy-on-write. For this reason, you may want to place heavy write workloads on data volumes.
218
+- **Use Data Volumes**. Data volumes provide the best and most predictable 
219
+performance. This is because they bypass the storage driver and do not incur 
220
+any of the potential overheads introduced by thin provisioning and 
221
+copy-on-write. For this reason, you should place heavy write workloads on data 
222
+volumes.
... ...
@@ -12,15 +12,27 @@ weight = -1
12 12
 # Select a storage driver
13 13
 
14 14
 This page describes Docker's storage driver feature. It lists the storage
15
-driver's that Docker supports and the basic commands associated with managing them. Finally, this page provides guidance on choosing a storage driver.
15
+driver's that Docker supports and the basic commands associated with managing
16
+them. Finally, this page provides guidance on choosing a storage driver.
16 17
 
17
-The material on this page is intended for readers who already have an [understanding of the storage driver technology](imagesandcontainers.md).
18
+The material on this page is intended for readers who already have an
19
+[understanding of the storage driver technology](imagesandcontainers.md).
18 20
 
19 21
 ## A pluggable storage driver architecture
20 22
 
21
-The Docker has a pluggable storage driver architecture.  This gives you the flexibility to "plug in" the storage driver is best for your environment and use-case. Each Docker storage driver is based on a Linux filesystem or volume manager. Further, each storage driver is free to implement the management of image layers and the container layer in it's own unique way. This means some storage drivers perform better than others in different circumstances.
23
+Docker has a pluggable storage driver architecture. This gives you the
24
+flexibility to "plug in" the storage driver that is best for your environment
25
+and use-case. Each Docker storage driver is based on a Linux filesystem or
26
+volume manager. Further, each storage driver is free to implement the
27
+management of image layers and the container layer in its own unique way. This
28
+means some storage drivers perform better than others in different
29
+circumstances.
22 30
 
23
-Once you decide which driver is best, you set this driver on the Docker daemon at start time. As a result, the Docker daemon can only run one storage driver, and all containers created by that daemon instance use the same storage driver. The table below shows the supported storage driver technologies and their driver names:
31
+Once you decide which driver is best, you set this driver on the Docker daemon
32
+at start time. As a result, the Docker daemon can only run one storage driver,
33
+and all containers created by that daemon instance use the same storage driver.
34
+ The table below shows the supported storage driver technologies and their
35
+driver names:
24 36
 
25 37
 |Technology    |Storage driver name  |
26 38
 |--------------|---------------------|
... ...
@@ -31,7 +43,8 @@ Once you decide which driver is best, you set this driver on the Docker daemon a
31 31
 |VFS*          |`vfs`                |
32 32
 |ZFS           |`zfs`                |
33 33
 
34
-To find out which storage driver is set on the daemon , you use the `docker info` command:
34
+To find out which storage driver is set on the daemon , you use the
35
+`docker info` command:
35 36
 
36 37
     $ docker info
37 38
     Containers: 0
... ...
@@ -44,9 +57,19 @@ To find out which storage driver is set on the daemon , you use the `docker info
44 44
     Operating System: Ubuntu 15.04
45 45
     ... output truncated ...
46 46
 
47
-The `info` subcommand reveals that the Docker daemon is using the `overlay` storage driver with a `Backing Filesystem` value of `extfs`. The `extfs` value means that the `overlay` storage driver is operating on top of an existing (ext) filesystem. The backing filesystem refers to the filesystem that was used to create the Docker host's local storage area under `/var/lib/docker`.
47
+The `info` subcommand reveals that the Docker daemon is using the `overlay`
48
+storage driver with a `Backing Filesystem` value of `extfs`. The `extfs` value
49
+means that the `overlay` storage driver is operating on top of an existing
50
+(ext) filesystem. The backing filesystem refers to the filesystem that was used
51
+ to create the Docker host's local storage area under `/var/lib/docker`.
48 52
 
49
-Which storage driver you use, in part, depends on the backing filesystem you plan to use for your Docker host's local storage area. Some storage drivers can operate on top of different backing filesystems. However, other storage drivers require the backing filesystem to be the same as the storage driver. For example, the `btrfs` storage driver can only work with a `btrfs` backing filesystem. The following table lists each storage driver and whether it must match the host's backing file system:
53
+Which storage driver you use, in part, depends on the backing filesystem you
54
+plan to use for your Docker host's local storage area. Some storage drivers can
55
+ operate on top of different backing filesystems. However, other storage
56
+drivers require the backing filesystem to be the same as the storage driver.
57
+For example, the `btrfs` storage driver on a Btrfs backing filesystem. The
58
+following table lists each storage driver and whether it must match the host's
59
+backing file system:
50 60
 
51 61
     |Storage driver |Must match backing filesystem |
52 62
     |---------------|------------------------------|
... ...
@@ -58,9 +81,12 @@ Which storage driver you use, in part, depends on the backing filesystem you pla
58 58
     |zfs            |Yes                           |
59 59
 
60 60
 
61
-You can set the storage driver by passing the `--storage-driver=<name>` option to the `docker daemon` command line or by setting the option on the `DOCKER_OPTS` line in `/etc/default/docker` file.
61
+You can set the storage driver by passing the `--storage-driver=<name>` option
62
+to the `docker daemon` command line, or by setting the option on the
63
+`DOCKER_OPTS` line in the `/etc/default/docker` file.
62 64
 
63
-The following command shows how to start the Docker daemon with the `devicemapper` storage driver using the `docker daemon` command:
65
+The following command shows how to start the Docker daemon with the
66
+`devicemapper` storage driver using the `docker daemon` command:
64 67
 
65 68
     $ docker daemon --storage-driver=devicemapper &
66 69
 
... ...
@@ -90,25 +116,82 @@ The following command shows how to start the Docker daemon with the `devicemappe
90 90
     Operating System: Ubuntu 15.04
91 91
     <output truncated>
92 92
 
93
-Your choice of storage driver can affect the performance of your containerized applications. So it's important to understand the different storage driver options available and select the right one for your application. Later, in this page you'll find some advice for choosing an appropriate driver.
93
+Your choice of storage driver can affect the performance of your containerized
94
+applications. So it's important to understand the different storage driver
95
+options available and select the right one for your application. Later, in this
96
+ page you'll find some advice for choosing an appropriate driver.
94 97
 
95 98
 ## Shared storage systems and the storage driver
96 99
 
97
-Many enterprises consume storage from shared storage systems such as SAN and NAS arrays. These often provide increased performance and availability, as well as advanced features such as thin provisioning, deduplication and compression.
100
+Many enterprises consume storage from shared storage systems such as SAN and
101
+NAS arrays. These often provide increased performance and availability, as well
102
+ as advanced features such as thin provisioning, deduplication and compression.
98 103
 
99
-The Docker storage driver and data volumes can both operate on top of storage provided by shared storage systems. This allows Docker to leverage the increased performance and availability these systems provide. However, Docker does not integrate with these underlying systems.
104
+The Docker storage driver and data volumes can both operate on top of storage
105
+provided by shared storage systems. This allows Docker to leverage the
106
+increased performance and availability these systems provide. However, Docker
107
+does not integrate with these underlying systems.
100 108
 
101
-Remember that each Docker storage driver is based on a Linux filesystem or volume manager. Be sure to follow existing best practices for operating your storage driver (filesystem or volume manager) on top of your shared storage system. For example, if using the ZFS storage driver on top of *XYZ* shared storage system, be sure to follow best practices for operating ZFS filesystems on top of XYZ shared storage system.
109
+Remember that each Docker storage driver is based on a Linux filesystem or
110
+volume manager. Be sure to follow existing best practices for operating your
111
+storage driver (filesystem or volume manager) on top of your shared storage
112
+system. For example, if using the ZFS storage driver on top of *XYZ* shared
113
+storage system, be sure to follow best practices for operating ZFS filesystems
114
+on top of XYZ shared storage system.
102 115
 
103 116
 ## Which storage driver should you choose?
104 117
 
105
-As you might expect, the answer to this question is "it depends". While there are some clear cases where one particular storage driver outperforms other for certain workloads, you should factor all of the following into your decision:
106
-
107
-Choose a storage driver that you and your team/organization are comfortable with.  Consider how much experience you have with a particular storage driver. There is no substitute for experience and it is rarely a good idea to try something brand new in production. That's what labs and laptops are for!
108
-
109
-If your Docker infrastructure is under support contracts, choose an option that will get you good support. You probably don't want to go with a solution that your support partners have little or no experience with.
110
-
111
-Whichever driver you choose, make sure it has strong community support and momentum. This is important because storage driver development in the Docker project relies on the community as much as the Docker staff to thrive.
118
+Several factors influence the selection of a storage driver. However, these two
119
+ facts must be kept in mind:
120
+
121
+1. No single driver is well suited to every use-case
122
+2. Storage drivers are improving and evolving all of the time
123
+
124
+With these factors in mind, the following points, coupled with the table below,
125
+ should provide some guidance.
126
+
127
+### Stability
128
+For the most stable and hassle-free Docker experience, you should consider the
129
+following:
130
+
131
+- **Use the default storage driver for your distribution**. When Docker
132
+installs, it chooses a default storage driver based on the configuration of
133
+your system. Stability is an important factor influencing which storage driver
134
+is used by default. Straying from this default may increase your chances of
135
+encountering bugs and nuances.
136
+- **Follow the configuration specified on the CS Engine
137
+[compatibility matrix](https://www.docker.com/compatibility-maintenance)**. The
138
+ CS Engine is the commercially supported version of the Docker Engine. It's
139
+code-base is identical to the open source Engine, but it has a limited set of
140
+supported configurations. These *supported configurations* use the most stable
141
+and mature storage drivers. Straying from these configurations may also
142
+increase your chances of encountering bugs and nuances.
143
+
144
+### Experience and expertise
145
+
146
+Choose a storage driver that you and your team/organization have experience
147
+with. For example, if you use RHEL or one of its downstream forks, you may
148
+already have experience with LVM and Device Mapper. If so, you may wish to use
149
+the `devicemapper` driver.
150
+
151
+If you do not feel you have expertise with any of the storage drivers supported
152
+ by Docker, and you want an easy-to-use stable Docker experience, you should
153
+consider using the default driver installed by your distribution's Docker
154
+package.
155
+
156
+### Future-proofing
157
+
158
+Many people consider OverlayFS as the future of the Docker storage driver.
159
+However, it is less mature, and potentially less stable than some of the more
160
+mature drivers such as `aufs` and `devicemapper`.  For this reason, you should
161
+use the OverlayFS driver with caution and expect to encounter more bugs and
162
+nuances than if you were using a more mature driver.
163
+
164
+The following diagram lists each storage driver and provides insight into some
165
+of their pros and cons. When selecting which storage driver to use, consider
166
+the guidance offered by the table below along with the points mentioned above.
167
+
168
+![](images/driver-pros-cons.png)
112 169
 
113 170
 
114 171
 ## Related information
... ...
@@ -10,13 +10,24 @@ parent = "engine_driver"
10 10
 
11 11
 # Docker and ZFS in practice
12 12
 
13
-ZFS is a next generation filesystem that supports many advanced storage technologies such as volume management, snapshots, checksumming, compression and deduplication, replication and more.
13
+ZFS is a next generation filesystem that supports many advanced storage 
14
+technologies such as volume management, snapshots, checksumming, compression 
15
+and deduplication, replication and more.
14 16
 
15
-It was created by Sun Microsystems (now Oracle Corporation) and is open sourced under the CDDL license. Due to licensing incompatibilities between the CDDL and GPL, ZFS cannot be shipped as part of the mainline Linux kernel. However, the ZFS On Linux (ZoL) project provides an out-of-tree kernel module and userspace tools which can be installed separately.
17
+It was created by Sun Microsystems (now Oracle Corporation) and is open sourced
18
+ under the CDDL license. Due to licensing incompatibilities between the CDDL 
19
+and GPL, ZFS cannot be shipped as part of the mainline Linux kernel. However, 
20
+the ZFS On Linux (ZoL) project provides an out-of-tree kernel module and 
21
+userspace tools which can be installed separately.
16 22
 
17
-The ZFS on Linux (ZoL) port is healthy and maturing. However, at this point in time it is not recommended to use the `zfs` Docker storage driver for production use unless you have substantial experience with ZFS on Linux.
23
+The ZFS on Linux (ZoL) port is healthy and maturing. However, at this point in 
24
+time it is not recommended to use the `zfs` Docker storage driver for 
25
+production use unless you have substantial experience with ZFS on Linux.
18 26
 
19
-> **Note:** There is also a FUSE implementation of ZFS on the Linux platform. This should work with Docker but is not recommended. The native ZFS driver (ZoL) is more tested, more performant, and is more widely used. The remainder of this document will relate to the native ZoL port.
27
+> **Note:** There is also a FUSE implementation of ZFS on the Linux platform. 
28
+> This should work with Docker but is not recommended. The native ZFS driver 
29
+> (ZoL) is more tested, more performant, and is more widely used. The remainder
30
+>  of this document will relate to the native ZoL port.
20 31
 
21 32
 
22 33
 ## Image layering and sharing with ZFS
... ...
@@ -27,53 +38,96 @@ The Docker `zfs` storage driver makes extensive use of three ZFS datasets:
27 27
 - snapshots
28 28
 - clones
29 29
 
30
-ZFS filesystems are thinly provisioned and have space allocated to them from a ZFS pool (zpool) via allocate on demand operations. Snapshots and clones are space-efficient point-in-time copies of ZFS filesystems. Snapshots are read-only. Clones are read-write. Clones can only be created from snapshots. This simple relationship is shown in the diagram below.
30
+ZFS filesystems are thinly provisioned and have space allocated to them from a 
31
+ZFS pool (zpool) via allocate on demand operations. Snapshots and clones are 
32
+space-efficient point-in-time copies of ZFS filesystems. Snapshots are 
33
+read-only. Clones are read-write. Clones can only be created from snapshots. 
34
+This simple relationship is shown in the diagram below.
31 35
 
32 36
 ![](images/zfs_clones.jpg)
33 37
 
34
-The solid line in the diagram shows the process flow for creating a clone. Step 1 creates a snapshot of the filesystem, and step two creates the clone from the snapshot. The dashed line shows the relationship between the clone and the filesystem, via the snapshot. All three ZFS datasets draw space form the same underlying zpool.
38
+The solid line in the diagram shows the process flow for creating a clone. Step
39
+ 1 creates a snapshot of the filesystem, and step two creates the clone from 
40
+the snapshot. The dashed line shows the relationship between the clone and the 
41
+filesystem, via the snapshot. All three ZFS datasets draw space form the same 
42
+underlying zpool.
35 43
 
36
-On Docker hosts using the `zfs` storage driver, the base layer of an image is a ZFS filesystem. Each child layer is a ZFS clone based on a ZFS snapshot of the layer below it. A container is a ZFS clone based on a ZFS Snapshot of the top layer of the image it's created from. All ZFS datasets draw their space from a common zpool. The diagram below shows how this is put together with a running container based on a two-layer image.
44
+On Docker hosts using the `zfs` storage driver, the base layer of an image is a
45
+ ZFS filesystem. Each child layer is a ZFS clone based on a ZFS snapshot of the
46
+ layer below it. A container is a ZFS clone based on a ZFS Snapshot of the top 
47
+layer of the image it's created from. All ZFS datasets draw their space from a 
48
+common zpool. The diagram below shows how this is put together with a running 
49
+container based on a two-layer image.
37 50
 
38 51
 ![](images/zfs_zpool.jpg)
39 52
 
40
-The following process explains how images are layered and containers created. The process is based on the diagram above.
53
+The following process explains how images are layered and containers created. 
54
+The process is based on the diagram above.
41 55
 
42 56
 1. The base layer of the image exists on the Docker host as a ZFS filesystem.
43 57
 
44
-    This filesystem consumes space from the zpool used to create the Docker host's local storage area at `/var/lib/docker`.
58
+    This filesystem consumes space from the zpool used to create the Docker 
59
+host's local storage area at `/var/lib/docker`.
45 60
 
46
-2. Additional image layers are clones of the dataset hosting the image layer directly below it.
61
+2. Additional image layers are clones of the dataset hosting the image layer 
62
+directly below it.
47 63
 
48
-    In the diagram, "Layer 1" is added by making a ZFS snapshot of the base layer and then creating a clone from that snapshot. The clone is writable and consumes space on-demand from the zpool. The snapshot is read-only, maintaining the base layer as an immutable object.
64
+    In the diagram, "Layer 1" is added by making a ZFS snapshot of the base 
65
+layer and then creating a clone from that snapshot. The clone is writable and 
66
+consumes space on-demand from the zpool. The snapshot is read-only, maintaining
67
+ the base layer as an immutable object.
49 68
 
50 69
 3. When the container is launched, a read-write layer is added above the image.
51 70
 
52
-    In the diagram above, the container's read-write layer is created by making a snapshot of the top layer of the image (Layer 1) and creating a clone from that snapshot.
71
+    In the diagram above, the container's read-write layer is created by making
72
+ a snapshot of the top layer of the image (Layer 1) and creating a clone from 
73
+that snapshot.
53 74
 
54
-    As changes are made to the container, space is allocated to it from the zpool via allocate-on-demand operations. By default, ZFS will allocate space in blocks of 128K.
75
+    As changes are made to the container, space is allocated to it from the 
76
+zpool via allocate-on-demand operations. By default, ZFS will allocate space in
77
+ blocks of 128K.
55 78
 
56
-This process of creating child layers and containers from *read-only* snapshots allows images to be maintained as immutable objects.
79
+This process of creating child layers and containers from *read-only* snapshots
80
+ allows images to be maintained as immutable objects.
57 81
 
58 82
 ## Container reads and writes with ZFS
59 83
 
60
-Container reads with the `zfs` storage driver are very simple. A newly launched container is based on a ZFS clone. This clone initially shares all of its data with the dataset it was created from. This means that read operations with the `zfs` storage driver are fast &ndash; even if the data being read was copied into the container yet. This sharing of data blocks is shown in the diagram below.
84
+Container reads with the `zfs` storage driver are very simple. A newly launched
85
+ container is based on a ZFS clone. This clone initially shares all of its data
86
+ with the dataset it was created from. This means that read operations with the
87
+ `zfs` storage driver are fast &ndash; even if the data being read was note 
88
+copied into the container yet. This sharing of data blocks is shown in the 
89
+diagram below.
61 90
 
62 91
 ![](images/zpool_blocks.jpg)
63 92
 
64
-Writing new data to a container is accomplished via an allocate-on-demand operation. Every time a new area of the container needs writing to, a new block is allocated from the zpool. This means that containers consume additional space as new data is written to them. New space is allocated to the container (ZFS Clone) from the underlying zpool.
93
+Writing new data to a container is accomplished via an allocate-on-demand 
94
+operation. Every time a new area of the container needs writing to, a new block
95
+ is allocated from the zpool. This means that containers consume additional 
96
+space as new data is written to them. New space is allocated to the container 
97
+(ZFS Clone) from the underlying zpool.
65 98
 
66
-Updating *existing data* in a container is accomplished by allocating new blocks to the containers clone and storing the changed data in those new blocks. The original are unchanged, allowing the underlying image dataset to remain immutable. This is the same as writing to a normal ZFS filesystem and is an implementation of copy-on-write semantics.
99
+Updating *existing data* in a container is accomplished by allocating new 
100
+blocks to the containers clone and storing the changed data in those new 
101
+blocks. The original blocks are unchanged, allowing the underlying image 
102
+dataset to remain immutable. This is the same as writing to a normal ZFS 
103
+filesystem and is an implementation of copy-on-write semantics.
67 104
 
68 105
 ## Configure Docker with the ZFS storage driver
69 106
 
70
-The `zfs` storage driver is only supported on a Docker host where `/var/lib/docker` is mounted as a ZFS filesystem. This section shows you how to install and configure native ZFS on Linux (ZoL) on an Ubuntu 14.04 system.
107
+The `zfs` storage driver is only supported on a Docker host where 
108
+`/var/lib/docker` is mounted as a ZFS filesystem. This section shows you how to
109
+ install and configure native ZFS on Linux (ZoL) on an Ubuntu 14.04 system.
71 110
 
72 111
 ### Prerequisites
73 112
 
74
-If you have already used the Docker daemon on your Docker host and have images you want to keep, `push` them Docker Hub or your private Docker Trusted Registry before attempting this procedure.
113
+If you have already used the Docker daemon on your Docker host and have images 
114
+you want to keep, `push` them Docker Hub or your private Docker Trusted 
115
+Registry before attempting this procedure.
75 116
 
76
-Stop the Docker daemon. Then, ensure that you have a spare block device at `/dev/xvdb`. The device identifier may be be different in your environment and you should substitute your own values throughout the procedure.
117
+Stop the Docker daemon. Then, ensure that you have a spare block device at 
118
+`/dev/xvdb`. The device identifier may be be different in your environment and 
119
+you should substitute your own values throughout the procedure.
77 120
 
78 121
 ### Install Zfs on Ubuntu 14.04 LTS
79 122
 
... ...
@@ -98,7 +152,8 @@ Stop the Docker daemon. Then, ensure that you have a spare block device at `/dev
98 98
         gpg:               imported: 1  (RSA: 1)
99 99
         OK
100 100
 
101
-3. Get the latest package lists for all registered repositories and package archives.
101
+3. Get the latest package lists for all registered repositories and package 
102
+archives.
102 103
 
103 104
         $ sudo apt-get update
104 105
         Ign http://us-west-2.ec2.archive.ubuntu.com trusty InRelease
... ...
@@ -156,7 +211,8 @@ Once ZFS is installed and loaded, you're ready to configure ZFS for Docker.
156 156
         zpool-docker         93.5K  3.84G    19K  /zpool-docker
157 157
         zpool-docker/docker  19K    3.84G    19K  /var/lib/docker
158 158
 
159
-    Now that you have a ZFS filesystem mounted to `/var/lib/docker`, the daemon should automatically load with the `zfs` storage driver.
159
+    Now that you have a ZFS filesystem mounted to `/var/lib/docker`, the daemon
160
+ should automatically load with the `zfs` storage driver.
160 161
 
161 162
 5. Start the Docker daemon.
162 163
 
... ...
@@ -165,9 +221,9 @@ Once ZFS is installed and loaded, you're ready to configure ZFS for Docker.
165 165
 
166 166
     The procedure for starting the Docker daemon may differ depending on the
167 167
     Linux distribution you are using. It is possible to force the Docker daemon
168
-    to start with the `zfs` storage driver by passing the `--storage-driver=zfs`
169
-    flag to the `docker daemon` command, or to the `DOCKER_OPTS` line in the
170
-    Docker config file.
168
+    to start with the `zfs` storage driver by passing the 
169
+    `--storage-driver=zfs`flag to the `docker daemon` command, or to the 
170
+    `DOCKER_OPTS` line in the Docker config file.
171 171
 
172 172
 6. Verify that the daemon is using the `zfs` storage driver.
173 173
 
... ...
@@ -186,33 +242,55 @@ Once ZFS is installed and loaded, you're ready to configure ZFS for Docker.
186 186
         [...]
187 187
 
188 188
     The output of the command above shows that the Docker daemon is using the
189
-    `zfs` storage driver and that the parent dataset is the `zpool-docker/docker`
190
-    filesystem created earlier.
189
+    `zfs` storage driver and that the parent dataset is the 
190
+    `zpool-docker/docker` filesystem created earlier.
191 191
 
192 192
 Your Docker host is now using ZFS to store to manage its images and containers.
193 193
 
194 194
 ## ZFS and Docker performance
195 195
 
196
-There are several factors that influence the performance of Docker using the `zfs` storage driver.
197
-
198
-- **Memory**. Memory has a major impact on ZFS performance. This goes back to the fact that ZFS was originally designed for use on big Sun Solaris servers with large amounts of memory. Keep this in mind when sizing your Docker hosts.
199
-
200
-- **ZFS Features**. Using ZFS features, such as deduplication, can significantly increase the amount
201
-of memory ZFS uses. For memory consumption and performance reasons it is
202
-recommended to turn off ZFS deduplication. However, deduplication at other
203
-layers in the stack (such as SAN or NAS arrays) can still be used as these do
204
-not impact ZFS memory usage and performance. If using SAN, NAS or other hardware
205
-RAID technologies you should continue to follow existing best practices for
206
-using them with ZFS.
207
-
208
-* **ZFS Caching**. ZFS caches disk blocks in a memory structure called the adaptive replacement cache (ARC). The *Single Copy ARC* feature of ZFS allows a single cached copy of a block to be shared by multiple clones of a filesystem. This means that multiple running containers can share a single copy of cached block. This means that ZFS is a good option for PaaS and other high density use cases.
209
-
210
-- **Fragmentation**. Fragmentation is a natural byproduct of copy-on-write filesystems like ZFS. However, ZFS writes in 128K blocks and allocates *slabs* (multiple 128K blocks) to CoW operations in an attempt to reduce fragmentation. The ZFS intent log (ZIL) and the coalescing of writes (delayed writes) also help to reduce fragmentation.
211
-
212
-- **Use the native ZFS driver for Linux**. Although the Docker `zfs` storage driver supports the ZFS FUSE implementation, it is not recommended when high performance is required. The native ZFS on Linux driver tends to perform better than the FUSE implementation.
196
+There are several factors that influence the performance of Docker using the 
197
+`zfs` storage driver.
198
+
199
+- **Memory**. Memory has a major impact on ZFS performance. This goes back to 
200
+the fact that ZFS was originally designed for use on big Sun Solaris servers 
201
+with large amounts of memory. Keep this in mind when sizing your Docker hosts.
202
+
203
+- **ZFS Features**. Using ZFS features, such as deduplication, can 
204
+significantly increase the amount of memory ZFS uses. For memory consumption 
205
+and performance reasons it is recommended to turn off ZFS deduplication. 
206
+However, deduplication at other layers in the stack (such as SAN or NAS arrays)
207
+ can still be used as these do not impact ZFS memory usage and performance. If 
208
+using SAN, NAS or other hardware RAID technologies you should continue to 
209
+follow existing best practices for using them with ZFS.
210
+
211
+- **ZFS Caching**. ZFS caches disk blocks in a memory structure called the 
212
+adaptive replacement cache (ARC). The *Single Copy ARC* feature of ZFS allows a
213
+ single cached copy of a block to be shared by multiple clones of a filesystem.
214
+ This means that multiple running containers can share a single copy of cached 
215
+block. This means that ZFS is a good option for PaaS and other high density use
216
+ cases.
217
+
218
+- **Fragmentation**. Fragmentation is a natural byproduct of copy-on-write 
219
+filesystems like ZFS. However, ZFS writes in 128K blocks and allocates *slabs* 
220
+(multiple 128K blocks) to CoW operations in an attempt to reduce fragmentation.
221
+ The ZFS intent log (ZIL) and the coalescing of writes (delayed writes) also 
222
+help to reduce fragmentation.
223
+
224
+- **Use the native ZFS driver for Linux**. Although the Docker `zfs` storage 
225
+driver supports the ZFS FUSE implementation, it is not recommended when high 
226
+performance is required. The native ZFS on Linux driver tends to perform better
227
+ than the FUSE implementation.
213 228
 
214 229
 The following generic performance best practices also apply to ZFS.
215 230
 
216
-- **Use of SSD**. For best performance it is always a good idea to use fast storage media such as solid state devices (SSD). However, if you only have a limited amount of SSD storage available it is recommended to place the ZIL on SSD.
231
+- **Use of SSD**. For best performance it is always a good idea to use fast 
232
+storage media such as solid state devices (SSD). However, if you only have a 
233
+limited amount of SSD storage available it is recommended to place the ZIL on 
234
+SSD.
217 235
 
218
-- **Use Data Volumes**. Data volumes provide the best and most predictable performance. This is because they bypass the storage driver and do not incur any of the potential overheads introduced by thin provisioning and copy-on-write. For this reason, you may want to place heavy write workloads on data volumes.
236
+- **Use Data Volumes**. Data volumes provide the best and most predictable 
237
+performance. This is because they bypass the storage driver and do not incur 
238
+any of the potential overheads introduced by thin provisioning and 
239
+copy-on-write. For this reason, you should place heavy write workloads on data 
240
+volumes.