Containers
EKS Persistent Volumes for Instance Store
The Kubernetes project is made up of a number of special interest groups (SIGs) that focus on a particular part of the Kubernetes ecosystem. The Storage SIG is focused on different types of storage (block and file) and ensuring that storage is available to containers when they are scheduled. One of the subprojects of the Storage SIG is the Local Volume Static Provisioner, and it is a Container Storage Interface (CSI) driver that creates Kubernetes PersistentVolumes for persistent disks attached during instance startup.
This post discusses deploying the Local Volume Static Provisioner CSI driver using Amazon EKS managed node groups and pre-bootstrap commands to expose the NVMe EC2 instance store drives as Kubernetes PV objects. Customers may wish to leverage the local NVMe storage volumes to achieve higher performance than what’s possible from the general-purpose Amazon EBS boot volume.
Note that instance storage volumes are for temporary storage, and the data is lost when the Amazon Elastic Compute Cloud (Amazon EC2) instance is stopped or terminated. To persist data stored in instance store volumes across the lifecycle of an instance, you need to handle replication at the application layer.
Storage in Kubernetes
A Kubernetes PersistentVolume (PV) is a cluster resource that defines the capabilities and location of a single storage volume. A PersistentVolumeClaim (PVC) defines a request for a certain amount of storage resources. When a Kubernetes Pod needs storage, it references a PVC. Kubernetes then works to match the PVC to an available PV or automatically provision a new PV if the CSI driver supports dynamic provisioning.
Below is an example of a Kubernetes Pod, PV, and PVC. The manifest first defines a PV named my-pv
, which offers 5 GiB of storage and is classified as being of storage class nfs
. Next, the manifest creates a PVC named nfs-claim
, which requests 4 GiB of nfs
storage. Finally, the Pod named app
mounts the storage, which is claimed by the PVC of nfs-claim
.
Walkthrough
This post will walk you through the following steps to install and test the Local Volume Static Provisioner:
- Create a service account with cluster level permissions
- Create a ConfigMap for CSI driver
- Create a DaemonSet to deploy the CSI driver
- Two options for creating Amazon EKS managed node groups with boot scripts to expose the NVMe instance store to Kubernetes Pods
- Clean up
Prerequisites
We need a few prerequisites and tools to successfully run through these steps. Ensure you have the following in your working environment:
Installing the Local Storage Static Provisioner
The Local Volume Static Provisioner CSI handles both the detection and creation of PVs for local disks mounted in a predefined file system path. Installing requires deploying a DaemonSet and granting Kubernetes API and host level permissions.
Kubernetes Service Accounts and Permissions
The CSI driver needs permission to issue API calls to the Kubernetes control plane to manage the lifecycle of the PVs. The manifest below defines a Kubernetes service account and attaches a Kubernetes cluster role that grants the necessary Kubernetes API permissions.
Copy and save the manifest below as service-account.yaml
Run the following command to create the ServiceAccount, ClusterRole, and ClusterRoleBinding:
CSI Driver ConfigMap
The Local Volume Static Provisioner CSI driver stores in a Kubernetes ConfigMap where to look for mounted EC2 NVMe instance store volumes and how to expose them as PVs. The below ConfigMap specifies that Local Volume Static Provisioner look for mounted NVMe instance store volumes in the /mnt/fast-disk
directory.
Kubernetes StorageClass specifies a type of storage available in the cluster. The manifest includes a new StorageClass of fast-disks
to identify that the PVs relate to NVMe instance store volumes.
Copy and save the manifest below as config-map.yaml
Run the following command to create the StorageClass and ConfigMap.
CSI Driver DaemonSet
The Local Volume Static Provisioner CSI Driver runs on each Amazon EKS node needing its NVMe instance store volumes exposed as Kubernetes PVs. Often Kubernetes clusters have multiple instance types in the cluster, where some nodes might not have NVMe instance store volumes. The DaemonSet in the following manifest specifies a nodeAffinity
selector to only schedule the DaemonSet on an Amazon EKS node with a label of fast-disk-node
and corresponding value of either pv-raid
or pv-nvme
.
Copy and save the following manifest as daemonset.yaml
Run the following command to create the DaemonSet.
Amazon EKS Managed Node Group – Pre-bootstrap Commands
The ConfigMap deployed has the Local Volume Static Provisioner CSI Driver looking for disks mounted in the /mnt/fast-disks
directory and running on nodes with a label of fast-disk-node
and a value of pv-raid
or pv-nvme
. Now we need to configure our Amazon EKS managed node group to spin up EC2 instances with the fast-disk-node
label and, on startup, to mount the NVMe instance store volumes to the /mnt/fast-disks
directory.
This post goes over two approaches:
- Multiple persistent volumes, one for each NVMe instance store volume
- One single persistent volume RAID-0 array across all the NVMe instance store volumes
Both of these options deliver high random I/O performance and very low latency storage volumes to your Kubernetes Pods. The two approaches offer different options depending on the use case.
In Option 1, a persistent volume is created for each NVMe instance store volume. The i3.8xlarge instance used in this blog has four NVMe volumes. Option 1 will create four persistent volumes for the use case when multiple Pods need fast storage. Option 2 creates a single persistent volume using RAID-0, which is useful when only a single Pod needs fast storage.
Option 1: Multiple Persistent Volumes, One for Each NVMe Instance Store
Using the eksctl utility, we create a new Amazon EKS managed node group. In this example, we’ve requested two i3.8xlarge EC2 instances. In the metadata, replace eksworkshop-eksctl
and us-west-2
with your respective EKS cluster’s name and AWS Region.
Copy and save the manifest below as pv-nvme-nodegroup.yaml
Run the following command to create the Amazon EKS managed node group.
Option 2: Single Persistent Volume RAID-0 array across all the NVMe instance stores
Similar to the last example, we use the eksctl utility and create a new Amazon EKS managed node group. However, this time a software RAID-0 array across the NVMe instance store volumes is created.
In the metadata, replace eksworkshop-eksctl
and us-west-2
with your respective EKS cluster’s name and AWS Region.
Copy and save the manifest below as pv-raid-nodegroup.yaml
Run the following command to create the Amazon EKS managed node group.
Viewing Persistent Volumes and DaemonSets
After the Amazon EKS managed node group is created, the Local Volume Static Provisioner will be scheduled as a DaemonSet on each of the managed node group’s EC2 instances. The DaemonSet will discover the mounted NVMe instance store volumes mounted in /mnt/fast-disks
and expose them as persistent volumes.
To view the DaemonSets running, run the following command:
To view the persistent volumes, run the following command:
Clean up
First, we remove the instance store node groups. Note that the eksctl command starts a CloudFormation script that can take a few minutes before the nodes and associated resources are terminated.
Then delete the persistent volumes.
Finally, remove the associated Kubernetes objects.
Conclusion
In this post we described how to use the Local Volume Static Provisioner CSI driver developed by the Kubernetes Storage special interest group. By using the Amazon EKS managed node groups pre-bootstrap commands, you can customize the provisioning of NVMe instance store volumes to meet your unique PV needs.
Application developers can use this deployment pattern to provide each pod access to an isolated instance store or a shared storage layer for cross-pod access.
The Local Volume Static Provisioner is a third-party open-source software released under the Apache 2 license. We encourage you to visit the AWS Containers Roadmap page on GitHub to stay in touch with the latest additions and upcoming features to AWS container services.