github.com/walkingsparrow/docker@v1.4.2-0.20151218153551-b708a2249bfa/docs/userguide/storagedriver/imagesandcontainers.md (about)

     1  <!--[metadata]>
     2  +++
     3  title = "Understand images, containers, and storage drivers"
     4  description = "Learn the technologies that support storage drivers."
     5  keywords = ["container, storage, driver, AUFS, btfs, devicemapper,zvfs"]
     6  [menu.main]
     7  parent = "mn_storage_docker"
     8  weight = -2
     9  +++
    10  <![end-metadata]-->
    11  
    12  
    13  # Understand images, containers, and storage drivers
    14  
    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.
    17  
    18  ## Images and containers rely on layers
    19  
    20  Docker images are a series of read-only layers that are stacked
    21  on top of each other to form a single unified view. The first image in the stack
    22  is called a *base image* and all the other layers are stacked on top of this
    23  layer. The diagram below shows the Ubuntu 15:04 image comprising 4 stacked image layers.
    24  
    25  ![](images/image-layers.jpg)
    26  
    27  When you make a change inside a container by, for example, adding a new file to the Ubuntu 15.04 image, you add a new layer on top of the underlying image stack. This change creates a new image layer containing the newly added file. Each image layer has its own universal unique identifier (UUID) and each successive image layer builds on top of the image layer below it.
    28  
    29  Containers (in the storage context) are a combination of a Docker image with a
    30  thin writable layer added to the top known as the *container layer*.  The diagram below shows a container running the Ubuntu 15.04 image.
    31  
    32  ![](images/container-layers.jpg)
    33  
    34  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.
    35  
    36  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.
    37  
    38  ![](images/sharing-layers.jpg)
    39  
    40  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).
    41  
    42  
    43  ## The copy-on-write strategy
    44  
    45  Sharing is a good way to optimize resources. People do this instinctively in
    46  daily life. For example, twins Jane and Joseph taking an Algebra class at
    47  different times from different teachers can share the same exercise book by
    48  passing it between each other. Now, suppose Jane gets an assignment to complete
    49  the homework on page 11 in the book. At that point, Jane copy page 11, complete the homework, and hand in her copy. The original exercise book is unchanged and only Jane has a copy of the changed page 11.
    50  
    51  Copy-on-write is a similar strategy of sharing and copying. In this strategy,
    52  system processes that need the same data share the same instance of that data
    53  rather than having their own copy. At some point, if one process needs to modify
    54  or write to the data, only then does the operating system make a copy of the
    55  data for that process to use. Only the process that needs to write has access to
    56  the data copy. All the other processes continue to use the original data.
    57  
    58  Docker uses a copy-on-write technology with both images and containers. This CoW
    59  strategy optimizes both image disk space usage and the performance of container
    60  start times. The next sections look at how copy-on-write is leveraged with
    61  images and containers thru sharing and copying.
    62  
    63  ### Sharing promotes smaller images
    64  
    65  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
    66  filesystem.
    67  
    68  The Docker client reports on image layers when instructed to pull and push
    69  images with `docker pull` and `docker push`. The command below pulls the
    70  `ubuntu:15.04` Docker image from Docker Hub.
    71  
    72      $ docker pull ubuntu:15.04
    73      15.04: Pulling from library/ubuntu
    74      6e6a100fa147: Pull complete
    75      13c0c663a321: Pull complete
    76      2bd276ed39d5: Pull complete
    77      013f3d01d247: Pull complete
    78      Digest: sha256:c7ecf33cef00ae34b131605c31486c91f5fd9a76315d075db2afd39d1ccdf3ed
    79      Status: Downloaded newer image for ubuntu:15.04
    80  
    81  From the output, you'll see  that the command actually pulls 4 image layers.
    82  Each of the above lines lists an image layer and its UUID. The combination of
    83  these four layers makes up the `ubuntu:15.04` Docker image.
    84  
    85  The image layers are stored in the Docker host's local storage area. Typically,
    86  the local storage area is in the host's `/var/lib/docker` directory. Depending
    87  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:
    88  
    89      $ sudo ls /var/lib/docker/aufs/layers
    90      013f3d01d24738964bb7101fa83a926181d600ebecca7206dced59669e6e6778  2bd276ed39d5fcfd3d00ce0a190beeea508332f5aec3c6a125cc619a3fdbade6
    91      13c0c663a321cd83a97f4ce1ecbaf17c2ba166527c3b06daaefe30695c5fcb8c  6e6a100fa147e6db53b684c8516e3e2588b160fd4898b6265545d5d4edb6796d
    92  
    93  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.
    94  
    95  You can illustrate this now for yourself. Starting the `ubuntu:15.04` image that
    96  you just pulled, make a change to it, and build a new image based on the change.
    97  One way to do this is using a Dockerfile and the `docker build` command.
    98  
    99  1. In an empty directory, create a simple `Dockerfile` that starts with the ubuntu:15.04 image.
   100  
   101          FROM ubuntu:15.04
   102  
   103  2. Add a new file called "newfile" in the image's `/tmp` directory with the text "Hello world" in it.
   104  
   105    When you are done, the `Dockerfile` contains two lines:
   106  
   107          FROM ubuntu:15.04
   108  
   109          RUN echo "Hello world" > /tmp/newfile
   110  
   111  3. Save and close the file.
   112  
   113  2. From a terminal in the same folder as your Dockerfile, run the following command:
   114  
   115          $ docker build -t changed-ubuntu .
   116          Sending build context to Docker daemon 2.048 kB
   117          Step 0 : FROM ubuntu:15.04
   118           ---> 013f3d01d247
   119          Step 1 : RUN echo "Hello world" > /tmp/newfile
   120           ---> Running in 2023460815df
   121           ---> 03b964f68d06
   122          Removing intermediate container 2023460815df
   123          Successfully built 03b964f68d06
   124  
   125      > **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.
   126  
   127      The output above shows a new image with image ID `03b964f68d06`.
   128  
   129  3. Run the `docker images` command to verify the new image is in the Docker host's local storage area.
   130  
   131          REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
   132          changed-ubuntu      latest              03b964f68d06        33 seconds ago      131.4 MB
   133          ubuntu  
   134  
   135  4. Run the `docker history` command to see which image layers were used to create the new `changed-ubuntu` image.
   136  
   137          $ docker history changed-ubuntu
   138          IMAGE               CREATED              CREATED BY                                      SIZE                COMMENT
   139          03b964f68d06        About a minute ago   /bin/sh -c echo "Hello world" > /tmp/newfile    12 B                
   140          013f3d01d247        6 weeks ago          /bin/sh -c #(nop) CMD ["/bin/bash"]             0 B                 
   141          2bd276ed39d5        6 weeks ago          /bin/sh -c sed -i 's/^#\s*\(deb.*universe\)$/   1.879 kB            
   142          13c0c663a321        6 weeks ago          /bin/sh -c echo '#!/bin/sh' > /usr/sbin/polic   701 B               
   143          6e6a100fa147        6 weeks ago          /bin/sh -c #(nop) ADD file:49710b44e2ae0edef4   131.4 MB            
   144  
   145      The `docker history` output shows the new `03b964f68d06` image layer at the
   146      top. You know that the `03b964f68d06` layer was added because it was created
   147      by the `echo "Hello world" > /tmp/newfile` command in your `Dockerfile`.
   148      The 4 image layers below it are the exact same image layers the make up the
   149      ubuntu:15.04 image as their UUIDs match.
   150  
   151  5. List the contents of the local storage area to further confirm.
   152  
   153          $ sudo ls /var/lib/docker/aufs/layers
   154          013f3d01d24738964bb7101fa83a926181d600ebecca7206dced59669e6e6778  2bd276ed39d5fcfd3d00ce0a190beeea508332f5aec3c6a125cc619a3fdbade6
   155          03b964f68d06a373933bd6d61d37610a34a355c168b08dfc604f57b20647e073  6e6a100fa147e6db53b684c8516e3e2588b160fd4898b6265545d5d4edb6796d
   156          13c0c663a321cd83a97f4ce1ecbaf17c2ba166527c3b06daaefe30695c5fcb8c
   157  
   158        Where before you had four layers stored, you now have 5.
   159  
   160  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.
   161  
   162  ![](images/saving-space.jpg)
   163  
   164  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  
   166  This sharing of image layers is what makes Docker images and containers so space
   167  efficient.
   168  
   169  ### Copying makes containers efficient
   170  
   171  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:
   172  
   173  ![](images/container-layers.jpg)
   174  
   175  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:
   176  
   177  ![](images/sharing-layers.jpg)
   178  
   179  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:
   180  
   181  *  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.
   182  *  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.
   183  * Modify the *copy of the file* in container's thin writable layer.
   184  
   185  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.
   186  
   187  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.
   188  
   189  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.
   190  
   191  Let's see what happens if we spin up 5 containers based on our `changed-ubuntu` image we built earlier:
   192  
   193  1. From a terminal on your Docker host, run the following `docker run` command 5 times.
   194  
   195          $ docker run -dit changed-ubuntu bash
   196          75bab0d54f3cf193cfdc3a86483466363f442fba30859f7dcd1b816b6ede82d4
   197          $ docker run -dit changed-ubuntu bash
   198          9280e777d109e2eb4b13ab211553516124a3d4d4280a0edfc7abf75c59024d47
   199          $ docker run -dit changed-ubuntu bash
   200          a651680bd6c2ef64902e154eeb8a064b85c9abf08ac46f922ad8dfc11bb5cd8a
   201          $ docker run -dit changed-ubuntu bash
   202          8eb24b3b2d246f225b24f2fca39625aaad71689c392a7b552b78baf264647373
   203          $ docker run -dit changed-ubuntu bash
   204          0ad25d06bdf6fca0dedc38301b2aff7478b3e1ce3d1acd676573bba57cb1cfef
   205  
   206    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.
   207  
   208  2. Run the `docker ps` command to verify the 5 containers are running.
   209  
   210          $ docker ps
   211          CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS               NAMES
   212          0ad25d06bdf6        changed-ubuntu      "bash"              About a minute ago   Up About a minute                       stoic_ptolemy
   213          8eb24b3b2d24        changed-ubuntu      "bash"              About a minute ago   Up About a minute                       pensive_bartik
   214          a651680bd6c2        changed-ubuntu      "bash"              2 minutes ago        Up 2 minutes                            hopeful_turing
   215          9280e777d109        changed-ubuntu      "bash"              2 minutes ago        Up 2 minutes                            backstabbing_mahavira
   216          75bab0d54f3c        changed-ubuntu      "bash"              2 minutes ago        Up 2 minutes                            boring_pasteur
   217  
   218      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.
   219  
   220  3. List the contents of the local storage area.
   221  
   222          $ sudo ls containers
   223          0ad25d06bdf6fca0dedc38301b2aff7478b3e1ce3d1acd676573bba57cb1cfef  9280e777d109e2eb4b13ab211553516124a3d4d4280a0edfc7abf75c59024d47
   224          75bab0d54f3cf193cfdc3a86483466363f442fba30859f7dcd1b816b6ede82d4  a651680bd6c2ef64902e154eeb8a064b85c9abf08ac46f922ad8dfc11bb5cd8a
   225          8eb24b3b2d246f225b24f2fca39625aaad71689c392a7b552b78baf264647373
   226  
   227  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.
   228  
   229  ![](images/shared-uuid.jpg)
   230  
   231  If Docker had to make an entire copy of the underlying image stack each time it
   232  started a new container, container start times and disk space used would be
   233  significantly increased.
   234  
   235  ## Data volumes and the storage driver
   236  
   237  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.
   238  
   239  Data volumes are not controlled by the storage driver. Reads and writes to data
   240  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.
   241  
   242  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.
   243  
   244  ![](images/shared-volume.jpg)
   245  
   246  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.
   247  
   248  For detailed information about data volumes [Managing data in containers](https://docs.docker.com/userguide/dockervolumes/).
   249  
   250  ## Related information
   251  
   252  * [Select a storage driver](selectadriver.md)
   253  * [AUFS storage driver in practice](aufs-driver.md)
   254  * [Btrfs storage driver in practice](btrfs-driver.md)
   255  * [Device Mapper storage driver in practice](device-mapper-driver.md)