What's in this module
TOPIC 1 Stateless vs stateful apps
The core question for storage design is: does your app need to remember data between restarts? Stateless apps can use ephemeral storage and be freely replaced. Stateful apps require that data outlive the container, the pod, and even the node.
Stateless
- All replicas are interchangeable
- Data is transient — can be rebuilt
- Ephemeral storage is fine
- Examples: web frontends, REST APIs, batch processors
- Scale freely: kill/replace any replica
Stateful
- Each replica has a unique identity
- Data must persist across restarts
- Persistent volume required
- Examples: databases, message brokers, caches
- Storage must match app design exactly
2. Data persistence independent of container/node — data survives crashes and rescheduling
3. Storage suited for app design — block vs file vs object depending on the workload
emptyDir volume is created when the pod is scheduled and deleted when the pod is removed — even if the pod restarts. All database data would be lost. Use a PersistentVolumeClaim backed by EBS or EFS instead.volumes: with emptyDir: {}. It is fast (can be backed by memory with medium: Memory), temporary, and requires no provisioning — perfect for caching or inter-container scratch space.TOPIC 2 StatefulSets
A StatefulSet is like a Deployment, but for workloads that need stable identities. Each pod gets a persistent ordinal name (e.g., mysql-0, mysql-1) that never changes, and its own PersistentVolumeClaim that travels with it across reschedules.
Deployment
- Pods are interchangeable
- Names are random hashes
- All pods share one PVC (or no PVC)
- Parallel scale-up/scale-down
- Any pod can be deleted/replaced
StatefulSet
- Pods have unique, stable identities
- Names: name-0, name-1…
- Each pod gets its own PVC
- Ordered deploy, scale, update
- PVC retained even if pod is deleted
2. Persistent storage per pod — each replica owns its data
3. Ordered deployment/scaling — pod N must be Running before pod N+1 starts
4. Ordered rolling updates — updates proceed in reverse ordinal order
<name>-<ordinal> — e.g., mysql-0, mysql-1. The ordinal is stable; if mysql-1 is killed, its replacement is also named mysql-1.Deployment:
<name>-<replicaset-hash>-<random> — no stable identity.TOPIC 3 Kubernetes storage objects
Four objects form the Kubernetes storage model. They separate the concerns of who provides the storage, who requests it, and how it's provisioned.
| Object | What it represents | Created by | YAML kind |
|---|---|---|---|
| emptyDir | Ephemeral scratch volume; lives and dies with the pod | Declared inline in pod spec | volumes[].emptyDir |
| PersistentVolume (PV) | Cluster-level resource representing actual storage (EBS vol, EFS mount, etc.) | Admin or dynamically by StorageClass | PersistentVolume |
| PersistentVolumeClaim (PVC) | User request for storage (capacity, access mode). Binds to a matching PV. | Developer / pod spec | PersistentVolumeClaim |
| StorageClass | Defines a "tier" of storage. Enables dynamic PV provisioning on demand. | Cluster admin | StorageClass |
PVC (PersistentVolumeClaim) is a request for storage by a user — specifying size and access mode. Kubernetes binds the PVC to a suitable PV automatically.
volumeBindingMode: WaitForFirstConsumer do?volumes[].persistentVolumeClaim.claimName). PVs are an admin/infrastructure concern. This separation of concerns means developers don't need to know the underlying storage type or backend.ReadOnlyMany (ROX) — many nodes mount read-only
ReadWriteMany (RWX) — many nodes mount read-write (EFS)
Note: EBS only supports RWO. EFS supports RWX.
allowVolumeExpansion: true in a StorageClass enable?spec.resources.requests.storage to a larger value. The EBS CSI driver will expand the underlying EBS volume without needing to delete and recreate the PVC or the pod.TOPIC 4 AWS storage options — EBS, EFS, FSx
EKS supports three families of AWS persistent storage. Choosing the right one depends on whether your workload needs block storage, shared file access, or specialized file system features.
| Feature | EBS | EFS |
|---|---|---|
| Type | Block storage (SSD/HDD) | Managed NFS file system |
| Access mode | ReadWriteOnce (one node) | ReadWriteMany (many pods/nodes) |
| Protocol | Block device | NFSv4 |
| Fargate support | ✗ Not supported | ✓ Supported |
| Capacity | Fixed at creation (expandable) | Elastic — grows/shrinks automatically |
| Best for | Databases, single-replica stateful apps | Shared content, ML training datasets, CMS |
EBS volume types
| Type | Category | Use case |
|---|---|---|
gp2 / gp3 | General purpose SSD | Most workloads — default choice |
io1 / io2 | Provisioned IOPS SSD | High-performance databases (io2 includes Block Express) |
st1 | Throughput HDD | Big data, log processing, large sequential reads |
sc1 | Cold HDD | Infrequently accessed data, lowest cost |
parameters.type: gp3).ReadWriteMany, allowing multiple pods across multiple nodes to mount and read the same file system concurrently. EBS (RWO) can only be mounted by one node at a time.2. FSx for Windows File Server — SMB/NTFS, Windows workloads
3. FSx for NetApp ONTAP — enterprise NAS features, multi-protocol
4. FSx for OpenZFS — ZFS features, low-latency NFS access
TOPIC 5 CSI drivers
The Container Storage Interface (CSI) is a standard API that lets Kubernetes communicate with any storage system through a consistent interface — without needing storage-specific code inside Kubernetes itself. Each storage type installs its own CSI driver as an EKS add-on.
EBS CSI Driver
- Provisioner:
ebs.csi.aws.com - EKS managed add-on
- Supports gp2, gp3, io1, io2, st1, sc1
- Requires IRSA for IAM permissions
- Supports volume snapshots
- Supports volume expansion
EFS CSI Driver
- Provisioner:
efs.csi.aws.com - EKS managed add-on
- Supports ReadWriteMany across pods
- Works on Fargate pods
- Requires IRSA for IAM permissions
- Uses EFS access points per PVC
ebs.csi.aws.comUsed in the
StorageClass.provisioner field. Similarly for EFS: efs.csi.aws.com. These strings tell the dynamic provisioner which CSI driver to call when a PVC is created.ec2:CreateVolume, ec2:AttachVolume, etc.). No long-lived credentials needed.eksctl, or the AWS CLI (aws eks create-addon --addon-name aws-ebs-csi-driver). EKS handles version upgrades. You must also configure an IRSA role for the driver's service account before or after installation.TOPIC 6 Storage scenario decision guide
The course gives four canonical scenarios that map directly to storage choices. Know these patterns — they are common exam questions.
| Scenario | Storage type | Why |
|---|---|---|
| Stateless multi-replica app needs scratch space | Volume (emptyDir) | No persistence needed; data is transient per pod |
| Stateful replicas need shared data access | Amazon EFS | ReadWriteMany; all replicas mount the same file system |
| Each stateful replica needs independent storage with expansion | Amazon EBS | ReadWriteOnce per pod; supports dynamic resizing |
| Fargate pods need persistent storage | Amazon EFS | EBS is not supported on Fargate; EFS NFS works over network |
App developer guidelines
- Use PVC in manifests (not PV directly)
- Specify the correct StorageClass
- Adhere to namespace storage quotas
- Request minimum storage needed
Cluster admin guidelines
- Define and maintain StorageClasses
- Set a default StorageClass for the cluster
- Monitor unbound PVCs (misconfigured requests)
- Define and enforce storage quotas per namespace
allowVolumeExpansion: true in the StorageClass.Each StatefulSet replica gets its own PVC via
volumeClaimTemplates → one EBS volume per pod, independent lifecycle, expandable. EFS would be shared across all replicas (wrong for database isolation).TOPIC 7 Kubernetes Secrets
Kubernetes Secrets store sensitive data — passwords, API tokens, SSH keys, TLS certificates. The most important thing to know: Kubernetes Secrets are NOT encrypted by default — they are only base64 encoded, which is trivially reversible.
What Secrets store
- Database credentials
- API tokens & OAuth keys
- SSH private keys
- TLS certificates
- Docker registry credentials (
imagePullSecret)
How Secrets work by default
- Values are base64 encoded (not encrypted)
- Stored in etcd (on encrypted volume)
- Injected into pods as env vars or mounted files
- Optional: enable KMS envelope encryption for etcd at rest
- base64 ≠ encryption — anyone with etcd access can decode
A. Plaintext in etcd B. AES-256 encrypted C. base64 encoded, stored in etcd on encrypted volume D. Stored in AWS KMS
The etcd volume is encrypted (disk-level), but the secret values themselves are only base64 encoded — not encrypted. KMS envelope encryption (option D) is an optional additional layer you can enable, but it is not the default.
echo "dXNlcjpwYXNz" | base64 -d → user:pass. Anyone who can read the etcd data or the Kubernetes API can immediately decode any Secret value without any key material.EncryptionConfig with an AWS KMS key ARN when creating the cluster. Kubernetes then encrypts secret values with a data key, and AWS KMS protects the envelope key. This adds a true encryption layer on top of the base64 encoding.env.valueFrom.secretKeyRef. Simple, but the value is visible in kubectl describe pod and in the process environment.2. Mounted volume (file) —
volumes[].secret.secretName + volumeMounts. The secret value appears as a file in the container; more secure and supports automatic rotation with ASCP.
TOPIC 8 AWS Secrets Manager + ASCP
The AWS Secrets and Configuration Provider (ASCP) bridges AWS Secrets Manager (and SSM Parameter Store) with Kubernetes pods. Secrets are stored and rotated in AWS — pods see them as mounted files or Kubernetes Secret objects, without manual syncing.
What ASCP provides
- Mounts secrets as files in pod volumes
- OR syncs to Kubernetes Secret objects
- Supports automatic key rotation
- Works with Secrets Manager and SSM Parameter Store
- Uses IRSA — no IAM keys in the cluster
Components required
- Secrets Store CSI Driver (
secrets-store.csi.k8s.io) - ASCP provider plugin for AWS
- IRSA role on the pod's service account
- SecretProviderClass custom resource
- Pod spec:
volumes[].csi.driver: secrets-store.csi.k8s.io
secretsmanager:GetSecretValue for only specific secret ARNs. Only pods with that service account can retrieve those secrets — no other pod can.provider: aws, the secret names/paths in Secrets Manager or SSM, and optional sync-to-Kubernetes-Secret configuration. Each pod that needs the secrets references a SecretProviderClass by name in its volume spec.secrets-store.csi.k8s.ioReferenced in the pod's volume spec under
volumes[].csi.driver. This is separate from the EBS CSI driver (ebs.csi.aws.com) and EFS CSI driver (efs.csi.aws.com) — it is a general-purpose secrets bridge, not a storage driver./mnt/secrets/MyDbPassword). This is the primary ASCP delivery method.2. Kubernetes Secret sync — ASCP can optionally create a Kubernetes Secret object that mirrors the AWS secret, so existing code that reads from env vars or K8s Secrets continues to work unchanged.
TOPIC 9 Knowledge checks (from the course)
Official course knowledge-check questions plus common exam traps for Module 08. Try to answer before flipping.
A. Plaintext B. AES-256 encrypted C. base64 encoded, stored in etcd on encrypted volume D. AWS KMS encrypted
The etcd disk is encrypted but the secret values are only base64 encoded — reversible without a key. KMS encryption (D) is an optional add-on, not the default.
name-0, name-1) and its own PersistentVolumeClaim that survives pod deletion. Deployments give pods random names and share (or forgo) PVCs.secretsmanager:GetSecretValue only for specific secret ARNs. Pods without that service account cannot retrieve the secret.ebs.csi.aws.com — referenced in the StorageClass provisioner field.EFS:
efs.csi.aws.comSecrets Store:
secrets-store.csi.k8s.io