<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>iscsi on Digi Hunch</title><link>https://static.digihunch.com/tag/iscsi/</link><description>Recent content in iscsi on Digi Hunch</description><generator>Hugo -- gohugo.io</generator><language>en-US</language><lastBuildDate>Mon, 28 Apr 2025 14:08:06 -0400</lastBuildDate><atom:link href="https://static.digihunch.com/tag/iscsi/index.xml" rel="self" type="application/rss+xml"/><item><title>Kubernetes Storage Explained – from in-tree plugin to CSI</title><link>https://static.digihunch.com/2021/06/kubernetes-storage-explained/</link><pubDate>Sat, 12 Jun 2021 21:55:46 -0400</pubDate><guid>https://static.digihunch.com/2021/06/kubernetes-storage-explained/</guid><description>&lt;img src="https://static.digihunch.com/wp-content/uploads/2025/04/feature-k8s-csi.webp" alt="Featured image of post Kubernetes Storage Explained – from in-tree plugin to CSI" /&gt;&lt;p class="wp-block-paragraph"&gt;To support a variety of storage backend, Kubernetes abstract storage issues with several objects (&lt;a href="https://kubernetes.io/docs/concepts/storage/volumes/"&gt;volume&lt;/a&gt;, &lt;a href="https://kubernetes.io/docs/concepts/storage/persistent-volumes/"&gt;persistent volume&lt;/a&gt;, &lt;a href="https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims"&gt;persistent volume claim&lt;/a&gt;, &lt;a href="https://kubernetes.io/docs/concepts/storage/storage-classes/"&gt;storage class&lt;/a&gt;) and adopts &lt;a href="https://github.com/container-storage-interface/spec/blob/master/spec.md"&gt;container storage interface&lt;/a&gt;. Unfortunately, the documents are not very well organized to deliver the idea of these concepts, most likely because features are introduced at very different times. Hence this article. At the bottom of this article, I also go through five examples of using volumes in different ways, taking azure disk (SSD as an example).&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The first to think about is whether we need just ephemeral storage or persistent storage. Generic volume with ephemeral storage lives and dies with the Pod and we don&amp;#8217;t really care where it is from. With persistent storage, we need to consider where it is from and how to create (provision) the storage. The storage can be created statically or dynamically.&lt;/p&gt;&#10;&lt;h3 class="wp-block-heading" id="h-persistentvolume-pv-and-persistentvolumeclaim-pvc"&gt;PersistentVolume (PV) and PersistentVolumeClaim (PVC)&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Regardlessly of static or dynamic storage provision, we first need to understand two objects before getting to that: Persistent Volume (PV) and Persistent Volume Claim (PVC). &lt;/p&gt;&#10;&lt;ol class="wp-block-list"&gt;&#10;&lt;li&gt;We use PV object to represent external storage volume. A single external storage volume can be represented by a single PV. So PV goes with external volumes in 1 to 1 relationship. A 100G volume cannot be represented by two PVs each with 50G, unless the storage administrator divides it into two separate volumes, each with 50G.&lt;/li&gt;&#10;&lt;li&gt;PVC goes with Pod in 1 to 1 relationship. The Pods needs a PVC in order to claim ownership of a PV. A valid PVC allows a Pod to mount a PV as its volume.&lt;/li&gt;&#10;&lt;li&gt;Here we call storage volume external in relative to the pods. If the storage volume is mapped to a directory on the host file system, it is still considered an external storage.&lt;/li&gt;&#10;&lt;li&gt;A single PV can link to multiple PVCs, so long as the total request in PVCs does not exceed PV&amp;#8217;s capacity. So PV and PVC are in 1 to many relationship.&lt;/li&gt;&#10;&lt;li&gt;How PVC binds to PV is defined by Access Mode, with three options. Note that the options are effective for the entire PV. You cannot have different options for each PVC linked to a PV:&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;RWO (ReadWriteOnce): allowing the PV to be bound to a single PVC (for read write). This mode is typically used in block storage;&lt;/li&gt;&#10;&lt;li&gt;RWM (ReadWriteMany): allowing the PV to be bound to multiple PVCs (for read write). This mode is only supported by file (e.g. NFS) and object storage;&lt;/li&gt;&#10;&lt;li&gt;ROM (ReadOnlyMany): allowing the PV bound to multiple PVCs for read only.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;When a PVC is released, what to do with the PV is defined as persistentVolumeReclaimPolicy, and the two options (effective at PV level) are:&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;Delete&lt;/li&gt;&#10;&lt;li&gt;Retain&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;h3 class="wp-block-heading" id="h-static-provisioning-and-dynamic-provisioning"&gt;Static Provisioning and Dynamic Provisioning&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;With static provisioning, the external storage volume must be pre-created. In this context, a PV object represents a pre-created external storage volume. So PVs must be explicit declared. The K8s literature also refers to such PVs as pre-created PV.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;With dynamic provisioning, the external storage volume is provisioned dynamically. Therefore, you do not need to explicitly create PVs. By the same token, access mode does not apply. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Instead of PV, now we need to explicitly declare storage class, which specifies how to dynamically provision PVs, with the following properties:&lt;/p&gt;&#10;&lt;ol class="wp-block-list"&gt;&#10;&lt;li&gt;volumeBindingMode defines when the binding and provisioning of a PersistentVolume occurs, with two options:&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;Immediate (default)&lt;/li&gt;&#10;&lt;li&gt;WaitForFirstConsumer (recommended): delays until a Pod using the PVC is created&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;reclaimPolicy (the equivalent of persistentVolumeReclaimPolicy for pre-created PV) with two options:&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;Delete (default)&lt;/li&gt;&#10;&lt;li&gt;Retain&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;provisioners: determines what volume plugin is used for provisioning PVs. There are two categories:&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;&lt;strong&gt;Internal provisioner &lt;/strong&gt;(prefixed with kubernetes.io): common ones are listed &lt;a href="https://kubernetes.io/docs/concepts/storage/storage-classes/#provisioner"&gt;here&lt;/a&gt;. Note that there isn&amp;#8217;t an internal &lt;a href="https://github.com/kubernetes-retired/external-storage"&gt;provisioner for NFS &lt;/a&gt;any more. External NFS provisioner is needed.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;External provisioner&lt;/strong&gt;: third-party out-of-tree plugins compliant to CSI. For example: Dell &lt;a href="https://github.com/dell/csi-xtremio-deploy"&gt;XtremIO&lt;/a&gt; CSI plugin, Dell &lt;a href="https://github.com/dell/csi-powerscale"&gt;Isilon&lt;/a&gt; plugin, &lt;a href="https://github.com/purestorage/pso-csi"&gt;PureStorage&lt;/a&gt; CSI driver, Scality &lt;a href="file:///Users/yi.lu/Downloads/artesca_wp_v4.pdf"&gt;Artesca&lt;/a&gt; (launched in Apr 2021), and NetApp &lt;a href="https://netapp-trident.readthedocs.io/en/stable-v19.01/index.html"&gt;Trident&lt;/a&gt; CSI drivers, and &lt;a href="https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner"&gt;NFS subdir provisioner&lt;/a&gt; in Kubernetes-sigs repo.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://kubernetes.io/docs/concepts/storage/storage-classes/#parameters"&gt;parameters&lt;/a&gt;: each provisioner has its own set of mandatory and optional parameters;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://kubernetes.io/docs/concepts/storage/storage-classes/#allow-volume-expansion"&gt;allowVolumeExpansion&lt;/a&gt;: can be set to true if the underlying storage class supports volume expansion;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://kubernetes.io/docs/concepts/storage/storage-classes/#mount-options"&gt;mountOptions&lt;/a&gt;: specify only if the storage class supports it;&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p class="wp-block-paragraph"&gt;With the information above, we can simplify the rules as follows:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;In static provisioning, PV needs to be declared explicitly and SC is not needed&lt;/li&gt;&#10;&lt;li&gt;In dynamic provisioning, SC is required so we can specify provisioner and the parameters needed by the provisioner. PV doesn&amp;#8217;t need to be explicitly declared, even though it exists in the interaction.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;In real life however, you might come across the following edge cases which seems to contradict with the two generic rules above:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;&lt;a href="https://kubernetes.io/docs/concepts/storage/storage-classes/#local"&gt;Local volume&lt;/a&gt;, currently does not support dynamic provisioning. However a StorageClass should still be created to delay volume binding until Pod scheduling. The volume binding mode &lt;em&gt;WaitForFirstConsumer&lt;/em&gt;&amp;nbsp;should be specified.&lt;/li&gt;&#10;&lt;li&gt;In dynamic provisioning, if a PVC does not explicitly define PVC, the administrator should have specified a &lt;a href="https://kubernetes.io/docs/concepts/storage/persistent-volumes/#dynamic"&gt;default StorageClass&lt;/a&gt; in place for the cluster. You might also come across PVC with empty string (&amp;#8220;&amp;#8221;) as storageClassName, which indicates that &lt;span style="text-decoration: underline;"&gt;no storage class will be used&lt;/span&gt; (i.e. dynamic provisioning is disabled for the PVC). According to &lt;a href="https://kubernetes.io/blog/2017/03/dynamic-provisioning-and-storage-classes-kubernetes/"&gt;this&lt;/a&gt; post, in a PVC:&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;If storageClassName=&amp;#8221;&amp;#8221;, then it is static provisioning&lt;/li&gt;&#10;&lt;li&gt;If storageClassName is not specified, then the default storage class will be used. &lt;/li&gt;&#10;&lt;li&gt;If storageClassName is set to a specific value, then the matching storageClassName will be considered. If no corresponding storage class exists, the PVC will fail.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 class="wp-block-heading" id="h-the-confusing-volumes"&gt;The confusing &amp;#8220;Volumes&amp;#8221;&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;We&amp;#8217;ve discussed PersistentVolume, which is a K8s object that represents an external storage volume. When the word Volume stands by itself, it generally refers to the part of storage exposed to the Kubernetes cluster, no matter what type of storage it is or where it comes from. We can distinguish them in the following table:&lt;/p&gt;&#10;&lt;figure class="wp-block-table is-style-regular"&gt;&lt;table class="has-background" style="background-color:#e9fbe5"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;td&gt;Generic &lt;strong&gt;Volumes&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Persistent Volumes&lt;/strong&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Pod assignment&lt;/td&gt;&lt;td&gt;Bound to a single pod, declared as part of a Pod.&lt;/td&gt;&lt;td&gt;A standalone resource type decoupled from Pod and can be bound to single, or multiple Pods via PVC&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Lifecycle&lt;/td&gt;&lt;td&gt;Volume is deleted as the owner Pod dies. Data on the volume may or may not persist.&lt;/td&gt;&lt;td&gt;Assuming PVC is gone with Pod, the PV persists. Data on PV may or may not persist depending on ReclaimPolicy.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Configuration&lt;/td&gt;&lt;td&gt;Pod creator (e.g. app developer) needs to know the details of storage resource in the cloud environment. (e.g volume ID)&lt;/td&gt;&lt;td&gt;Pod creator does not need the details of storage resource in the cloud environment. K8s Cluster administrator can provision PV, either statically or dynamically for Pod creator.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/figure&gt;&#10;&lt;p class="wp-block-paragraph"&gt;If you want to use PeristentVolume to back a Volume in Pod, you&amp;#8217;d have to use PersistentVolumeClaim. This means, some types of volumes (including hostPath) can be both mounted as a persistent volume as well as a regular volume. To compare the two ways of mount volume (direct vs via PVC), we take a look at the Kubernetes configuration &lt;a href="https://github.com/kubernetes/examples/tree/master/staging/volumes/azure_disk"&gt;examples&lt;/a&gt; for Azure Disk. The examples are provided at the bottom of this post. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Note that, no matter which method of using the volumes, some types of volumes just work natively, and some requires plugin to operate. The table below summarizes the mechanism behind common volume types.&lt;/p&gt;&#10;&lt;figure class="wp-block-table is-style-regular"&gt;&lt;table class="has-background" style="background-color:#e9fbe5"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Volume Types&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;strong&gt;Mechanism&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Mountable as &lt;strong&gt;non-persistent volume&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;mountable as &lt;strong&gt;persistent volume&lt;/strong&gt; (through PVC or SC)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;emptyDir &lt;/td&gt;&lt;td&gt;A native volume type, for temporary data only. Data is wiped along with volume. The storage media is determined by the medium of the filsystem holding the kubelet root dir (typically /var/lib/kubelet). You can even set emptyDir.medium to &amp;#8220;Memory&amp;#8221;&lt;/td&gt;&lt;td&gt;YES&lt;/td&gt;&lt;td&gt;NO. By definition, emptyDir is not persistent.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;ConfigMap, Secret&lt;/td&gt;&lt;td&gt;Native volume type to store non-sensitive or sensitive configuration data. ConfigMap and Secrets are stored in etcd.&lt;/td&gt;&lt;td&gt;YES&lt;/td&gt;&lt;td&gt;NO. However, by nature, ConfigMap and Secret are stored persistently. There is no need to mount them as PV.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;HostPath&lt;/td&gt;&lt;td&gt;A native volume type to mount a file or directory from the host node&amp;#8217;s filesystem into the Pod. In addition to path property, you may optionally specify a type for a hostPath volume (e.g. DirectoryOrCreate, Directory, FileOrCreate, etc). Note that there is also a type named empty string (&amp;#8220;&amp;#8221;) which is the default value. It means means that no checks will be performed before mounting the hostPath volume. &lt;br&gt;In addition to the &lt;a href="https://kubernetes.io/docs/concepts/storage/volumes/#hostpath"&gt;caveat&lt;/a&gt; with using hostPath from the documentation, we also need to understand that: &lt;br&gt;1. HostPath gives Pod the ability to maliciously modify files on the host system, or simply fill up the host file system;&lt;br&gt;2. As the document suggests, you may end up with multiple Pods trying to write simultaneously to a host path.&lt;/td&gt;&lt;td&gt;YES. Read &lt;a href="https://kubernetes.io/docs/concepts/storage/volumes/#hostpath"&gt;this&lt;/a&gt;.&lt;/td&gt;&lt;td&gt;YES. Check out &lt;a href="https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumes-typed-hostpath"&gt;PersistentVolumes typed hostPath&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Local&lt;/td&gt;&lt;td&gt;It represents a mounted local storage device such as a disk, partition, or directory. Compared to hostPath volumes, local volumes are used in a durable and portable manner, without manually scheduling pods to nodes. The system is aware of the volume&amp;#8217;s node constraints by looking at the node affinity on the PV. You must set nodeAffinity on the PV when using local volumes. This also means local volumes are subject to the availability of the underlying node. Refer to &lt;a href="https://kubernetes.io/blog/2019/04/04/kubernetes-1.14-local-persistent-volumes-ga/#how-is-it-different-from-a-hostpath-volume"&gt;this&lt;/a&gt; post.&lt;br&gt;This is also referred to as &lt;a href="https://kubernetes.io/blog/2019/04/04/kubernetes-1.14-local-persistent-volumes-ga/#what-is-a-local-persistent-volume"&gt;Local persistent Volume&lt;/a&gt;.&lt;/td&gt;&lt;td&gt;NO&lt;/td&gt;&lt;td&gt;YES. Static provisioning only. &lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;CephFS, NFS, GlusterFS, Ginder, RBD, FC, iSCSI&amp;#8230;&amp;#8230;&lt;/td&gt;&lt;td&gt;These volume types are backed by legacy in-tree plugins. They are used to connect to external storage in self-hosted clusters.&lt;/td&gt;&lt;td&gt;YES&lt;/td&gt;&lt;td&gt;YES&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;awsElasticBlockStore, AzureDisk, AzureFile, GCEPersistentDisk&lt;/td&gt;&lt;td&gt;These volume types are backed by legacy in-tree plugins. They are used to connect to external storage in public cloud&lt;/td&gt;&lt;td&gt;YES&lt;/td&gt;&lt;td&gt;YES&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/figure&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;strong&gt;Note&lt;/strong&gt; that the table above does not list &lt;a href="https://kubernetes.io/docs/concepts/storage/volumes/#persistentvolumeclaim"&gt;PersistenVolumeClaim&lt;/a&gt; as a volume type, because it obviously only support being mounted as persistent volume.&lt;/p&gt;&#10;&lt;h3 class="wp-block-heading" id="h-from-in-tree-plugins-to-out-of-tree-csi-plugins"&gt;From in-tree plugins to out-of-tree CSI plugins&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;In the table above, the bottom two rows involves in-tree plugins (aka built-in plugins). In-tree means the volume plugins are built in the Kubernetes code repository. They were built, linked, compiled, and shipped with the core Kubernetes binaries. There has been 20+ in-tree plugins. The problems of this plugin development model are:&lt;/p&gt;&#10;&lt;ol class="wp-block-list"&gt;&#10;&lt;li&gt;These in-tree plugins introduces risk to the stability of Kubernetes itself;&lt;/li&gt;&#10;&lt;li&gt;The maintenance and upgrade of plugin is tightly coupled with Kubernetes release&lt;/li&gt;&#10;&lt;li&gt;The Kubernetes community carries the burden of maintaining plugins for all storage backends.&lt;/li&gt;&#10;&lt;li&gt;Plugin developers have to open-source all their volume plugin code.&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The Kubernetes community seeks better alternatives, and has stopped accepting any more in-tree plugins since GA 1.8. The first alternative paradigm for shipping storage plugin, is &lt;a href="https://github.com/kubernetes/community/blob/master/contributors/devel/sig-storage/flexvolume.md"&gt;flexVolume&lt;/a&gt;, which existed since version 1.2. However, &lt;a href="https://github.com/kubernetes/community/blob/master/contributors/devel/sig-storage/flexvolume.md"&gt;flexVolume&lt;/a&gt; is still not good enough. For example, some packages like Ceph requires dependency package (ceph-common), and the deployment of plugin requires elevated access to the worker node. For that reason, the community later shifted to the Container Storage Interface (CSI) paradigm. A CSI-compliant plugin allows the storage resource to be surfaced as volumes (be it persistent or not) in Kubernetes cluster. More details in &lt;a href="https://kubernetes.io/blog/2019/01/15/container-storage-interface-ga/"&gt;this&lt;/a&gt; post and &lt;a href="https://kubernetes-csi.github.io/docs/drivers.html"&gt;here&lt;/a&gt; is a list of supported CSI-compliant drivers.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Back to our azure disk example, &lt;a href="https://github.com/kubernetes-sigs/azuredisk-csi-driver/blob/master/deploy/example/e2e_usage.md"&gt;this&lt;/a&gt; page provides examples for both dynamic and static provisioning.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;CSI-compliant plugin development is more complicate but it offloads it the driver developer. The community hopes users to shift to CSI so the 20+ grandfathered in-tree plugins can eventually be phased out. With that as the goal, there are several types of volumes with the name &amp;#8220;CSI migration&amp;#8221;, allowing users to migrate from in-tree volume plugins to CSI-based plugins.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;All the &lt;a href="https://kubernetes.io/docs/concepts/storage/volumes/#csi"&gt;CSI&lt;/a&gt;-based plugins are fairly recent. As of today, the document outlines three ways to use CSI volume in a Pod:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;through a reference to a PersistentVolumeClaim (examples 4 and 5 below)&lt;/li&gt;&#10;&lt;li&gt;with a &lt;a href="https://kubernetes.io/docs/concepts/storage/ephemeral-volumes/#generic-ephemeral-volume"&gt;generic ephemeral volume&lt;/a&gt; (alpha feature)&lt;/li&gt;&#10;&lt;li&gt;with a &lt;a href="https://kubernetes.io/docs/concepts/storage/ephemeral-volumes/#csi-ephemeral-volume"&gt;CSI ephemeral volume&lt;/a&gt; if the driver supports that (beta feature)&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h3 class="wp-block-heading" id="h-examples"&gt;Examples&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;We&amp;#8217;ll go over five examples, as listed in the able below. Note that out of all the combinations, you cannot mount a csi-based plugin as a volume. No such volume type supported by CSI exist.&lt;/p&gt;&#10;&lt;table id="tablepress-15" class="tablepress tablepress-id-15 tbody-has-connected-cells"&gt;&#10;&lt;thead&gt;&#10;&lt;tr class="row-1"&gt;&#10;&#9;&lt;th class="column-1"&gt;Plug-in mechanism&lt;/th&gt;&lt;th class="column-2"&gt;Mount method&lt;/th&gt;&lt;th class="column-3"&gt;Example&lt;/th&gt;&#10;&lt;/tr&gt;&#10;&lt;/thead&gt;&#10;&lt;tbody class="row-striping row-hover"&gt;&#10;&lt;tr class="row-2"&gt;&#10;&#9;&lt;td rowspan="3" class="column-1"&gt;In-tree legacy volume plug-in&lt;/td&gt;&lt;td class="column-2"&gt;as volume&lt;/td&gt;&lt;td class="column-3"&gt;#1. using azureDisk property of Volume&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr class="row-3"&gt;&#10;&#9;&lt;td class="column-2"&gt;as PV (static)&lt;/td&gt;&lt;td class="column-3"&gt;#2. using azureDisk property of PersistentVolume&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr class="row-4"&gt;&#10;&#9;&lt;td class="column-2"&gt;as PV (dynamic)&lt;/td&gt;&lt;td class="column-3"&gt;#3. using kubernetes.io/azure-disk as provisioner for SC&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr class="row-5"&gt;&#10;&#9;&lt;td rowspan="3" class="column-1"&gt;Out-of-tree CSI volume plugin&lt;/td&gt;&lt;td class="column-2"&gt;as volume&lt;/td&gt;&lt;td class="column-3"&gt;This mode does not exist. Example is not available&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr class="row-6"&gt;&#10;&#9;&lt;td class="column-2"&gt;as PV (static)&lt;/td&gt;&lt;td class="column-3"&gt;#4. using disk.csi.azure.com as csi driver of PV&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;tr class="row-7"&gt;&#10;&#9;&lt;td class="column-2"&gt;as PV (dynamic)&lt;/td&gt;&lt;td class="column-3"&gt;#5 using disk.csi.azure.com as provisioner for SC&lt;/td&gt;&#10;&lt;/tr&gt;&#10;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;!-- #tablepress-15 from cache --&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Now, let&amp;#8217;s take a look at the example code snippet. Some examples are from Azure &lt;a href="https://docs.microsoft.com/en-us/azure/aks/azure-disks-dynamic-pv"&gt;documentation&lt;/a&gt;. Some are from the &lt;a href="https://github.com/kubernetes-sigs/azuredisk-csi-driver/tree/master/deploy/example"&gt;azure-disk-csi-driver&lt;/a&gt; repository. I&amp;#8217;ve made minor modifications for conciseness.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Example 1 uses legacy in-tree plugin, and directly mount the volume. The example &lt;a href="https://github.com/kubernetes/examples/blob/master/staging/volumes/azure_disk/azure.yaml"&gt;code&lt;/a&gt; is in Kubernetes repo.&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;apiVersion: v1&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;kind: Pod&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;metadata:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; name: mypod&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;spec:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; containers:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - image: kubernetes/pause&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; name: mypod&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; volumeMounts:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - name: azure&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; mountPath: /mnt/azure&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; volumes:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - name: azure&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; azureDisk:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; kind: Managed&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; diskName: myAKSDisk&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; diskURI: /subscriptions/&amp;amp;lt;subscriptionID&amp;gt;/resourceGroups/MC_myAKSCluster_myAKSCluster_eastus/providers/Microsoft.Compute/disks/myAKSDisk&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;Example 2 uses legacy in-tree plugin, and mount the PV statically via PVC. No storage class is used (as indicated by empty string in storage class property)&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;apiVersion: v1&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;kind: PersistentVolume&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;metadata:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; name: azure-disk-pv&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;spec:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; capacity:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; storage: 2Gi&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; storageClassName: &amp;#34;&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; volumeMode: Filesystem&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; accessModes:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - ReadWriteOnce&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; azureDisk:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; kind: Managed&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; diskName: &amp;amp;lt;enter-disk-name&amp;gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; diskURI: &amp;amp;lt;enter-disk-resource-id&amp;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;span style="display:flex;"&gt;&lt;span&gt;apiVersion: v1&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;kind: PersistentVolumeClaim&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;metadata:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; name: azure-disk-pvc&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;spec:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; storageClassName: &amp;#34;&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; accessModes:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - ReadWriteOnce&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; resources:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; requests:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; storage: 2Gi&#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;apiVersion: apps/v1&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;kind: Pod&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;metadata:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; name: logz-deployment&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;spec:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; containers:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - name: pause&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; image: kubernetes/pause&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; volumeMounts:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - name: azure-disk-vol&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; mountPath: /mnt/logs&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; volumes:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - name: azure-disk-vol&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; persistentVolumeClaim:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; claimName: azure-disk-pvc&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;Example 3 uses legacy in-tree plugin, and mount the PV dynamically and implicitly via SC. Note that Azure AKS will create several SCs for you by default so use existing ones whenever available.&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;allowVolumeExpansion: true&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;apiVersion: storage.k8s.io/v1&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;kind: StorageClass&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;metadata:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; name: managed-premium&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;parameters:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cachingmode: ReadOnly&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; kind: Managed&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; storageaccounttype: Premium_LRS&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;provisioner: kubernetes.io/azure-disk&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;volumeBindingMode: WaitForFirstConsumer&#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;apiVersion: v1&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;kind: PersistentVolumeClaim&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;metadata:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; name: azure-managed-disk&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;spec:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; accessModes:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - ReadWriteOnce&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; storageClassName: managed-premium&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; resources:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; requests:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; storage: 5Gi&#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;kind: Pod&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;apiVersion: v1&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;metadata:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; name: mypod&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;spec:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; containers:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - name: mypod&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; image: kubernetes/pause&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; volumeMounts:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - mountPath: &amp;#34;/mnt/azure&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; name: volume&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; volumes:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - name: volume&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; persistentVolumeClaim:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; claimName: azure-managed-disk&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;Example 4 uses CSI-based plugin, and mount the PV statically via PVC&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;apiVersion: v1&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;kind: PersistentVolume&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;metadata:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; name: pv-azuredisk&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;spec:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; capacity:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; storage: 10Gi&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; accessModes:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - ReadWriteOnce&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; persistentVolumeReclaimPolicy: Retain&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; csi:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; driver: disk.csi.azure.com&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; readOnly: false&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; volumeHandle: /subscriptions/{sub-id}/resourcegroups/{group-name}/providers/microsoft.compute/disks/{disk-id}&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; volumeAttributes:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; fsType: ext4&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; partition: &amp;#34;1&amp;#34; # optional, remove this if there is no partition&#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;kind: PersistentVolumeClaim&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;apiVersion: v1&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;metadata:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; name: pvc-azuredisk&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;spec:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; accessModes:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - ReadWriteOnce&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; resources:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; requests:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; storage: 10Gi&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; volumeName: pv-azuredisk&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; storageClassName: &amp;#34;&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;kind: Pod&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;apiVersion: v1&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;metadata:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; name: nginx-azuredisk&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;spec:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; nodeSelector:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; kubernetes.io/os: linux&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; containers:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - image: kubernetes/pause&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; name: mypod&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; volumeMounts:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - name: azuredisk01&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; mountPath: &amp;#34;/mnt/azuredisk&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; volumes:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - name: azuredisk01&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; persistentVolumeClaim:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; claimName: pvc-azuredisk&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;Example 5 uses CSI-based plugin, and mount the PV dynamically and implicitly via SC&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;kind: StorageClass&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;apiVersion: storage.k8s.io/v1&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;metadata:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; name: azuredisk-csi-waitforfirstconsumer&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;provisioner: disk.csi.azure.com&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;parameters:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; skuname: StandardSSD_LRS &#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;allowVolumeExpansion: true&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;reclaimPolicy: Delete&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;volumeBindingMode: WaitForFirstConsumer&#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;apiVersion: v1&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;kind: PersistentVolumeClaim&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;metadata:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; name: pvc-azuredisk&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;spec:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; accessModes:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - ReadWriteOnce&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; resources:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; requests:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; storage: 10Gi&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; storageClassName: managed-csi&#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;kind: Pod&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;apiVersion: v1&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;metadata:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; name: nginx-azuredisk&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;spec:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; nodeSelector:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; kubernetes.io/os: linux&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; containers:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - image: kubernetes/pause&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; name: mypod&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; volumeMounts:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - name: azuredisk01&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; mountPath: &amp;#34;/mnt/azuredisk&amp;#34;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; volumes:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; - name: azuredisk01&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; persistentVolumeClaim:&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; claimName: pvc-azuredisk&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 class="wp-block-heading" id="h-bottomline"&gt; Bottomline&lt;/h3&gt;&#10;&lt;p class="wp-block-paragraph"&gt;As of June 2021, the CSI support is still new. Generally, if a CSI-based plugin is available and in GA, you should consider using it. If you have existing legacy volume types using in-tree plugin, you should consider migration, and create a migration plan. Also, try to avoid the use case of mounting as generic volume (without PVC) because it is rare and not supported with CSI drivers. Without PVC, it also cannot take advantage of the &lt;strong&gt;volumeClaimTemplates&lt;/strong&gt; property in StatefulSet object.&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/05/getting-started-with-github-actions/"&gt;&lt;span class="wp-post-navigation-label"&gt;Previous Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;Getting started with GitHub Actions&lt;/strong&gt;&lt;/a&gt;&#10;&lt;a rel="next" href="https://static.digihunch.com/2021/06/kubernetes-networking-solutions-overview/"&gt;&lt;span class="wp-post-navigation-label"&gt;Next Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;Kubernetes Networking Solutions Overview&lt;/strong&gt;&lt;/a&gt;&#10;&lt;/nav&gt;&#10;</description></item><item><title>Storage Nitty-Gritty 2 of 5 – SAN</title><link>https://static.digihunch.com/2019/05/storage-nitty-gritty-2-5/</link><pubDate>Mon, 06 May 2019 22:06:02 -0400</pubDate><guid>https://static.digihunch.com/2019/05/storage-nitty-gritty-2-5/</guid><description>&lt;p class="wp-block-paragraph"&gt;In &lt;strong&gt;direct attached storage (DAS)&lt;/strong&gt;, storage is server centric and the host owns the storage. The storage is fully dedicated to the server that owns it.&lt;/p&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter is-resized"&gt;&lt;img loading="lazy" decoding="async" src="https://static.digihunch.com/wp-content/uploads/2019/11/image-20.png" alt="" class="wp-image-353" width="346" height="122"/&gt;&lt;figcaption class="wp-element-caption"&gt;With DAS, storage is server-centric&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Storage has evolved into information centric model. In this model, when a new server is deployed in the environment, storage is assigned from the same shared storage pool to the new server.&lt;/p&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter is-resized"&gt;&lt;img loading="lazy" decoding="async" src="https://static.digihunch.com/wp-content/uploads/2019/11/image-21.png" alt="" class="wp-image-354" width="332" height="329"/&gt;&lt;figcaption class="wp-element-caption"&gt;Network based centralized storage solution&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;A network-based storage solution is the centralized storage pool. No single host owns the entire storage pool. The storage solution consists of two categories based on the interface with the host: &lt;strong&gt;SAN (storage area network)&lt;/strong&gt; and &lt;strong&gt;NAS (network attached storage)&lt;/strong&gt;. To a client OS on the host, SAN typically appears as a local disk, allowing block-level access from the client OS, and therefore is more suited for structured workload such as database storage. It operates on its own storage network independent of the host network. NAS on the other hand, typically appears as a file share to the client OS, identified by an IP address and path. This is because NAS operates on the same TCP/IP network where the hosts are operated on. The client has file level access to storage, therefore NAS is better for unstructured data such as video and medical images. It is very important to understand the difference between SAN and NAS.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;SAN deployment consists of two categories based on the connection technology. FC SAN is based on Fibre Channel network; and IP SAN is based on Internet protocol (iSCSI, FCIP, FCoE).&lt;/p&gt;&#10;&lt;h4 class="wp-block-heading" id="h-fibre-channel-san"&gt;&lt;strong&gt;Fibre Channel SAN&lt;/strong&gt;&lt;/h4&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;Cable types: &lt;strong&gt;MMF&lt;/strong&gt; (multimode fibre, usually for short distance within data centre because of signal attenuation due to modal dispersion) and &lt;strong&gt;SMF&lt;/strong&gt; (single mode fibre, carries a single ray of light, used for long-distance cable runs;&lt;/li&gt;&#10;&lt;li&gt;Connector: standard connector (SC), lucent connector (LC) and straight tip connector (ST);&lt;/li&gt;&#10;&lt;li&gt;Interconnect device&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;FC hub &amp;#8211; for FC-AL implementation, but no longer in use&lt;/li&gt;&#10;&lt;li&gt;FC switch &amp;#8211; directly route data from one physical port to another (more intelligent than hub)&lt;/li&gt;&#10;&lt;li&gt;Director &amp;#8211; high end switches with redundant components to provide high availability&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;FC connectivity&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;point-to-point: two devices connected directly to each other;&lt;/li&gt;&#10;&lt;li&gt;arbitrated loop (FC-AL): devices are attached to a shared loop;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter is-resized"&gt;&lt;img loading="lazy" decoding="async" src="https://static.digihunch.com/wp-content/uploads/2019/11/image-23.png" alt="" class="wp-image-356" width="349" height="256"/&gt;&lt;figcaption class="wp-element-caption"&gt;FC- AL (rarely used today)&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;switched fabric (FC-SW): uses switches that can switch data traffic between nodes directly through switch ports. Frames are routed between source and destination by the fabric&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter is-resized"&gt;&lt;img loading="lazy" decoding="async" src="https://static.digihunch.com/wp-content/uploads/2019/11/image-22.png" alt="" class="wp-image-355" width="458" height="357"/&gt;&lt;figcaption class="wp-element-caption"&gt;Fibre Channel Switched Fabric&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;Protocol: &lt;strong&gt;Fibre Channel Protocol (FCP)&lt;/strong&gt;: defines protocol stack (five layers, FC-0 through FC-4), addressing, identification (world wide name), frame, data structure, flow control, fabric services&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter is-resized"&gt;&lt;img loading="lazy" decoding="async" src="https://static.digihunch.com/wp-content/uploads/2019/11/image-24.png" alt="" class="wp-image-357" width="382" height="231"/&gt;&lt;figcaption class="wp-element-caption"&gt;Fibre Channel Protocol stack&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter is-resized"&gt;&lt;img loading="lazy" decoding="async" src="https://static.digihunch.com/wp-content/uploads/2019/11/image-25.png" alt="" class="wp-image-358" width="370" height="184"/&gt;&lt;figcaption class="wp-element-caption"&gt;FC frame&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;Topology: mesh topology and core-edge fabric topology&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Block-level virtualization&lt;/strong&gt;: aggregates block storage devices (LUNs) and enables provisioning of virtual storage volumes, independent of underlying physical storage. The virtualization layer maps the virtual volumes to the LUNs on the individual arrays. &lt;span style="text-decoration: underline;"&gt;Block-level storage virtualization not only enables extending the storage volumes online; it consolidates heterogeneous storage arrays and enables transparent volume access. It also provides the advantage of non-disruptive data migration, where the virtualization layer handles the back-end migration of data, which enables the LUNs to remain online during migration.&lt;/span&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter is-resized"&gt;&lt;img loading="lazy" decoding="async" src="https://static.digihunch.com/wp-content/uploads/2019/11/image-27.png" alt="" class="wp-image-360" width="405" height="386"/&gt;&lt;figcaption class="wp-element-caption"&gt;Block-level virtualization (classic)&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter is-resized"&gt;&lt;img loading="lazy" decoding="async" src="https://static.digihunch.com/wp-content/uploads/2019/11/image-29.png" alt="" class="wp-image-362" width="480" height="450"/&gt;&lt;figcaption class="wp-element-caption"&gt;Federation of block storage across data centers (new generation)&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;Virtual SAN (VSAN, aka virtual fabric) &amp;#8211; a logical fabric on an FC SAN, which enables communication among a group of nodes regardless of physical location in the fabric.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h4 class="wp-block-heading" id="h-ip-san"&gt;&lt;strong&gt;IP SAN&lt;/strong&gt;&lt;/h4&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;strong&gt;iSCI (one of the IP SAN protocols)&lt;/strong&gt; &amp;#8211; an IP based protocol that establishes and manages connections between host and storage over IP. iSCSI encapsulates SCSI commands and data into an IP packet and transport them using TCP/IP. It is relatively inexpensive and easy to implement so widespread in environments without FC SAN.&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;Topology&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;Native connectivity (without FC components)&lt;/li&gt;&#10;&lt;li&gt;Bridged connectivity (including FC components in the configuration)&lt;/li&gt;&#10;&lt;li&gt;Combined connectivity (most common because a storage array usually comes with both FC and iSCSI ports)&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter is-resized"&gt;&lt;img loading="lazy" decoding="async" src="https://static.digihunch.com/wp-content/uploads/2019/11/image-30.png" alt="" class="wp-image-365" width="429" height="554"/&gt;&lt;figcaption class="wp-element-caption"&gt;iSCSI topologies&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;Protocol&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;stack: &lt;span style="text-decoration: underline;"&gt;SCSI is the command protocol that works at the application layer of OSI model; iSCSI is session-layer protocol that initiates a reliable session between devices that recognize SCSI commands and TCP/IP&lt;/span&gt;. The iSCSI session-layer interface is responsible for handling login, authentication, target discovery, and session management.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter is-resized"&gt;&lt;img loading="lazy" decoding="async" src="https://static.digihunch.com/wp-content/uploads/2019/11/image-31.png" alt="" class="wp-image-366" width="485" height="320"/&gt;&lt;figcaption class="wp-element-caption"&gt;iSCSI protocol stack&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;iSCSI session and PDU encapsulation&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter is-resized"&gt;&lt;img loading="lazy" decoding="async" src="https://static.digihunch.com/wp-content/uploads/2019/11/image-32.png" alt="" class="wp-image-367" width="428" height="111"/&gt;&lt;figcaption class="wp-element-caption"&gt;PDU encapsulation&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;iSCSI discovery &amp;#8211; an initiator must discover the location of its targets on the network and the names of the targets available to it before session establishment. Two types are SendTargets discovery and internet Storage Name Service&lt;/li&gt;&#10;&lt;li&gt;iSCSI names:&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;IQN, iSCSI Qualified Name such as &lt;em&gt;iqn.2008-02.com.example:optional_string&lt;/em&gt;;&amp;nbsp;&lt;/li&gt;&#10;&lt;li&gt;EUI, extended unique identifier such as &lt;em&gt;eui.0300732A32598D26&lt;/em&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;iSCSI command sequencing&lt;/strong&gt; &amp;#8211; A command sequence may generate multiple PDUs. A command sequence number (CmdSN) within an iSCSI session is used for numbering all initiator-to-target command PDUs belonging to the session. This number ensures that every command is delivered in the same order in which it is transmitted, regardless of the TCP connection that carries the command in the session.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;strong&gt;FCIP (one of the IP SAN protocols)&lt;/strong&gt; &amp;#8211; transporting FC block data over the IP infrastructure.&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;protocol stack and packet encapsulation&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter is-resized"&gt;&lt;img loading="lazy" decoding="async" src="https://static.digihunch.com/wp-content/uploads/2019/11/image-38.png" alt="" class="wp-image-373" width="420" height="199"/&gt;&lt;figcaption class="wp-element-caption"&gt;FCIP protocol stack&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter is-resized"&gt;&lt;img loading="lazy" decoding="async" src="https://static.digihunch.com/wp-content/uploads/2019/11/image-39.png" alt="" class="wp-image-374" width="385" height="157"/&gt;&lt;figcaption class="wp-element-caption"&gt;FCIP encapsulation&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;Topology (FCIP gateway involved):&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter is-resized"&gt;&lt;img loading="lazy" decoding="async" src="https://static.digihunch.com/wp-content/uploads/2019/11/image-40.png" alt="" class="wp-image-375" width="507" height="365"/&gt;&lt;figcaption class="wp-element-caption"&gt;FCIP topology&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;strong&gt;FCoE (one of the IP SAN protocols)&lt;/strong&gt; &amp;#8211; consolidation of LAN and SAN traffic over a single physical interface infrastructure. FCoE helps organizations address the challenges of having multiple discrete network infrastructures.&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;CNA (converged network adapters) replaces both HBAs and NICs in the server and consolidates both the IP and FC traffic&lt;/li&gt;&#10;&lt;li&gt;Special requirement on cables and switches&lt;/li&gt;&#10;&lt;li&gt;protocol stack and encapsulation&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter is-resized"&gt;&lt;img loading="lazy" decoding="async" src="https://static.digihunch.com/wp-content/uploads/2019/11/image-41.png" alt="" class="wp-image-376" width="479" height="273"/&gt;&lt;figcaption class="wp-element-caption"&gt;FCoE field mapping&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;CEE (converged enhanced Ethernet, or lossless Ethernet) provides new specification to existing Ethernet standard that eliminates the lossy nature of Ethernet. This makes 10Gb Ethernet a viable storage networking option, similar to FC. It features the following functionalities as part of IEEE 802.1:&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;PFC (priority-based flow control)&lt;/li&gt;&#10;&lt;li&gt;ETS (enhanced transmission selection)&lt;/li&gt;&#10;&lt;li&gt;CN (congestion notification)&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h4 class="wp-block-heading" id="h-related-postings"&gt;Related Postings&lt;/h4&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;&lt;a href="https://static.digihunch.com/2019/03/storage-nitty-gritty-1-5/"&gt;Disk and RAID&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://static.digihunch.com/2019/07/storage-nitty-gritty-3-of-5-nas-and-object-storage/"&gt;NAS and Object Storage&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://static.digihunch.com/2019/10/storage-nitty-gritty-4-of-5-backup-and-archive-solutions/"&gt;Backup and Archive Solution&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://static.digihunch.com/2019/11/storage-nitty-gritty-5-of-5-replication/"&gt;Replication&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;nav class="wp-post-navigation" aria-label="Post navigation"&gt;&#10;&lt;a rel="prev" href="https://static.digihunch.com/2019/04/application-i-o-characteristics/"&gt;&lt;span class="wp-post-navigation-label"&gt;Previous Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;Application I/O Characteristics&lt;/strong&gt;&lt;/a&gt;&#10;&lt;a rel="next" href="https://static.digihunch.com/2019/05/automation-with-ansible-a-primer/"&gt;&lt;span class="wp-post-navigation-label"&gt;Next Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;Set up automation with Ansible&lt;/strong&gt;&lt;/a&gt;&#10;&lt;/nav&gt;&#10;</description></item><item><title>Storage Nitty-Gritty 1 of 5 – Disk and RAID</title><link>https://static.digihunch.com/2019/03/storage-nitty-gritty-1-5/</link><pubDate>Sat, 09 Mar 2019 22:25:52 -0500</pubDate><guid>https://static.digihunch.com/2019/03/storage-nitty-gritty-1-5/</guid><description>&lt;p class="wp-block-paragraph"&gt;On my trip I have been through several pre-sales discussions on storage. Therefore I&amp;#8217;m taking this opportunities to write up a series of postings deep diving into storage technologies. In this first section, we lay out the foundation of storage technology, from physical device to RAID, focusing on the concepts. Some contents are excerpts from Information Storage and Management.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;strong&gt;Volume Manager&lt;/strong&gt; &amp;#8211; In early days, a file system occupies the entire disk drive, and presents continuous disk blocks directly to operating systems. Logical Volume Manager (LVM) was then introduced to bring a layer of abstraction (logical volume) on top of disks. The layers are shown as follows:&lt;/p&gt;&#10;&lt;p&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="604px" viewBox="-0.5 -0.5 604 186" style="max-width:100%;max-height:186px;"&gt;&lt;defs&gt;&lt;/defs&gt;&lt;g&gt;&lt;rect x="0" y="127" width="120" height="50" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(6.5,145.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow:visible;" pointer-events="all" width="106" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 107px; white-space: nowrap; overflow-wrap: normal; text-align: center;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;white-space:normal;"&gt;Physical Hard Drive&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="53" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica"&gt;Physical Hard Drive&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;rect x="240" y="147" width="300" height="30" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(336.5,155.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow:visible;" pointer-events="all" width="106" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 106px; white-space: nowrap; overflow-wrap: normal; text-align: center;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;white-space:normal;"&gt;Physical Hard Drive&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="53" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica"&gt;Physical Hard Drive&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;rect x="120" y="127" width="120" height="50" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(126.5,145.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow:visible;" pointer-events="all" width="106" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 107px; white-space: nowrap; overflow-wrap: normal; text-align: center;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;white-space:normal;"&gt;Physical Hard Drive&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="53" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica"&gt;Physical Hard Drive&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;rect x="240" y="127" width="120" height="20" fill="#f5f5f5" stroke="#666666" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(277.5,130.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow:visible;" pointer-events="all" width="44" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(51, 51, 51); line-height: 1.2; vertical-align: top; width: 45px; white-space: nowrap; overflow-wrap: normal; text-align: center;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;white-space:normal;"&gt;Partition&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="22" y="12" fill="#333333" text-anchor="middle" font-size="12px" font-family="Helvetica"&gt;Partition&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;rect x="360" y="127" width="180" height="20" fill="#f5f5f5" stroke="#666666" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(427.5,130.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow:visible;" pointer-events="all" width="44" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(51, 51, 51); line-height: 1.2; vertical-align: top; width: 45px; white-space: nowrap; overflow-wrap: normal; text-align: center;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;white-space:normal;"&gt;Partition&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="22" y="12" fill="#333333" text-anchor="middle" font-size="12px" font-family="Helvetica"&gt;Partition&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;rect x="240" y="97" width="120" height="30" fill="#ffffff" stroke="#000000" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(255.5,105.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow:visible;" pointer-events="all" width="88" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 89px; white-space: nowrap; overflow-wrap: normal; text-align: center;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;white-space:normal;"&gt;Physical Volume&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="44" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica"&gt;Physical Volume&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;rect x="120" y="97" width="120" height="30" fill="#ffffff" stroke="#000000" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(135.5,105.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow:visible;" pointer-events="all" width="88" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 89px; white-space: nowrap; overflow-wrap: normal; text-align: center;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;white-space:normal;"&gt;Physical Volume&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="44" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica"&gt;Physical Volume&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;rect x="0" y="97" width="120" height="30" fill="#ffffff" stroke="#000000" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(15.5,105.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow:visible;" pointer-events="all" width="88" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 89px; white-space: nowrap; overflow-wrap: normal; text-align: center;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;white-space:normal;"&gt;Physical Volume&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="44" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica"&gt;Physical Volume&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;rect x="360" y="97" width="180" height="30" fill="#ffffff" stroke="#000000" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(405.5,105.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow:visible;" pointer-events="all" width="88" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 89px; white-space: nowrap; overflow-wrap: normal; text-align: center;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;white-space:normal;"&gt;Physical Volume&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="44" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica"&gt;Physical Volume&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;rect x="0" y="67" width="360" height="30" fill="#ffe6cc" stroke="#d79b00" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(141.5,75.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow:visible;" pointer-events="all" width="77" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 78px; white-space: nowrap; overflow-wrap: normal; text-align: center;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;white-space:normal;"&gt;Volume Group&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="39" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica"&gt;Volume Group&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;rect x="360" y="67" width="180" height="30" fill="#ffe6cc" stroke="#d79b00" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(411.5,75.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow:visible;" pointer-events="all" width="77" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 78px; white-space: nowrap; overflow-wrap: normal; text-align: center;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;white-space:normal;"&gt;Volume Group&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="39" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica"&gt;Volume Group&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;rect x="0" y="37" width="170" height="30" fill="#fff2cc" stroke="#d6b656" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(43.5,45.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow:visible;" pointer-events="all" width="82" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 83px; white-space: nowrap; overflow-wrap: normal; text-align: center;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;white-space:normal;"&gt;Logical Volume&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="41" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica"&gt;Logical Volume&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;rect x="170" y="37" width="190" height="30" fill="#fff2cc" stroke="#d6b656" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(223.5,45.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow:visible;" pointer-events="all" width="82" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 83px; white-space: nowrap; overflow-wrap: normal; text-align: center;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;white-space:normal;"&gt;Logical Volume&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="41" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica"&gt;Logical Volume&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;rect x="360" y="37" width="180" height="30" fill="#fff2cc" stroke="#d6b656" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(408.5,45.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow:visible;" pointer-events="all" width="82" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 82px; white-space: nowrap; overflow-wrap: normal; text-align: center;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;white-space:normal;"&gt;Logical Volume&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="41" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica"&gt;Logical Volume&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;rect x="0" y="7" width="170" height="30" fill="#d5e8d4" stroke="#82b366" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(53.5,15.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow:visible;" pointer-events="all" width="63" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 63px; white-space: nowrap; overflow-wrap: normal; text-align: center;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;white-space:normal;"&gt;File System&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="32" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica"&gt;File System&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;rect x="170" y="7" width="190" height="30" fill="#d5e8d4" stroke="#82b366" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(233.5,15.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow:visible;" pointer-events="all" width="62" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 64px; white-space: nowrap; overflow-wrap: normal; text-align: center;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;white-space:normal;"&gt;File System&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="31" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica"&gt;File System&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;rect x="360" y="7" width="180" height="30" fill="#d5e8d4" stroke="#82b366" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(418.5,15.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow:visible;" pointer-events="all" width="62" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 64px; white-space: nowrap; overflow-wrap: normal; text-align: center;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;white-space:normal;"&gt;File System&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="31" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica"&gt;File System&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;rect x="560" y="117" width="40" height="20" fill="none" stroke="none" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(556.5,120.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow:visible;" pointer-events="all" width="46" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 47px; white-space: nowrap; overflow-wrap: normal; text-align: center;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;white-space:normal;"&gt;pvcreate&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="23" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica"&gt;pvcreate&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;rect x="560" y="87" width="40" height="20" fill="none" stroke="none" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(556.5,90.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow:visible;" pointer-events="all" width="46" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 47px; white-space: nowrap; overflow-wrap: normal; text-align: center;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;white-space:normal;"&gt;vgcreate&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="23" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica"&gt;vgcreate&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;rect x="560" y="57" width="40" height="20" fill="none" stroke="none" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(558.5,60.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow:visible;" pointer-events="all" width="42" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 43px; white-space: nowrap; overflow-wrap: normal; text-align: center;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;white-space:normal;"&gt;lvcreate&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="21" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica"&gt;lvcreate&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;rect x="550" y="32" width="40" height="20" fill="none" stroke="none" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(556.5,35.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow:visible;" pointer-events="all" width="26" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 27px; white-space: nowrap; overflow-wrap: normal; text-align: center;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;white-space:normal;"&gt;mkfs&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="13" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica"&gt;mkfs&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;rect x="550" y="137" width="40" height="20" fill="none" stroke="none" pointer-events="all"&gt;&lt;/rect&gt;&lt;g transform="translate(557.5,140.5)"&gt;&lt;switch&gt;&lt;foreignObject style="overflow:visible;" pointer-events="all" width="25" height="12" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; vertical-align: top; width: 26px; white-space: nowrap; overflow-wrap: normal; text-align: center;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display:inline-block;text-align:inherit;text-decoration:inherit;white-space:normal;"&gt;fdisk&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="13" y="12" fill="#000000" text-anchor="middle" font-size="12px" font-family="Helvetica"&gt;fdisk&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;path d="M 550 177 L 550 13.37" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke"&gt;&lt;/path&gt;&lt;path d="M 550 8.12 L 553.5 15.12 L 550 13.37 L 546.5 15.12 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all"&gt;&lt;/path&gt;&lt;/g&gt;&lt;/svg&gt;&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;With all these layers, a byte in user file maps to disk sectors through several layers:&lt;/p&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter is-resized"&gt;&lt;img loading="lazy" decoding="async" src="https://static.digihunch.com/wp-content/uploads/2019/11/image-3.png" alt="" class="wp-image-311" width="519" height="348"/&gt;&lt;figcaption class="wp-element-caption"&gt;Mapping from user file to physical disk&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;strong&gt;File System&lt;/strong&gt; &amp;#8211; a hierarchical structure of files. It organizes data in a structural hierarchical manner. It includes files, directories as well as metadata. metadata must be consistent for the file system to be considered healthy. In Linux, metadata consists of:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;&lt;strong&gt;Superblock&lt;/strong&gt;: important information about file system, e.g. type, creation and modification dates, size, mount status flag&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Inodes&lt;/strong&gt;: a data structure that contains information associated with every file or directory&lt;/li&gt;&#10;&lt;li&gt;list of data blocks free and in use&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Host connects to storage through various Interface Protocols. Common interface protocols include:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;IDE/&lt;strong&gt;ATA&lt;/strong&gt; and Serial &lt;strong&gt;ATA&lt;/strong&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;SCSI&lt;/strong&gt; (Small Computer System Interface)&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;FC&lt;/strong&gt; (Fibre Channel)&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;IP&lt;/strong&gt; (Internet Protocol per se is a network protocol traditionally used for host-to-host traffic in the early days. In the virtualization era, it has become a viable option for host-to-storage communication. Examples are &lt;strong&gt;iSCSI&lt;/strong&gt; and &lt;strong&gt;FCIP&lt;/strong&gt;)&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The most prevalent disk drive types are &lt;strong&gt;SSD&lt;/strong&gt; (solid state drive) and &lt;strong&gt;HDD&lt;/strong&gt; (hard disk driveA). SSD (solid state drive) is newer, flash-based technology. Without seek and rotational latencies they deliver a high number of IOPS with low response times. They are especially suited for applications with small block size and random-read workloads requiring constant latency &amp;lt;1ms.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;HDD is traditional and more cost effective. Its physical components are illustrated in the following two graphs:&lt;/p&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter is-resized"&gt;&lt;img loading="lazy" decoding="async" src="https://static.digihunch.com/wp-content/uploads/2019/11/image-4.png" alt="" class="wp-image-312" width="325" height="226"/&gt;&lt;figcaption class="wp-element-caption"&gt;Hard disk component&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter is-resized"&gt;&lt;img loading="lazy" decoding="async" src="https://static.digihunch.com/wp-content/uploads/2019/11/image-5.png" alt="" class="wp-image-313" width="367" height="213"/&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;For HDD, disk service time (time taken by a disk to complete an I/O request) is determined by the following factors:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;&lt;strong&gt;Seek time&lt;/strong&gt; (aka access time) describes the time taken to position the R/W heads across the platter with a radial movement (moving along the radius of the platter). In other words, it is the time taken to position and settle the arm and the head over the correct track.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Rotation latency&lt;/strong&gt; is the time taken by the platter to rotate and position the data under the R/W head. It depends on the rotation speed of the spindle and is measured in milliseconds.&lt;/li&gt;&#10;&lt;li&gt;(&lt;strong&gt;Data) transfer rate &lt;/strong&gt;is the average amount of data per unit time that the drive can deliver from disk controller to the HBA (on the host).&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;strong&gt;Zone Bit Recording&lt;/strong&gt; &amp;#8211; a mechanism to use disk efficiently by grouping tracks into zones based on their distance from the disk.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;strong&gt;Logical Block Addressing (LBA) &lt;/strong&gt;&amp;#8211; disk controller translates LBA to a physical address (CHS, cylinder, head and sector). The host only needs to know the size of disk drive in terms of number of blocks. The logical blocks are mapped to physical sectors on a 1:1 basis&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;strong&gt;IO request processing &lt;/strong&gt;&amp;#8211; I/O controller is introduce to improve response time for I/O request, in this model, The I/O requests arrive at the controller at the rate generated by the application. This rate is also called the arrival rate. These requests are held in the I/O queue, and the I/O controller processes them one by one, as shown here:&lt;/p&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter is-resized"&gt;&lt;img loading="lazy" decoding="async" src="https://static.digihunch.com/wp-content/uploads/2019/11/image-6.png" alt="" class="wp-image-314" width="541" height="57"/&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The relationship between controller utilization and average response time is: &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Average response time = Service time / (1 – Utilization) &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;where service time is the time taken by disk controller to service the I/O request. This results in a classic relation between response time and utilization, as plotted below:&lt;/p&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter is-resized"&gt;&lt;img loading="lazy" decoding="async" src="https://static.digihunch.com/wp-content/uploads/2019/11/image-7.png" alt="" class="wp-image-315" width="434" height="196"/&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The graph indicates that the response time changes are nonlinear as the utilization increases. When the average queue sizes are low, the response time remains low. The response time increases slowly with added load on the queue and increases exponentially when the utilization exceeds 70 percent. Therefore, for performance-sensitive applications, it is common to utilize disks below their 70 percent of I/O serving capability. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;strong&gt;Command queuing&lt;/strong&gt; is a technique implemented on modern disk drives that determines the execution order of received I/Os and reduces unnecessary drive-head movements to improve disk performance. When an I/O is received for execution at the disk controller, the command queuing algorithms assign a tag that defines a sequence in which the commands should be executed. With command queuing, commands are executed based on the organization of data on the disk, regardless of the order in which the commands are received. Below is an example:&lt;/p&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter is-resized"&gt;&lt;img loading="lazy" decoding="async" src="https://static.digihunch.com/wp-content/uploads/2019/11/image-8.png" alt="" class="wp-image-318" width="525" height="383"/&gt;&lt;figcaption class="wp-element-caption"&gt;Disk Command Queuing&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;RAID is a technology that leverages multiple drives as part of a set that provides data protection against drive failures. It may also improve performance by serving I/Os from multiple disks simultaneously. It is primarily used in HDD but SSD may still benefit from it. RAID may be implemented by software but hardware RAID with a controller is widespread. RAID is built on three basic techniques:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;&lt;strong&gt;Striping&lt;/strong&gt;: spread data across multiple drives (more than one) to use the drives in parallel.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Mirroring&lt;/strong&gt;: same data is stored on two different disk drives, yielding two copies of the data.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Parity&lt;/strong&gt;: a method to protect striped data from disk drive failure without the cost of mirroring. An additional disk drive is added to hold parity, a mathematical construct that allows re-creation of the missing data.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Basic RAID levels are summarized here:&lt;/p&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter is-resized"&gt;&lt;img loading="lazy" decoding="async" src="https://static.digihunch.com/wp-content/uploads/2019/11/image-9.png" alt="" class="wp-image-320" width="520" height="199"/&gt;&lt;figcaption class="wp-element-caption"&gt;RAID summary&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;RAID 0, 1, 5 and 6 are pretty common in data centre operations. In addition to these levels above. If you hear RAID 1+0, 5+0 and RAID 6+0, they are called nested RAID. They are simply a RAID 0 on top of RAID1, RAID 5 and RAID 6, respectively.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;strong&gt;RAID 0&lt;/strong&gt; &amp;#8211; data striping technique utilizes full capacity of drives. Although it is a good option for applications that need high I/O throughput. It lacks data protection so it cannot drive application requiring high availability.&lt;/p&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter is-resized"&gt;&lt;img loading="lazy" decoding="async" src="https://static.digihunch.com/wp-content/uploads/2019/11/image-10.png" alt="" class="wp-image-321" width="256" height="364"/&gt;&lt;figcaption class="wp-element-caption"&gt;RAID 0&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;strong&gt;RAID 1&lt;/strong&gt; &amp;#8211; mirroring technique ensures data duplication. In the event of disk failure, it introduces minimal impact to the disk array. It is suitable for applications that require high availability and cost is no constraint.&lt;/p&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter is-resized"&gt;&lt;img loading="lazy" decoding="async" src="https://static.digihunch.com/wp-content/uploads/2019/11/image-11.png" alt="" class="wp-image-322" width="294" height="382"/&gt;&lt;figcaption class="wp-element-caption"&gt;RAID 1&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;strong&gt;RAID 1+0 or RAID 10&lt;/strong&gt; &amp;#8211; performs well for workloads with small, random, write-intensive I/Os. Some applications that benefit from RAID 1+0 include the following:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;High transaction rate Online Transaction Processing (OLTP)&lt;/li&gt;&#10;&lt;li&gt;Large messaging installations&lt;/li&gt;&#10;&lt;li&gt;Database applications with write intensive random access workloads&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter is-resized"&gt;&lt;img loading="lazy" decoding="async" src="https://static.digihunch.com/wp-content/uploads/2019/11/image-12.png" alt="" class="wp-image-323" width="334" height="367"/&gt;&lt;figcaption class="wp-element-caption"&gt;RAID 1+0&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;strong&gt;RAID 3&lt;/strong&gt; &amp;#8211; RAID 3 stripes data for performance and uses parity for fault tolerance. the total disk space required is 1.25 times the size of the data disks. RAID 3 always reads and writes complete stripes of data across all disks because the drives operate in parallel. RAID 3 provides good performance for applications that involve large sequential data access, such as data backup or video streaming.&lt;/p&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter is-resized"&gt;&lt;img loading="lazy" decoding="async" src="https://static.digihunch.com/wp-content/uploads/2019/11/image-13.png" alt="" class="wp-image-324" width="266" height="370"/&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;strong&gt;RAID 5&lt;/strong&gt; &amp;#8211; RAID5 is similar to RAID 4 because it uses striping. The drives (strips) are also independently accessible. The difference between RAID 4 and RAID 5 is the parity location. In RAID 4, parity is written to a dedicated drive, creating a write bottleneck for the parity disk. In RAID 5, parity is distributed across all disks to overcome the write bottleneck of a dedicated parity disk.&lt;/p&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter is-resized"&gt;&lt;img loading="lazy" decoding="async" src="https://static.digihunch.com/wp-content/uploads/2019/11/image-14.png" alt="" class="wp-image-325" width="281" height="390"/&gt;&lt;figcaption class="wp-element-caption"&gt;RAID 5&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;RAID 5 is good for random, read-intensive I/O applications and preferred for messaging, data mining, medium-performance media serving, and relational database management system (RDBMS) implementations, in which database administrators (DBAs) optimize data access.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;strong&gt;RAID 6&lt;/strong&gt; &amp;#8211; works the same way as RAID 5, except that RAID 6 includes a second parity element to enable survival if two disk failures occur in a RAID set. The write penalty in RAID 6 is more than that in RAID 5; therefore, RAID 5 writes perform better than RAID 6. The rebuild operation in RAID 6 may take longer than that in RAID 5 due to the presence of two parity sets.&lt;/p&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter is-resized"&gt;&lt;img loading="lazy" decoding="async" src="https://static.digihunch.com/wp-content/uploads/2019/11/image-15.png" alt="" class="wp-image-326" width="288" height="405"/&gt;&lt;figcaption class="wp-element-caption"&gt;RAID 6&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;strong&gt;Intelligent Storage System&lt;/strong&gt; involves cache as the core component. An intelligent storage system involves front end, cache, back end and physical disks, as shown here:&lt;/p&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter is-resized"&gt;&lt;img loading="lazy" decoding="async" src="https://static.digihunch.com/wp-content/uploads/2019/11/image-16.png" alt="" class="wp-image-330" width="565" height="255"/&gt;&lt;figcaption class="wp-element-caption"&gt;Intelligent Storage System components&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;A variety of &lt;strong&gt;physical disk&lt;/strong&gt; types and speed (e.g. mix of FC, SATA, SAS and flash) can be supported in a modern intelligent storage system.&amp;nbsp;The &lt;strong&gt;front end&lt;/strong&gt; provides the interface between the storage system and the host. It consists of ports and controllers, with redundancy. The &lt;strong&gt;back end&lt;/strong&gt; provides an interface between cache and the physical disks. It consists of ports and controllers. For high data protection and high availability, storage systems are configured with dual controllers with multiple ports.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;strong&gt;Cache&lt;/strong&gt; improves storage system performance by isolating hosts from mechanical delays associated with hard disks. In intelligent storage system, read and write are first attempted on cache.&lt;/p&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter is-resized"&gt;&lt;img loading="lazy" decoding="async" src="https://static.digihunch.com/wp-content/uploads/2019/11/image-17.png" alt="" class="wp-image-334" width="454" height="226"/&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Page is the basic unit of cache, and the size of page is configured based on application I/O size. Cache consists of:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;&lt;strong&gt;data store&lt;/strong&gt;: holds the actual data temporarily&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;tag RAM&lt;/strong&gt;: mainly serves three purposes:&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;it tracks locations of data in cache and on disk; &lt;/li&gt;&#10;&lt;li&gt;it maintains dirty bit flag to indicate whether data in cache has been committed to disk;&lt;/li&gt;&#10;&lt;li&gt;it keeps time based information such as last access time, for cache management&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;strong&gt;Read Operation with Cache&lt;/strong&gt;: When host issues a read request, the storage controller reads the tag RAM first to determine whether required data is available in cache:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;&lt;strong&gt;Read cache hit&lt;/strong&gt;: data is sent to host without any disk operation;&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Read cache miss&lt;/strong&gt;: back end access the disk to retrieve the requested data. Data is then placed in cache and sent to host through front end.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter is-resized"&gt;&lt;img loading="lazy" decoding="async" src="https://static.digihunch.com/wp-content/uploads/2019/11/image-18.png" alt="" class="wp-image-335" width="546" height="466"/&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Cache miss increases I/O response time, to increase read hit ratio, read-ahead algorithm can be used when read requests are sequential. In a sequential read request, a contiguous set of associated blocks is retrieved. Several other blocks that have not yet been requested by the host can be read from the disk and placed into cache in advance. When the host subsequently requests these blocks, the read operations will be read hits. &lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;&lt;strong&gt;Fixed prefetch&lt;/strong&gt; &amp;#8211; the intelligent storage system prefetches a fixed amount of data. It is most suitable when host I/O sizes are uniform. &lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Variable prefetch&lt;/strong&gt;, the storage system prefetches an amount of data in multiples of the size of the host request. &lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Maximum prefetch&lt;/strong&gt; limits the number of data blocks that can be prefetched to prevent the disks from being rendered busy with prefetch at the expense of other I/Os.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;strong&gt;Write Operation with Cache&lt;/strong&gt;: When an I/O is written to cache and acknowledged, it is completed in far less time (from the host’s perspective) than it would take to write directly to disk. Sequential writes also offer opportunities for optimization because many smaller writes can be coalesced for larger transfers to disk drives with the use of cache. Write operation with cache can be implemented in two ways:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;&lt;strong&gt;Write-back cache&lt;/strong&gt;: Data is placed in cache and an acknowledgment is sent to the host immediately. Later, data from several writes are committed (de-staged) to the disk. Write response times are much faster because the write operations are isolated from the mechanical delays of the disk. However, uncommitted data is at risk of loss if cache failures occur.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Write-through cache&lt;/strong&gt;: Data is placed in the cache and immediately written to the disk, and an acknowledgment is sent to the host. Because data is committed to disk as it arrives, the risks of data loss are low, but the write-response time is longer because of the disk operations.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;If the size of an I/O request exceeds the &lt;strong&gt;write aside size&lt;/strong&gt;, writes are sent to the disk directly to reduce the impact of large writes consuming a large cache space. This is helpful where cache resources are constrained and cache is required for small random I/Os. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Cache space can be assigned in two ways:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;&lt;strong&gt;dedicated cache&lt;/strong&gt;: separate sets of locations are reserved for read and write;&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;global cache&lt;/strong&gt;: user may specify percentage of cache for read and write based on application workload pattern; or the system set is dynamically.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Cache Management algorithm is used to determine when, and what pages of the cache need to be free up during maintenance. Most commonly used algorithms are:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;LRU (least recently used): assuming data not accessed for a while will not be requested by host any more;&lt;/li&gt;&#10;&lt;li&gt;MRU (most recently used): assuming data recently accessed will not be requested by host again&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;As cache fills, the storage system must take action to flush dirty pages by committing data from cache to disk. There are several triggers for cache management action:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;Idle flushing &amp;#8211; occurs continuously at modest rate when cache utilization level is between high and low watermark;&lt;/li&gt;&#10;&lt;li&gt;High watermark flushing &amp;#8211; activated when utilization hits high watermark; and stops at low watermark; this has impact to I/O processing;&lt;/li&gt;&#10;&lt;li&gt;Forced flushing &amp;#8211; occurs in the event of large I/O burst when cache reaches 100% capacity; this significantly impacts I/O response time&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter is-resized"&gt;&lt;img loading="lazy" decoding="async" src="https://static.digihunch.com/wp-content/uploads/2019/11/image-19.png" alt="" class="wp-image-336" width="523" height="184"/&gt;&lt;figcaption class="wp-element-caption"&gt;Types of Flushing&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;strong&gt;Cache data protection&lt;/strong&gt; is the mechanism to prevent losing uncommitted data held in cache. Common mechanisms are:&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;strong&gt;Cache mirroring&lt;/strong&gt; &amp;#8211; Each write to cache is held in two different memory locations on two independent memory cards. If a cache failure occurs, the write data will still be safe in the mirrored location and can be committed to the disk. The array operating environment needs to maintain cache coherency between the redundant memory locations. Read cache does not need mirroring.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;strong&gt;Cache vaulting&lt;/strong&gt; &amp;#8211; In the event of server power failure, use battery power to write the cache content to the disk (vault drive). When power is restored, data from these disks is written back to write cache and then written to the intended disks.&lt;/p&gt;&#10;&lt;p&gt;&lt;!--StartFragment--&gt;&lt;/p&gt;&#10;&lt;h4 class="wp-block-heading" id="h-related-postings"&gt;Related Postings&lt;/h4&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;&lt;a href="https://static.digihunch.com/2019/03/storage-nitty-gritty-1-5/"&gt;SAN&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://static.digihunch.com/2019/07/storage-nitty-gritty-3-of-5-nas-and-object-storage/"&gt;NAS and Object Storage&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://static.digihunch.com/2019/10/storage-nitty-gritty-4-of-5-backup-and-archive-solutions/"&gt;Backup and Archive Solution&lt;/a&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;a href="https://static.digihunch.com/2019/11/storage-nitty-gritty-5-of-5-replication/"&gt;Replication&lt;/a&gt;&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;&lt;!--EndFragment--&gt;&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/2019/02/package-repository-management-in-linux/"&gt;&lt;span class="wp-post-navigation-label"&gt;Previous Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;Package Repository Management for Linux&lt;/strong&gt;&lt;/a&gt;&#10;&lt;a rel="next" href="https://static.digihunch.com/2019/04/build-a-wordpress-site-in-one-hour-with-lightsail/"&gt;&lt;span class="wp-post-navigation-label"&gt;Next Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;Lightsail – create a WordPress site in one hour&lt;/strong&gt;&lt;/a&gt;&#10;&lt;/nav&gt;&#10;</description></item></channel></rss>