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.
Use Separate Volumes When Isolation Is Required
Instead of:
Container A
|
+----+
|
/data
|
+----+
|
Container B
use:
Container A -> /data-a
Container B -> /data-b
Example:
volumes:
- name: app-a-data
emptyDir: {}
- name: app-b-data
emptyDir: {}
This creates a clearer security boundary.
emptyDir With Memory
Kubernetes also supports memory-backed emptyDir volumes:
volumes:
- name: cache
emptyDir:
medium: Memory
This stores data in memory rather than ordinary node filesystem storage.
It can be useful for temporary sensitive data or high-speed temporary files, but memory-backed storage consumes the pod's available memory.
Set an appropriate size limit where needed:
volumes:
- name: cache
emptyDir:
medium: Memory
sizeLimit: 256Mi
Do not use memory-backed storage without considering memory pressure.
Common Permission Problems
Permission denied
Check the container identity:
id
Then:
ls -ld /data
Compare the UID/GID with the directory ownership.
One Container Cannot Read Another Container's Files
Check:
File ownership
Group ownership
File mode
fsGroupWhether both containers actually need to share the directory
Do not automatically use:
chmod 777 /data
That solves the immediate symptom by removing meaningful access restrictions.
Why chmod 777 Is a Bad Fix
This is a common shortcut:
chmod -R 777 /data
It allows virtually any user with access to the directory to read, modify, and execute files according to the filesystem permissions.
A better approach is to use a specific UID/GID and appropriate permissions.
For example:
Owner: application user
Group: application group
Permissions: only what the workload requires
The principle is least privilege, not maximum accessibility.
Important emptyDir Characteristics
Characteristic |
|
|---|---|
Created | When the pod is assigned to a node |
Data lifetime | Pod lifetime |
Persistent after pod deletion | No |
Shared between containers | Yes |
Suitable for temporary files | Yes |
Suitable for permanent application data | No |
Can use memory | Yes |
Best Practices
Run containers as non-root.
Use explicit UID/GID settings where appropriate.
Use
fsGroupwhen shared volume access requires it.Do not use
chmod 777as a default solution.Use separate
emptyDirvolumes when containers need isolation.Use
medium: Memoryonly when the memory impact is understood.Never treat
emptyDiras permanent storage.Use Pod Security controls to prevent unnecessarily privileged workloads.
Summary
emptyDir is simple temporary storage, but its permissions should still be designed carefully.
For most workloads, running containers as non-root and using appropriate UID/GID settings provides a strong baseline. When multiple containers share an emptyDir, make sure they genuinely need the same level of access.
Avoid shortcuts such as chmod 777. If stronger isolation is required, use separate volumes rather than giving every container unrestricted access to the same directory.
The main rule is straightforward: temporary storage does not mean unrestricted storage. Treat emptyDir permissions with the same least-privilege mindset used for other application resources.
Join the conversation! Your thoughts help the community grow.