Read-only root filesystem
Read-only root filesystem
Read-only root filesystem
Starting in Astro Private Cloud (APC) 1.0, the root filesystem of every platform container and every Airflow Deployment container is read-only. Kubernetes enforces this by setting readOnlyRootFilesystem: true on each container’s securityContext, which reduces the container attack surface.
This document explains the behavior, lists the locations that are writable by default, and shows how to add additional writable directories when an application needs to write outside of those paths.
readOnlyRootFilesystem: true./usr/local/airflow and /tmp are mounted as emptyDir volumes so that Airflow, your Dags, and provider packages can continue to write to these standard locations./, /etc, /var, and /home, are read-only. Any process that tries to create or modify a file outside of a mounted writable volume fails with a Read-only file system error.If your application or Dag needs to write to disk, write to /usr/local/airflow/logs if the data is log output, or to a directory you have explicitly mounted with extraVolumes and extraVolumeMounts. Writing to other paths under /usr/local/airflow fails because the root filesystem is read-only.
extraVolumes and extraVolumeMountsWhen an application must write to a path that isn’t writable by default, mount an emptyDir (or other ephemeral volume) at that path using the extraVolumes and extraVolumeMounts keys on the relevant component.
The Airflow Helm chart exposes extraVolumes and extraVolumeMounts on each Airflow component, including:
airflow.schedulerairflow.workersairflow.triggererairflow.dagProcessorairflow.apiServerairflow.webserverairflow.pgbouncerairflow.redisairflow.statsdairflow.flowerdagDeployThe following example mounts an emptyDir at /opt/cache on Airflow workers so a provider package can write its cache:
Apply the same pattern to other components by setting extraVolumes and extraVolumeMounts under the appropriate component key.
By default, emptyDir volumes can grow until they exhaust the node’s ephemeral storage. Set sizeLimit to bound the volume:
For more guidance on sizing ephemeral storage, see Ephemeral storage configuration.
extraVolumes mounts an empty directory at the target path, which hides any files that were baked into the container image at that location. If your application reads files from a path it also needs to write to, use an init container to copy the image contents into the writable volume before the main container starts.
The following example makes /opt/app writable on Airflow workers while preserving files from the image:
The init container shares the emptyDir volume with the main container. When the main container starts, the volume already contains the files from the image, and the main container can also write to it.
Some applications can be configured to write to a different location through environment variables. When that option exists, mount a writable volume with extraVolumes and extraVolumeMounts as shown earlier, and then point the application at that mount path.
For example, mount an emptyDir at /tmp on Airflow workers and set TMPDIR so libraries that respect it write there:
Check each application’s documentation for the variables it supports, such as TMPDIR, HOME, XDG_CACHE_HOME, or vendor-specific cache directory variables. Combining a single writable volume with an environment variable is often cheaper than mounting volumes at each path the application touches.
If a Pod or task fails with an error such as Read-only file system, Permission denied, or Errno 30, the application is attempting to write to a path that isn’t backed by a writable volume.
/usr/local/airflow/logs or a directory you mounted with extraVolumes, verify that the Pod has the expected volumes with kubectl describe pod <pod-name>.extraVolumes and extraVolumeMounts for the component that runs the application, as shown in the previous sections.