How can you store persistent data for a Kubernetes application running on EKS?

How can you store persistent data for a Kubernetes application running on EKS?

Scenario:

You are deploying a Kubernetes-based web application on Amazon EKS that includes a database for storing user data and configurations. The database needs to maintain its data across pod restarts and re-scheduling, requiring persistent storage.

Solution Breakdown:

  1. Choosing the Storage Solution:

    AWS EBS (Elastic Block Store)

    • Why EBS?: AWS EBS provides block-level storage volumes that are durable and high-performance, suitable for persistent storage needs. EBS volumes can be dynamically provisioned using Kubernetes StorageClass, making them a good fit for applications requiring reliable storage that persists beyond the lifecycle of individual pods.
  2. Setting Up Persistent Storage:

    • Define a StorageClass:

      • A StorageClass defines the provisioning and configuration parameters for storage in Kubernetes. It specifies the storage provider and characteristics such as performance, encryption, and volume types. For AWS EBS, you can define a StorageClass to use the EBS CSI (Container Storage Interface) driver.

Example StorageClass YAML (ebs-sc.yaml):

        apiVersion: storage.k8s.io/v1
        kind: StorageClass
        metadata:
          name: ebs-sc
        provisioner: ebs.csi.aws.com
        volumeBindingMode: WaitForFirstConsumer
        parameters:
          csi.storage.k8s.io/fstype: xfs
          type: io1
          iopsPerGB: "50"
          encrypted: "true"
        allowedTopologies:
        - matchLabelExpressions:
          - key: topology.kubernetes.io/zone
            values:
            - us-east-2c
  • Define a PersistentVolume (PV) and PersistentVolumeClaim (PVC):

    • PersistentVolume (PV): Represents the actual storage resource and defines its attributes. PVs can be either pre-provisioned manually or dynamically provisioned by Kubernetes based on the StorageClass.

    • PersistentVolumeClaim (PVC): Requests storage from a StorageClass and binds to a PV. It specifies the amount of storage and access modes required by your application.

Example PV YAML (ebs-pv.yaml):

        apiVersion: v1
        kind: PersistentVolume
        metadata:
          name: ebs-pv
        spec:
          capacity:
            storage: 10Gi
          accessModes:
            - ReadWriteOnce
          storageClassName: ebs-sc
          hostPath:
            path: /mnt/data

Example PVC YAML (ebs-pvc.yaml):

        apiVersion: v1
        kind: PersistentVolumeClaim
        metadata:
          name: ebs-pvc
        spec:
          accessModes:
            - ReadWriteOnce
          resources:
            requests:
              storage: 10Gi
          storageClassName: ebs-sc
  • Dynamic Provisioning: If you use a StorageClass for dynamic provisioning, you typically do not need to manually create PersistentVolume resources. Kubernetes will automatically create and manage the PersistentVolume based on the StorageClass and PersistentVolumeClaim.

    • Use PVC in a Pod:
  • Modify your pod or deployment manifest to mount the PVC, making the storage available to your application.

Example Deployment YAML (app-deployment.yaml):

        apiVersion: apps/v1
        kind: Deployment
        metadata:
          name: my-app
        spec:
          replicas: 2
          selector:
            matchLabels:
              app: my-app
          template:
            metadata:
              labels:
                app: my-app
            spec:
              containers:
              - name: app-container
                image: my-app-image:latest
                volumeMounts:
                - mountPath: /data
                  name: app-storage
              volumes:
              - name: app-storage
                persistentVolumeClaim:
                  claimName: ebs-pvc
  1. Summary:

    • StorageClass: Defines how storage should be dynamically provisioned and configured. It specifies parameters like volume type, filesystem, and encryption.

    • PersistentVolume (PV): Represents an actual storage resource. When using dynamic provisioning, you do not need to manually create PVs; Kubernetes will handle it based on the StorageClass and PersistentVolumeClaim.

    • PersistentVolumeClaim (PVC): Requests storage from a StorageClass and binds to a PV. It ensures your application gets the storage it needs.

    • Pod Usage: Pods mount the storage defined by the PVC to persist data across pod restarts and re-scheduling.

By using a StorageClass to dynamically provision EBS volumes and defining PersistentVolumeClaim resources, you ensure that your Kubernetes application on EKS has reliable, scalable, and persistent storage that meets its performance and security needs. If you opt for dynamic provisioning, manual creation of PersistentVolume resources is optional, as Kubernetes handles this automatically.

Reference:

https://github.com/kubernetes-sigs/aws-ebs-csi-driver/tree/master/examples/kubernetes/storageclass