Kubernetes Mounting Volumes in Pods: Difference between revisions
(51 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
=External= | =External= | ||
{{External|https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#volumemount-v1-core}} | |||
=Internal= | =Internal= | ||
* [[Kubernetes_Storage_Concepts#Mounting_Volumes_in_Pods|Kubernetes Storage Concepts]] | * [[Kubernetes_Storage_Concepts#Mounting_Volumes_in_Pods|Kubernetes Storage Concepts]] | ||
* [[Kubernetes_Pod_Manifest#volumeMounts|Pod Manifest | volumeMounts]] | |||
* [[Kubernetes_Security_Concepts#Pod_Security|Kubernetes Security Concepts | Pod Security]] | |||
=Overview= | =Overview= | ||
Specifies how the volumes declared in the [[Kubernetes_Pod_Manifest#volumes_manifest|volumes section of the manifest]] are to be mounted (projected) into the container's filesystem. The <tt>volumeMounts</tt> element contains an array of '''volume mounts'''. Each volume mount specifies the [[#name|volume name]] and mount details, such as the container filesystem [[#mountPath#mountPath|mount path]] and optionally a [[#subPath|subpath]] inside the external volume, relative to its root. Mounting the same volume (specified by its name) multiple times, as part of different volume mounts with different mount characteristics, such different mount points, subPaths, etc. is permitted. | |||
Mounting the same volume (specified by its name) multiple | |||
=<tt>volumeMounts</tt> Pod Manifest Section= | =<tt>volumeMounts</tt> Pod Manifest Section= | ||
Line 20: | Line 19: | ||
- [[#volume_name|name]]: 'mount-0' | - [[#volume_name|name]]: 'mount-0' | ||
[[#mountPath|mountPath]]: '/red' | [[#mountPath|mountPath]]: '/red' | ||
[[#subPath|subPath]]: 'orange' | [[#subPath|subPath]]: 'orange' | ||
This configuration specifies that the file system exposed by the volume "mount-0" will be mounted inside the container's filesystem as /red. Only a part of the volume "mount-0" filesystem will be exposed, and that is the content of its "/orange" subdirectory. | |||
==<span id='volume_name'></span><tt>name</tt>== | |||
The identifier of the volume to be mounted. Must match the name the volume specification was declared under, in the [[Kubernetes_Pod_Manifest#volumes|volumes]] section of the specification. Is the same volume is used for multiple mount points, those mount points should refer the same volume name. | |||
==<tt>mountPath</tt>== | |||
Specifies the path '''within the container filesystem''' where the volume will be mounted. Must not contain ':'. The path does NOT need to be created in advance in the container's filesystem. The mount process will create it, even if contains multiple path elements. If a directory with the same name as the mount path exists, it will be overwritten, regardless of whether it is empty or it contains files. For ownership and permission-related details, see [[#Mount_Path_Ownership_and_Permissions|Mount Path Ownership and Permissions]] below. | |||
==<tt>subPath</tt>== | |||
Specifies the relative path '''within the external volume''', relative to the root of the external volume, whose content will be mounted as container's volume. If the path does not exist on the external volume, it will be created. If not specified, defaults to "" (external volume's root). <code>subPath</code> value must be a relative, the metadata will cause a deployment error if "/" or a path that starts with "/" is used. | Specifies the relative path '''within the external volume''', relative to the root of the external volume, whose content will be mounted as container's volume. If the path does not exist on the external volume, it will be created. If not specified, defaults to "" (external volume's root). <code>subPath</code> value must be a relative, the metadata will cause a deployment error if "/" or a path that starts with "/" is used. | ||
Line 50: | Line 38: | ||
is a noop - the metadata will be accepted as correct, and the external volume's root will be mounted. | is a noop - the metadata will be accepted as correct, and the external volume's root will be mounted. | ||
==<tt>subPathExpr</tt>== | |||
Expanded path within the volume from which the container's volume should be mounted. Behaves similarly to [[#subPath|subPath]] but environment variable references $(VAR_NAME) are expanded using the container's environment. Defaults to "" (volume's root). subPathExpr and subPath are mutually exclusive. | Expanded path within the volume from which the container's volume should be mounted. Behaves similarly to [[#subPath|subPath]] but environment variable references $(VAR_NAME) are expanded using the container's environment. Defaults to "" (volume's root). subPathExpr and subPath are mutually exclusive. | ||
==<tt>readOnly</tt>== | |||
Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false. | Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false. | ||
==== | =<span id='Permissions'></span>Mount Path Ownership and Permissions= | ||
This section discusses the mountPath permissions, as seen from inside of the container. | |||
The [[#mountPath|mountPath]] path does NOT need to be created in advance in the container's filesystem. The mount process will create it, even if contains multiple path elements. | |||
In general, the mount path directory will be owned by the UID:GID ([[Kubernetes_Pod_and_Container_Security#runAsUser|runAsUser]]/[[Kubernetes_Pod_and_Container_Security#runAsGroup|runAsGroup]]) that runs the container, [[Kubernetes_Pod_and_Container_Security#fsGroup|fsGroup]] if specified, and if those are not explicitly specified in the pod manifest or the container metadata, by root. However, there are situations when the mount path will be owned by root:root even if runAsUser/runAsGroup/fsGroup are specified. | |||
If the mount path consists in multiple elements, the created intermediate path elements will be owned by root, but the final path element will be owned by the UID:GID ([[Kubernetes_Pod_and_Container_Security#runAsUser|runAsUser]]/[[Kubernetes_Pod_and_Container_Security#runAsGroup|runAsGroup]]) that runs the container, and if those are not explicitly specified in the pod manifest or the container metadata, by root. | |||
This behavior varies, though, depending on backing file system storage details: | |||
* ⚠️ On Mac/Docker Desktop Kubernetes, if the hostPath backing a volume mount is not among those listed in [[Docker_Desktop#Docker_Desktop_File_Sharing|Docker Desktop File Sharing]], then the mount path directory belongs to root:root, regardless of whether the container runs under a non-root UID:GID or not. | |||
* For fsGroup behavior see [[Kubernetes_Pod_and_Container_Security#fsGroup|fsGroup]]. | |||
Also see: | |||
{{Internal|Kubernetes_Pod_and_Container_Security#runAsUser|runAsUser}} | |||
{{Internal|Kubernetes_Pod_and_Container_Security#runAsGroup|runAsGroup}} | |||
{{Internal|Kubernetes_Pod_and_Container_Security#fsGroup|fsGroup}} | |||
==Non-Standard Mount Path Permissions== | |||
* For EFS CSI, the mount path is always owned by root:root. <font color=darkgray>Investigation in progress. A workaround to be able to use a mount path from a pod is to 1) create a directory (e.g. "dirA") on the EFS filesystem root 2) chown <runAsUser>:<runAsGroup> dirA 3) declare dirA as a subPath of the mountPath. The mount path will be projected in pod as 1111:2222 and the pod will be able to write in it.</font> | |||
==Ownership and Permissions of Newly Created Files== | |||
For Docker Desktop Kubernetes hostPath, inside the container, the files belong to [[Kubernetes_Pod_and_Container_Security#runAsUser|runAsUser]]:[[Kubernetes_Pod_and_Container_Security#runAsGroup|runAsGroup]], and if [[Kubernetes_Pod_and_Container_Security#fsGroup|fsGroup]] is used, to fsGroup. On the host filesystem, the files belong to the user that runs the docker daemon? | |||
For more details on fsGroup behavior see [[Kubernetes_Pod_and_Container_Security#fsGroup|fsGroup]]. | |||
=Use Cases= | |||
* Storage | * Storage | ||
* [[Kubernetes_Secrets_Operations#Consume_a_Secret_as_a_File|Secrets projected as files]] | * [[Kubernetes_Secrets_Operations#Consume_a_Secret_as_a_File|Secrets projected as files]] |
Latest revision as of 00:11, 31 March 2021
External
Internal
Overview
Specifies how the volumes declared in the volumes section of the manifest are to be mounted (projected) into the container's filesystem. The volumeMounts element contains an array of volume mounts. Each volume mount specifies the volume name and mount details, such as the container filesystem mount path and optionally a subpath inside the external volume, relative to its root. Mounting the same volume (specified by its name) multiple times, as part of different volume mounts with different mount characteristics, such different mount points, subPaths, etc. is permitted.
volumeMounts Pod Manifest Section
kind: Pod spec: containers: - name: 'test' ... volumeMounts: - name: 'mount-0' mountPath: '/red' subPath: 'orange'
This configuration specifies that the file system exposed by the volume "mount-0" will be mounted inside the container's filesystem as /red. Only a part of the volume "mount-0" filesystem will be exposed, and that is the content of its "/orange" subdirectory.
name
The identifier of the volume to be mounted. Must match the name the volume specification was declared under, in the volumes section of the specification. Is the same volume is used for multiple mount points, those mount points should refer the same volume name.
mountPath
Specifies the path within the container filesystem where the volume will be mounted. Must not contain ':'. The path does NOT need to be created in advance in the container's filesystem. The mount process will create it, even if contains multiple path elements. If a directory with the same name as the mount path exists, it will be overwritten, regardless of whether it is empty or it contains files. For ownership and permission-related details, see Mount Path Ownership and Permissions below.
subPath
Specifies the relative path within the external volume, relative to the root of the external volume, whose content will be mounted as container's volume. If the path does not exist on the external volume, it will be created. If not specified, defaults to "" (external volume's root). subPath
value must be a relative, the metadata will cause a deployment error if "/" or a path that starts with "/" is used.
Specifying:
subPath: ''
is a noop - the metadata will be accepted as correct, and the external volume's root will be mounted.
subPathExpr
Expanded path within the volume from which the container's volume should be mounted. Behaves similarly to subPath but environment variable references $(VAR_NAME) are expanded using the container's environment. Defaults to "" (volume's root). subPathExpr and subPath are mutually exclusive.
readOnly
Mounted read-only if true, read-write otherwise (false or unspecified). Defaults to false.
Mount Path Ownership and Permissions
This section discusses the mountPath permissions, as seen from inside of the container.
The mountPath path does NOT need to be created in advance in the container's filesystem. The mount process will create it, even if contains multiple path elements.
In general, the mount path directory will be owned by the UID:GID (runAsUser/runAsGroup) that runs the container, fsGroup if specified, and if those are not explicitly specified in the pod manifest or the container metadata, by root. However, there are situations when the mount path will be owned by root:root even if runAsUser/runAsGroup/fsGroup are specified.
If the mount path consists in multiple elements, the created intermediate path elements will be owned by root, but the final path element will be owned by the UID:GID (runAsUser/runAsGroup) that runs the container, and if those are not explicitly specified in the pod manifest or the container metadata, by root.
This behavior varies, though, depending on backing file system storage details:
- ⚠️ On Mac/Docker Desktop Kubernetes, if the hostPath backing a volume mount is not among those listed in Docker Desktop File Sharing, then the mount path directory belongs to root:root, regardless of whether the container runs under a non-root UID:GID or not.
- For fsGroup behavior see fsGroup.
Also see:
Non-Standard Mount Path Permissions
- For EFS CSI, the mount path is always owned by root:root. Investigation in progress. A workaround to be able to use a mount path from a pod is to 1) create a directory (e.g. "dirA") on the EFS filesystem root 2) chown <runAsUser>:<runAsGroup> dirA 3) declare dirA as a subPath of the mountPath. The mount path will be projected in pod as 1111:2222 and the pod will be able to write in it.
Ownership and Permissions of Newly Created Files
For Docker Desktop Kubernetes hostPath, inside the container, the files belong to runAsUser:runAsGroup, and if fsGroup is used, to fsGroup. On the host filesystem, the files belong to the user that runs the docker daemon?
For more details on fsGroup behavior see fsGroup.
Use Cases
- Storage
- Secrets projected as files