Existing architecture
In this section, we'll explore how to handle storage in Kubernetes deployments using a simple image hosting example. We'll start with an existing deployment from our sample store application and modify it to serve as an image host. The UI component is a stateless microservice, which is an excellent example for demonstrating deployments since they enable horizontal scaling and declarative state management of Pods.
One of the roles of the UI component is to serve static product images. Currently, these images are bundled into the container during the build process. However, this approach has a significant limitation - we're unable to add new images once the container is deployed. To address this limitation, we'll implement a solution using Amazon S3 Files and Kubernetes Persistent Volume to create a shared storage environment. This will allow multiple web server containers to serve assets while scaling dynamically to meet demand.
S3 Files differs from other storage options in that it provides a true NFS file system backed by Amazon S3. Your data always remains in S3, while S3 Files provides low-latency file access through a high-performance storage layer. Changes made through the file system are automatically synchronized back to your S3 bucket, and changes made directly to your bucket are reflected in the file system.
Let's examine the current Deployment's volume configuration:
Name: ui
Namespace: ui
[...]
Containers:
ui:
Image: public.ecr.aws/aws-containers/retail-store-sample-ui:1.2.1
Port: 8080/TCP
Host Port: 0/TCP
Limits:
memory: 1536Mi
Requests:
cpu: 250
memory: 1536Mi
[...]
Mounts:
/tmp from tmp-volume (rw)
Volumes:
tmp-volume:
Type: EmptyDir (a temporary directory that shares a pod's lifetime)
Medium: Memory
SizeLimit: <unset>
[...]
Looking at the Volumes section, we can see that the Deployment currently uses an EmptyDir volume type that exists only for the Pod's lifetime. This means that when the Pod is terminated, the data stored in this volume is permanently lost.
However, in the case of the UI component, the product images are currently being served as static web content via Spring Boot, so the images are not even present on the filesystem.