Using persistent EBS volumes
Now let's update the catalog MySQL database to use persistent EBS storage. With EKS Auto Mode, the EBS CSI Driver is already installed and managed by AWS.
Create the StorageClass
The StorageClass defines how EKS Auto Mode will provision EBS volumes. While EKS Auto Mode includes the EBS CSI Driver, you need to create a StorageClass that references ebs.csi.eks.amazonaws.com to use the storage capability.
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: ebs-sc
provisioner: ebs.csi.eks.amazonaws.com
volumeBindingMode: WaitForFirstConsumer
parameters:
type: gp3
encrypted: "true"
provisioner: ebs.csi.eks.amazonaws.com - Uses EKS Auto Mode's built-in EBS CSI Driver
type: gp3 - Specifies the EBS volume type
Apply the StorageClass:
Update the catalog MySQL database
Since many StatefulSet fields, including volumeClaimTemplates, cannot be modified, we'll need to delete and recreate the catalog service with the new storage configuration.
First, delete the current catalog MySQL StatefulSet:
Now recreate it with persistent storage enabled. The updated StatefulSet includes a volumeClaimTemplates section:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: catalog-mysql
labels:
app.kubernetes.io/created-by: eks-workshop
app.kubernetes.io/team: database
spec:
replicas: 1
serviceName: catalog-mysql
selector:
matchLabels:
app.kubernetes.io/name: catalog
app.kubernetes.io/instance: catalog
app.kubernetes.io/component: mysql
template:
metadata:
labels:
app.kubernetes.io/name: catalog
app.kubernetes.io/instance: catalog
app.kubernetes.io/component: mysql
app.kubernetes.io/created-by: eks-workshop
app.kubernetes.io/team: database
spec:
containers:
- name: mysql
image: "public.ecr.aws/docker/library/mysql:8.0"
imagePullPolicy: IfNotPresent
env:
- name: MYSQL_ROOT_PASSWORD
value: my-secret-pw
- name: MYSQL_DATABASE
value: catalog
- name: MYSQL_USER
valueFrom:
secretKeyRef:
name: catalog-db
key: RETAIL_CATALOG_PERSISTENCE_USER
- name: MYSQL_PASSWORD
valueFrom:
secretKeyRef:
name: catalog-db
key: RETAIL_CATALOG_PERSISTENCE_PASSWORD
volumeMounts:
- name: data
mountPath: /var/lib/mysql
ports:
- name: mysql
containerPort: 3306
protocol: TCP
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: ebs-sc
resources:
requests:
storage: 30Gi
The accessModes specifies ReadWriteOnce, allowing the volume to be mounted by a single node
The storageClassName specifies the ebs-sc StorageClass for dynamic provisioning
We are requesting a 30GB EBS volume
Apply the configuration, and restart the catalog pod to ensure initialization of the database:
Verify the PersistentVolumeClaim
The recreated catalog MySQL StatefulSet now has an associated PersistentVolumeClaim.
Name: catalog-mysql
Namespace: catalog
...
Containers:
mysql:
Image: public.ecr.aws/docker/library/mysql:8.0
Port: 3306/TCP
Mounts:
/var/lib/mysql from data (rw)
Volume Claims:
Name: data
StorageClass:
Labels: <none>
Annotations: <none>
Capacity: 30Gi
Access Modes: [ReadWriteOnce]
Examine the Persistent Volucmes Claims(PVC) that was created:
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
data-catalog-mysql-0 Bound pvc-abc123... 30Gi RWO ebs-sc 2m
Inspect the PVC details:
Name: data-catalog-mysql-0
Namespace: catalog
StorageClass: ebs-sc
Status: Bound
Volume: pvc-abc123...
Annotations: pv.kubernetes.io/bind-completed: yes
pv.kubernetes.io/bound-by-controller: yes
volume.beta.kubernetes.io/storage-provisioner: ebs.csi.aws.com
Capacity: 30Gi
Access Modes: RWO
VolumeMode: Filesystem
Used By: catalog-mysql-0
The PVC is bound to a Persitent Volume (PV), provisioned using ebs.csi.aws.com with 30Gi capacity.
Inspect the PersistentVolume (PV)
Name: pvc-abc123...
Annotations: pv.kubernetes.io/provisioned-by: ebs.csi.aws.com
StorageClass: ebs-sc
Status: Bound
Claim: catalog/data-catalog-mysql-0
Reclaim Policy: Delete
Access Modes: RWO
VolumeMode: Filesystem
Capacity: 30Gi
Node Affinity:
Required Terms:
Term 0: topology.kubernetes.io/zone in [us-west-2a]
Source:
Type: CSI (a Container Storage Interface (CSI) volume source)
Driver: ebs.csi.aws.com
FSType: ext4
VolumeHandle: vol-0abc123...
ReadOnly: false
The VolumeHandle references the Amazon EBS Volume ID. The Node Affinity ensures the pod is scheduled in the same Availability Zone as the EBS volume.
Verify the EBS volume
Get the EBS Volume ID:
Display the EBS volume details:
The volume uses gp3 storage with encryption enabled.
Test data persistence
Let's verify that data persists across pod restarts. Create a test file in the MySQL data directory:
Verify the test file was created:
-rw-r--r--. 1 root root 4 Oct 11 00:39 test.txt
Now delete the pod to simulate a failure:
Wait for the StatefulSet controller to automatically recreate the pod:
Verify the test file still exists after the pod restart:
123
Success! The test file persisted across the pod restart because it's stored on the EBS volume, not in the pod's ephemeral storage. Amazon EBS is storing the data and keeping it safe and available within an AWS availability zone.
Summary
In this section, we:
- Updated the catalog MySQL database to use persistent EBS storage
- Verified that the EBS volume was created correctly
- Tested data persistence across pod restarts
With EKS Auto Mode, the EBS CSI Driver is pre-installed and managed, making it simple to provision persistent block storage for your stateful workloads.