<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Volumes on Digi Hunch</title><link>https://static.digihunch.com/tag/volumes/</link><description>Recent content in Volumes on Digi Hunch</description><generator>Hugo -- gohugo.io</generator><language>en-US</language><lastBuildDate>Wed, 02 Apr 2025 14:07:24 -0400</lastBuildDate><atom:link href="https://static.digihunch.com/tag/volumes/index.xml" rel="self" type="application/rss+xml"/><item><title>Basic Resource Object in Kubernetes 2 of 2</title><link>https://static.digihunch.com/2021/02/basic-resource-object-in-kubernetes-2-of-2/</link><pubDate>Mon, 08 Feb 2021 21:02:16 -0400</pubDate><guid>https://static.digihunch.com/2021/02/basic-resource-object-in-kubernetes-2-of-2/</guid><description>&lt;p class="wp-block-paragraph"&gt;We continued from previous posting about resource object, starting from storage related ones. &lt;/p&gt;&#10;&lt;div class="wp-block-image"&gt;&lt;figure class="aligncenter"&gt;&lt;img decoding="async" src="https://github.com/kubernetes/community/raw/master/icons/png/resources/labeled/vol-128.png" alt=""/&gt;&lt;figcaption&gt;Volume&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;In Kubernetes, we use the term volume to refer to a section storage device. There are many plugins, compliant to Container Storage Interface (CSI), to allow heterogeneous storage resources to be surfaced as volumes in Kubernetes. CSI allows storage driver to operate in parallel to the main Kubernetes code tree. Any driver that complies with CSI would work with any orchestration platform that requires CSI, such as Docker Swarm, Kubernetes. Three main resources in the storage system are: PV (persistent volumes), PVC (persistent volume claims), and SC (storage classes).&lt;/p&gt;&#10;&lt;div class="wp-block-image"&gt;&lt;figure class="aligncenter"&gt;&lt;img decoding="async" src="https://github.com/kubernetes/community/raw/master/icons/png/resources/labeled/pv-128.png" alt=""/&gt;&lt;figcaption&gt;Persistent Volume&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Persistent Volumes (PV) allows you to map external storage onto the Kubernetes cluster. It is a representation of the external storage on the cluster. A single external storage volume can only be represented by a single PV. For example, you cannot have a 50GB external volume that has two 25GB PVs each representing half of it.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;PV can be mounted in three options:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&lt;li&gt;RWO (ReadWriteOnce): allows single PVC to mount. This is common for block device.&lt;/li&gt;&lt;li&gt;RWM (ReadWriteMany): allows multiple PVCs to bind as read and write. This is common for file and object level access.&lt;/li&gt;&lt;li&gt;ROM (ReadOnlyMany): allows multiple PVCs to bind as read only. Think of it along the lines of ISO media.&lt;/li&gt;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Note that a PV can only be opened in one of the modes above. All connecting PVC (if multiple are allowed) will use that mode.&lt;/p&gt;&#10;&lt;div class="wp-block-image"&gt;&lt;figure class="aligncenter"&gt;&lt;img decoding="async" src="https://github.com/kubernetes/community/raw/master/icons/png/resources/labeled/pvc-128.png" alt=""/&gt;&lt;figcaption&gt;Persistent Volume Claim&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Persistent Volume Claims (PVC) act like tickets that authorize applications (Pods) to use a PV. Once a Pod has the PVC, it can bind the respective PV as a volume. You need to specify PV name when declaring a PVC to associate them. Pods do not act directly on PVs, they always act on the PVC object that is bound to the PV. When a PVC is released, two actions can be configured in the policy: Delete and Retain. The delete policy will delete the PV as well as associated storage resource on the external storage system. The retain policy will keep the associated PV object on the cluster as well as any data stored on the associated external assets.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The spec section of PVC object declaration must match the fields in the corresponding PV it binds to. For example access modes, capacity and storage class name.&lt;/p&gt;&#10;&lt;div class="wp-block-image"&gt;&lt;figure class="aligncenter"&gt;&lt;img decoding="async" src="https://github.com/kubernetes/community/raw/master/icons/png/resources/labeled/sc-128.png" alt=""/&gt;&lt;figcaption&gt;Storage Class&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Storage classes allow you to define different classes (or tiers) of storage using an external provisioner such as aws-ebs. This works well with cloud storage provider. As long as the plugin for storage backend is available, you can configure as many StorageClass object as you need, and even specify to encrypt them. Storage classes create PV dynamically, so you will need to create PVC object that reference the newly created storage class, in order to use cloud storage.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The whole purpose of storage class is to create PVs dynamically, for various storage backend/plugin. You just create the StorageClass object and use a plugin to tie it to a particular type of storage on a particular storage back-end. When matching PVCs appear, the StorageClass dynamically creates the required volume on the back-end storage system.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;If a cluster has a default storage class, you can deploy a Pod using just PVC with PodSpec, without explicitly declare storage class per Pod. However, this is not recommended in production.&lt;/p&gt;&#10;&lt;div class="wp-block-image"&gt;&lt;figure class="aligncenter"&gt;&lt;img decoding="async" src="https://github.com/kubernetes/community/raw/master/icons/png/resources/labeled/cm-128.png" alt=""/&gt;&lt;figcaption&gt;ConfigMaps&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;With modern application it is a good practice to decouple configurations from application execution environment. They are stored separately but brought together at runtime. ConfigMap (CM) allows you to store configuration data outside of a Pod, and dynamically inject the configuration data into a Pod at runtime. ConfigMaps are essentially key/value pairs, and each key/value pair is called an entry.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Once data is stored in a ConfigMap, it can be injected into containers at run-time via one of the three methods:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&lt;li&gt;environment variables: updates to ConfigMap is not updated &lt;/li&gt;&lt;li&gt;arguments to the container&amp;#8217;s startup command (very limited)&lt;/li&gt;&lt;li&gt;files in a volume (most flexible): requires creating a ConfigMap volume in the Pod template and mounting. Eateries in the ConfigMap will appear in the container as individual files. You can make changes to entries after a container is deployed, and the change is seen in the file.&lt;/li&gt;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The application is unaware that the data originally came from a ConfigMap. Also note that ConfigMap is not to store sensitive data.&lt;/p&gt;&#10;&lt;div class="wp-block-image"&gt;&lt;figure class="aligncenter"&gt;&lt;img decoding="async" src="https://github.com/kubernetes/community/raw/master/icons/png/resources/labeled/secret-128.png" alt=""/&gt;&lt;figcaption&gt;Secret&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Kubernetes Secrets let you store and manage sensitive information, such as passwords, OAuth tokens, and ssh keys. Storing confidential information in a Secret is safer and more flexible than putting it verbatim in a Pod definition or in a container image.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The name of a Secret object must be a valid DNS subdomain name. A Secret can be used with a Pod in three ways:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&lt;li&gt;As files in a volume mounted on one or more of its containers.&lt;/li&gt;&lt;li&gt;As container environment variable.&lt;/li&gt;&lt;li&gt;By the kubelet when pulling images for the Pod.&lt;/li&gt;&lt;/ul&gt;&#10;&lt;div class="wp-block-image"&gt;&lt;figure class="aligncenter"&gt;&lt;img decoding="async" src="https://github.com/kubernetes/community/raw/master/icons/png/resources/labeled/ing-128.png" alt=""/&gt;&lt;figcaption&gt;Ingress&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Ingress manages manages external access to the services in a cluster, typically HTTP. It may provide load balancing, SSL termination and name-based virtual hosting. Also, you must have an Ingress controller to satisfy an Ingress. Only creating an Ingress resource has no effect.You can choose from a number of Ingress controllers. Nginx is a common flavour.&lt;/p&gt;&#10;&lt;div class="wp-block-image"&gt;&lt;figure class="aligncenter is-resized"&gt;&lt;img loading="lazy" decoding="async" src="https://github.com/kubernetes/community/raw/master/icons/png/resources/labeled/limits-128.png" alt="" width="128" height="124"/&gt;&lt;/figure&gt;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;By default, containers run with unbounded compute resources on a Kubernetes cluster. With resource quotas, cluster administrators can restrict resource consumption and creation on a namespace basis. Within a namespace, a Pod or Container can consume as much CPU and memory as defined by the namespace&amp;#8217;s resource quota. There is a concern that one Pod or Container could monopolize all available resources. A LimitRange is a policy to constrain resource allocations (to Pods or Containers) in a namespace.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;A LimitRange provides constraints that can:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&lt;li&gt;Enforce minimum and maximum compute resources usage per Pod or Container in a namespace.&lt;/li&gt;&lt;li&gt;Enforce minimum and maximum storage request per PersistentVolumeClaim in a namespace.&lt;/li&gt;&lt;li&gt;Enforce a ratio between request and limit for a resource in a namespace.&lt;br&gt;Set default request/limit for compute resources in a namespace and automatically inject them to Containers at runtime.&lt;/li&gt;&lt;/ul&gt;&#10;&lt;div class="wp-block-image"&gt;&lt;figure class="aligncenter"&gt;&lt;img decoding="async" src="https://github.com/kubernetes/community/raw/master/icons/png/resources/labeled/quota-128.png" alt=""/&gt;&lt;figcaption&gt;Resource Quotas&lt;/figcaption&gt;&lt;/figure&gt;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;When several users or teams share a cluster with a fixed number of nodes, there is a concern that one team could use more than its fair share of resources. Resource quotas are a tool for administrators to address this concern.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;A resource quota, defined by a ResourceQuota object, provides constraints that limit aggregate resource consumption per namespace. It can limit the quantity of objects that can be created in a namespace by type, as well as the total amount of compute resources that may be consumed by resources in that namespace.&lt;/p&gt;&#10;&lt;nav class="wp-post-navigation" aria-label="Post navigation"&gt;&#10;&lt;a rel="prev" href="https://static.digihunch.com/2021/01/a-shallow-dive-into-artificial-intelligence/"&gt;&lt;span class="wp-post-navigation-label"&gt;Previous Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;A shallow dive into Artificial Intelligence&lt;/strong&gt;&lt;/a&gt;&#10;&lt;a rel="next" href="https://static.digihunch.com/2021/02/interpret-census-data-from-statistics-canada/"&gt;&lt;span class="wp-post-navigation-label"&gt;Next Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;Census Data from Statistics Canada&lt;/strong&gt;&lt;/a&gt;&#10;&lt;/nav&gt;&#10;</description></item><item><title>Docker storage</title><link>https://static.digihunch.com/2020/11/docker-storage/</link><pubDate>Tue, 03 Nov 2020 20:22:00 -0400</pubDate><guid>https://static.digihunch.com/2020/11/docker-storage/</guid><description>&lt;p class="wp-block-paragraph"&gt;Microservices are all about stateless and ephemeral workloads, and containers are great microservices. This may suggest that that Docker is all about ephemeral storage. In fact, Docker supports both non-persistent and persistent storage, such as database, kafka, etc. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Non-persistent storage is automatically created, alongside the container and is tied to the lifecycle of the container. On Linux system, it is /var/lib/docker/ as part of container. This is referred to as local storage.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Docker has a concept of volume, which is essentially a file or a directory. Volumes are for persistent data. they are de-coupled from containers and are not tied to the lifecycle of any container. Volume allows process in docker container to bypass the default uionFS, and stores file or directory on host machine. It also allows different containers to share data. You may mount a volume to a container. even if container is deleted, volume persists.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;By default, Docker creates new volumes with the built-in local driver. Local volumes are only available to containers on the node they&amp;#8217;re created on. There are also third-party drivers as plugins that provides advanced options to integrate external storage system with Docker. (NAS, SAN, etc)&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;There are more than 25 volume plugins that you can specify with -d switch, to cover all three categories of storage&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;Block storage tends to be high performance and good for small-block random access workloads.&lt;/li&gt;&#10;&lt;li&gt;File storage is high performance, shared amongs multiple containers with NFS or SMB protocols.&lt;/li&gt;&#10;&lt;li&gt;Object storage is good for long term storage of large data blobs that do not change frequently. It is often content addressable and relatively low performance.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Note that if you share volume with multiple containers, the application needs to worry about data collision.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;You may use docker volume create command to create volume. Note that there is no quota management within docker so the partition needs to be managed at operating system level.&lt;/p&gt;&#10;&lt;h3 class="wp-block-heading"&gt;Implementation of Volume&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Remember that Docker image is built on multi-layer file system. When we run a container, Docker places a read-write layer on top of the image, such that the active files in running container are all placed in this read-write layer. When container is deleted, so are the files. The file system in Docker is a pseudo file system implemented in unionFS. Volumes bypasses the uionFS and directly accesses the host file system. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;When we create a Docker volume, Docker places the volume data to /var/lib/docker/volumes and under each directory named after volume, creates a directory _data, which is attached to the corresponding container.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;You can even mount an NFS volume to container. Reference &lt;a href="https://forums.docker.com/t/nfs-mount-inside-docker-container-bypassing-the-host/77890" class="rank-math-link"&gt;here&lt;/a&gt;.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;We mentioned UnionFS a couple times so far. UnionFS is a light-weight, layered file system. It can mount the contents of multiple directories to the same directory, to form a single file system. User can use unionFS like a directory. It is the foundation of Docker image and container and enables saving of spaces.&lt;/p&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter size-large is-resized"&gt;&lt;img loading="lazy" decoding="async" width="1024" height="444" src="https://static.digihunch.com/wp-content/uploads/2024/07/unionfs-1024x444.png" alt="" class="wp-image-11424" style="width:526px;height:auto" srcset="https://static.digihunch.com/wp-content/uploads/2024/07/unionfs-1024x444.png 1024w, https://static.digihunch.com/wp-content/uploads/2024/07/unionfs-300x130.png 300w, https://static.digihunch.com/wp-content/uploads/2024/07/unionfs-768x333.png 768w, https://static.digihunch.com/wp-content/uploads/2024/07/unionfs.png 1380w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;There are three common types of union FS: AUFS, DeviceMapper, and OverlayFS.&lt;/p&gt;&#10;&lt;h3 class="wp-block-heading"&gt;AUFS file system&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;AUFS is the earliest driver that Docker uses for file system, most common in Ubuntu and Debian. To check if the system support AUFS, check out the documentation &lt;a href="https://docs.docker.com/storage/storagedriver/aufs-driver/" class="rank-math-link"&gt;here&lt;/a&gt;.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;AUFS is recommended in Ubuntu or Debian. For CentOS and Redhat, it needs to be installed and make sure the command above returns aufs. To configure AUFS, create file /etc/docker/daemon.json and add:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;storage-driver&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;aufs&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;Then restart docker service. Run &amp;#8220;docker info&amp;#8221; and examine the Storage Driver section, as documented &lt;a href="https://docs.docker.com/storage/storagedriver/aufs-driver/" class="rank-math-link"&gt;here&lt;/a&gt;. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;AUFS layers multiple directories on a single Linux host and presents them as a single directory. These directories are called branches in AUFS terminology, and layers in Docker terminology. The unification process is referred to as a union mount.&lt;/p&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter size-full is-resized"&gt;&lt;img loading="lazy" decoding="async" width="884" height="724" src="https://static.digihunch.com/wp-content/uploads/2024/07/ubuntu-layers.png" alt="" class="wp-image-11425" style="width:538px;height:auto" srcset="https://static.digihunch.com/wp-content/uploads/2024/07/ubuntu-layers.png 884w, https://static.digihunch.com/wp-content/uploads/2024/07/ubuntu-layers-300x246.png 300w, https://static.digihunch.com/wp-content/uploads/2024/07/ubuntu-layers-768x629.png 768w" sizes="auto, (max-width: 884px) 100vw, 884px" /&gt;&lt;figcaption class="wp-element-caption"&gt;Layers of a Ubuntu container&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt; &lt;a href="https://docs.docker.com/storage/storagedriver/aufs-driver/#example-image-and-container-on-disk-constructs" class="rank-math-link"&gt;This section&lt;/a&gt; describes how the layers work and &lt;a href="https://docs.docker.com/storage/storagedriver/aufs-driver/#how-container-reads-and-writes-work-with-aufs" class="rank-math-link"&gt;this section&lt;/a&gt; describes how it reads and writes files (Copy-on-Write (CoW) strategy to maximize storage efficiency and minimize overhead). CoW characterized AUFS.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;AUFS has not been adopted in the Linux kernel mainline for lack of maintainability. So for CentOS, the recommended file system driver is devicemapper.&lt;/p&gt;&#10;&lt;h3 class="wp-block-heading"&gt;Devicemapper file system&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Devicemapper is a technical framework to map physical block device to virtual block device, introduced since kernel 2.6.9. So it&amp;#8217;s essentially different from AUFS. The Logical Volume Manager (LVM) in Linux is also implemented based on devicemapper.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The three critical components in devicemapper are:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;mapped device: a virtual device that devicemapper provides to client&lt;/li&gt;&#10;&lt;li&gt;target device: the underlying physical device or a section of it.&lt;/li&gt;&#10;&lt;li&gt;map table: keeps track of the offset, range, etc between mapped and target devices.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Devicemapper uses target driver to block, filter, and forward I/O requests (e.g. Raid, encryption, think provisioning, etc). In thin provisioning, storage driver only assigns spaces that are needed. Docker uses snapshot technology in thin provisioning. This &lt;a class="rank-math-link" href="https://docs.docker.com/storage/storagedriver/device-mapper-driver/#how-the-devicemapper-storage-driver-works"&gt;part of the documentation&lt;/a&gt; provides further details as to how device mapper works.&lt;/p&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter size-large is-resized"&gt;&lt;img loading="lazy" decoding="async" width="854" height="1024" src="https://static.digihunch.com/wp-content/uploads/2025/04/ubuntu-busybox-layer-854x1024.webp" alt="" class="wp-image-13114" style="width:539px;height:auto" srcset="https://static.digihunch.com/wp-content/uploads/2025/04/ubuntu-busybox-layer-854x1024.webp 854w, https://static.digihunch.com/wp-content/uploads/2025/04/ubuntu-busybox-layer-250x300.webp 250w, https://static.digihunch.com/wp-content/uploads/2025/04/ubuntu-busybox-layer-768x921.webp 768w, https://static.digihunch.com/wp-content/uploads/2025/04/ubuntu-busybox-layer.webp 1046w" sizes="auto, (max-width: 854px) 100vw, 854px" /&gt;&lt;figcaption class="wp-element-caption"&gt;Ubuntu and busybox image layers&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Devicemapper has to modes:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;loop-lvm: in dev and test environment&lt;/li&gt;&#10;&lt;li&gt;direct-lvm: recommended in production&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Here is the performance &lt;a href="https://docs.docker.com/storage/storagedriver/device-mapper-driver/#device-mapper-and-docker-performance" class="rank-math-link"&gt;best practice&lt;/a&gt;. To configure devicemapper, create /etc/docker/daemon.json file and add:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;storage-driver&amp;#34;:&amp;#34;devicemapper&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;storage-opts&amp;#34;:[&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;dm.directlvm_device=/dev/xdf&amp;#34;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;dm.thinp_percent=95&amp;#34;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;dm.thinp_metapercent=1&amp;#34;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;dm.thinp_autoextend_threshold=80&amp;#34;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;dm.thinp_autoextend_percent=20&amp;#34;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;#34;dm.directlvm_device_force=false&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ]&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;Then restart docker service. Run &amp;#8220;docker info&amp;#8221; and examine the Storage Driver section to ensure direct-lvm mode is on. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Since devicemapper uses block device to store files, it is faster than directly operate on file system. It is adopted as default driver as unionFS for a long time, ensuring stable performance under Red Hat and CentOS.&lt;/p&gt;&#10;&lt;h3 class="wp-block-heading"&gt;OverlayFS file system&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Earlier versions of OverlayFS (known as overlay driver) is not stable. Later version is known as overlay2, which is very stable and recommended in overlay2. It requires:&lt;/p&gt;&#10;&lt;ol class="wp-block-list"&gt;&#10;&lt;li&gt;Docker version higher than 17.06.02;&lt;/li&gt;&#10;&lt;li&gt;Kernel version higher than 3.10.0-514 for CentOS and RHEL; or higher than 4.0 for other distributions of Linux;&lt;/li&gt;&#10;&lt;li&gt;Using with xfs file system with d_type turned on&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p class="wp-block-paragraph"&gt;In production environment, it is recommended to moutn /var/lib/docker to separate disk or partition, to prevent the directory getting full from impacting the host OS. The option pquota is recommended for mounting options in /etc/fstab.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;To configure storage driver, create file /etc/docker/daemon.json, with the following content:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-java" data-lang="java"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;storage-driver&amp;#34;&lt;/span&gt;:&lt;span style="color:#e6db74"&gt;&amp;#34;overlay2&amp;#34;&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;storage-opts&amp;#34;&lt;/span&gt;:&lt;span style="color:#f92672"&gt;[&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;overlay2.size=20G&amp;#34;&lt;/span&gt;,&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;overlay2.override_kernel_check=true&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;]&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;Then restart docker service. Run &amp;#8220;docker info&amp;#8221; and examine the Storage Driver section to ensure storage driver is overlay2 and d_type is true.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The way overlay2 works is similar to AUFS, involving union mount process, with lowerdir, upperdir and merged. More details are &lt;a href="https://docs.docker.com/storage/storagedriver/overlayfs-driver/#how-the-overlay2-driver-works" class="rank-math-link"&gt;here&lt;/a&gt;, including &lt;a href="https://docs.docker.com/storage/storagedriver/overlayfs-driver/#how-the-overlay-driver-works" class="rank-math-link"&gt;how overlay2 works&lt;/a&gt; with file read and file write (e.g. CopyOnWrite).&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Today, overlay2 driver is officially recommended by Docker for its stability and performance, it should be used if all the conditions are met.&lt;/p&gt;&#10;&lt;nav class="wp-post-navigation" aria-label="Post navigation"&gt;&#10;&lt;a rel="prev" href="https://static.digihunch.com/2020/10/docker-under-the-hood/"&gt;&lt;span class="wp-post-navigation-label"&gt;Previous Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;Docker components&lt;/strong&gt;&lt;/a&gt;&#10;&lt;a rel="next" href="https://static.digihunch.com/2020/11/medical-imaging-web-server-deployment-pipeline/"&gt;&lt;span class="wp-post-navigation-label"&gt;Next Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;Automatic deployment of Orthanc on AWS&lt;/strong&gt;&lt;/a&gt;&#10;&lt;/nav&gt;&#10;</description></item></channel></rss>