Kubernetes developers often use emptyDir when a pod needs temporary storage shared between containers. It is simple, fast, and useful for caching, temporary files, and intermediate data.
But emptyDir is still a filesystem, so Linux ownership and permissions matter.
If multiple containers share the same emptyDir, incorrect permissions can allow one container to modify files that another container expects to control. Running containers as root can make the situation worse.
This article explains how emptyDir permissions work and how to configure them safely.
What Is emptyDir?
An emptyDir volume is created when a pod is assigned to a node and exists for the lifetime of that pod.
volumes:
- name: shared-data
emptyDir: {}
A container can mount it with:
volumeMounts:
- name: shared-data
mountPath: /data
The basic lifecycle is:
Pod starts
|
v
emptyDir created
|
v
Containers use /data
|
v
Pod removed
|
v
emptyDir removed
The data should therefore be considered temporary.
Why Permissions Matter
Consider two containers sharing the same directory:
Pod
|
+-- Container A -> /data
|
+-- Container B -> /data
If both containers can write everything inside /data, Container B could potentially modify files created by Container A.
For applications with different trust levels, this may be undesirable.
The goal should be:
Container A
|
+-- Access only what it needs
Container B
|
+-- Access only what it needs
Run Containers as Non-Root
A good starting point is to run applications with a dedicated UID/GID.
apiVersion: v1
kind: Pod
metadata:
name: app
spec:
securityContext:
runAsNonRoot: true
runAsUser: 10001
runAsGroup: 10001
fsGroup: 10001
containers:
- name: app
image: example/app:1.0
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
emptyDir: {}
The important settings are:
runAsNonRoot: prevents the application from running as root.runAsUser: specifies the process UID.runAsGroup: specifies the process GID.fsGroup: can provide group ownership for supported volumes.
Do not assume fsGroup behaves identically for every storage implementation. Test the actual workload.
Using fsGroup With emptyDir
For a shared temporary directory, fsGroup can simplify access.
securityContext:
runAsUser: 10001
runAsGroup: 10001
fsGroup: 10001
The application can then create files using the configured identity.
You can verify the identity from inside the container:
id
And inspect the directory:
ls -ld /data
This is much better than solving permission problems by running the entire container as root.
Shared emptyDir Between Containers
A common pattern is a producer and consumer:
Container A
|
| writes
v
/data
^
| reads
|
Container B
For example:
spec:
securityContext:
fsGroup: 10001
containers:
- name: producer
image: example/producer:1.0
volumeMounts:
- name: shared
mountPath: /data
- name: consumer
image: example/consumer:1.0
volumeMounts:
- name: shared
mountPath: /data
volumes:
- name: shared
emptyDir: {}
This works when both containers are designed to share the same access level.
If they should not have identical access, consider using separate volumes or a different application design.
Join the conversation! Your thoughts help the community grow.