Kubernetes
readOnlyRootFilesystem
directory exemption
container security
configuration management

How to exempt a directory when using readOnlyRootFilesystem in kubernetes?

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

When readOnlyRootFilesystem is enabled, the container root layer cannot be written. You cannot mark a subdirectory inside that same root layer as writable directly. The correct approach is to mount a writable volume at the path your app needs, effectively replacing that directory with writable storage.

How Exemption Really Works

In Kubernetes, the root filesystem and mounted volumes are separate filesystems. With root set to read-only, write attempts fail unless they target a mounted volume that allows writes. So directory exemption is done by mounting emptyDir, persistent volume, or projected storage at that specific path.

Base Security Context with Read-Only Root

Start with a strict container security context.

yaml
1apiVersion: v1
2kind: Pod
3metadata:
4  name: readonly-app
5spec:
6  containers:
7    - name: app
8      image: ghcr.io/example/app:1.0.0
9      securityContext:
10        readOnlyRootFilesystem: true
11        runAsNonRoot: true
12        allowPrivilegeEscalation: false

At this stage, any write to root paths such as /var/tmp fails unless a writable volume is mounted.

Exempt One Directory with emptyDir

For scratch space or cache files that can be lost on restart, use emptyDir.

yaml
1apiVersion: v1
2kind: Pod
3metadata:
4  name: readonly-with-tmp
5spec:
6  containers:
7    - name: app
8      image: ghcr.io/example/app:1.0.0
9      securityContext:
10        readOnlyRootFilesystem: true
11        runAsNonRoot: true
12      volumeMounts:
13        - name: tmp
14          mountPath: /tmp
15  volumes:
16    - name: tmp
17      emptyDir: {}

Now /tmp is writable while root stays read-only.

Exempt Persistent Data Directory

If data must survive pod restart, mount a persistent volume claim.

yaml
1apiVersion: v1
2kind: Pod
3metadata:
4  name: readonly-with-data
5spec:
6  containers:
7    - name: app
8      image: ghcr.io/example/app:1.0.0
9      securityContext:
10        readOnlyRootFilesystem: true
11      volumeMounts:
12        - name: data
13          mountPath: /var/lib/myapp
14  volumes:
15    - name: data
16      persistentVolumeClaim:
17        claimName: myapp-data-pvc

This is the preferred pattern for stateful workloads.

Use subPath for Narrower Mount Scope

When one shared volume backs multiple paths, subPath can isolate directories.

yaml
1volumeMounts:
2  - name: shared
3    mountPath: /var/cache/myapp
4    subPath: cache

Be careful that subPath directories exist and permissions are correct, or container startup can fail.

Permissions and Ownership

Writable volume mounts often fail due to uid and gid mismatch. If your app runs as non-root, set pod fsGroup or pre-create volume permissions in init workflows.

yaml
securityContext:
  fsGroup: 2000

Also ensure your app writes only to intended mount paths. Hidden writes to default locations such as /root or /var/run can still fail under read-only root.

Validate at Runtime

After deployment, verify behavior quickly:

bash
kubectl exec -it readonly-with-tmp -- sh -c 'echo ok > /tmp/probe && cat /tmp/probe'
kubectl exec -it readonly-with-tmp -- sh -c 'echo fail > /etc/probe'

First command should succeed. Second should fail, confirming root remains read-only.

Deployment Policy and Validation

If your cluster enforces Pod Security standards or admission policies, verify that writable mounts and security settings remain compliant. A useful practice is adding a policy check in CI with your chosen admission tooling and then running an integration smoke test that writes only to approved mount paths. This confirms your manifest both satisfies security controls and still meets runtime write requirements.

Common Pitfalls

A common mistake is expecting Kubernetes to whitelist a writable path inside root without a volume mount. That is not supported. Another issue is mounting writable storage but forgetting application configuration still points writes to old read-only paths. Teams also overlook permissions on mounted volumes, especially with non-root containers, causing false assumptions that read-only root is broken. Finally, mounting over system-critical paths can hide required files, so choose mount targets carefully.

Summary

  • You cannot directly exempt a root subdirectory without mounting a volume.
  • Keep readOnlyRootFilesystem enabled for baseline hardening.
  • Mount emptyDir for ephemeral writes and PVCs for persistent writes.
  • Align user permissions with mounted storage ownership.
  • Test writable and non-writable paths to verify security intent.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.