Revise docs for hostPath volumes

- Combine warnings
- Add a heading for the section about the type field
- Improve readability

Co-authored-by: Qiming Teng <tengqm@outlook.com>
This commit is contained in:
Tim Bannister 2023-08-12 14:19:25 +01:00
parent 4813a41f26
commit a6338f8bf3
1 changed files with 70 additions and 40 deletions

View File

@ -349,56 +349,81 @@ and then removed entirely in the v1.26 release.
### hostPath {#hostpath}
{{< warning >}}
HostPath volumes present many security risks, and it is a best practice to avoid the use of
HostPaths when possible. When a HostPath volume must be used, it should be scoped to only the
required file or directory, and mounted as ReadOnly.
If restricting HostPath access to specific directories through AdmissionPolicy, `volumeMounts` MUST
be required to use `readOnly` mounts for the policy to be effective.
{{< /warning >}}
A `hostPath` volume mounts a file or directory from the host node's filesystem
into your Pod. This is not something that most Pods will need, but it offers a
powerful escape hatch for some applications.
For example, some uses for a `hostPath` are:
{{< warning >}}
Using the `hostPath` volume type presents many security risks.
If you can avoid using a `hostPath` volume, you should. For example,
define a [`local` PersistentVolume](#local), and use that instead.
* running a container that needs access to Docker internals; use a `hostPath`
of `/var/lib/docker`
* running cAdvisor in a container; use a `hostPath` of `/sys`
* allowing a Pod to specify whether a given `hostPath` should exist prior to the
Pod running, whether it should be created, and what it should exist as
If you are restricting access to specific directories on the node using
admission-time validation, that restriction is only effective when you
additionally require that any mounts of that `hostPath` volume are
**read only**. If you allow a read-write mount of any host path by an
untrusted Pod, the containers in that Pod may be able to subvert the
read-write host mount.
In addition to the required `path` property, you can optionally specify a `type` for a `hostPath` volume.
---
The supported values for field `type` are:
Take care when using `hostPath` volumes, whether these are mounted as read-only
or as read-write, because:
* Access to the host filesystem can expose privileged system credentials (such as for the kubelet) or privileged APIs
(such as the container runtime socket), that can be used for container escape or to attack other
parts of the cluster.
* Pods with identical configuration (such as created from a PodTemplate) may
behave differently on different nodes due to different files on the nodes.
{{< /warning >}}
Some uses for a `hostPath` are:
* running a container that needs access to node-level system components
(such as a container that transfers system logs to a central location,
accessing those logs using a read-only mount of `/var/log`)
* making a configuration file stored on the host system available read-only
to a {{< glossary_tooltip text="static pod" term_id="static-pod" >}};
unlike normal Pods, static Pods cannot access ConfigMaps
#### `hostPath` volume types
In addition to the required `path` property, you can optionally specify a
`type` for a `hostPath` volume.
The available values for `type` are:
<!-- empty string represented using U+200C ZERO WIDTH NON-JOINER -->
| Value | Behavior |
|:------|:---------|
| | Empty string (default) is for backward compatibility, which means that no checks will be performed before mounting the hostPath volume. |
| `""` | Empty string (default) is for backward compatibility, which means that no checks will be performed before mounting the `hostPath` volume. |
| `DirectoryOrCreate` | If nothing exists at the given path, an empty directory will be created there as needed with permission set to 0755, having the same group and ownership with Kubelet. |
| `Directory` | A directory must exist at the given path |
| `FileOrCreate` | If nothing exists at the given path, an empty file will be created there as needed with permission set to 0644, having the same group and ownership with Kubelet. |
| `File` | A file must exist at the given path |
| `Socket` | A UNIX socket must exist at the given path |
| `CharDevice` | A character device must exist at the given path |
| `BlockDevice` | A block device must exist at the given path |
| `CharDevice` | _(Linux nodes only)_ A character device must exist at the given path |
| `BlockDevice` | _(Linux nodes only)_ A block device must exist at the given path |
Watch out when using this type of volume, because:
{{< caution >}}
The `FileOrCreate` mode does **not** create the parent directory of the file. If the parent directory
of the mounted file does not exist, the pod fails to start. To ensure that this mode works,
you can try to mount directories and files separately, as shown in the
[`FileOrCreate` example](#hostpath-fileorcreate-example) for `hostPath`.
{{< /caution >}}
* HostPaths can expose privileged system credentials (such as for the Kubelet) or privileged APIs
(such as container runtime socket), which can be used for container escape or to attack other
parts of the cluster.
* Pods with identical configuration (such as created from a PodTemplate) may
behave differently on different nodes due to different files on the nodes
* The files or directories created on the underlying hosts are only writable by root. You
either need to run your process as root in a
[privileged Container](/docs/tasks/configure-pod-container/security-context/) or modify the file
permissions on the host to be able to write to a `hostPath` volume
Some files or directories created on the underlying hosts might only be
accessible by root. You then either need to run your process as root in a
[privileged container](/docs/tasks/configure-pod-container/security-context/)
or modify the file permissions on the host to be able to read from
(or write to) a `hostPath` volume.
#### hostPath configuration example
This manifest mounts `/data` on the host as `/test-pd` inside the
single container that runs within the `test-pd` Pod:
```yaml
apiVersion: v1
kind: Pod
@ -414,21 +439,26 @@ spec:
volumes:
- name: test-volume
hostPath:
# directory location on host
path: /data
# this field is optional
type: Directory
path: /data # directory location on host
type: Directory # this field is optional
```
{{< caution >}}
The `FileOrCreate` mode does not create the parent directory of the file. If the parent directory
of the mounted file does not exist, the pod fails to start. To ensure that this mode works,
you can try to mount directories and files separately, as shown in the
[`FileOrCreate`configuration](#hostpath-fileorcreate-example).
{{< /caution >}}
#### hostPath FileOrCreate configuration example {#hostpath-fileorcreate-example}
The following manifest defines a Pod that mounts `/var/local/aaa`
inside the single container in the Pod. If the node does not
already have a path `/var/local/aaa`, the kubelet creates
it as a directory and then mounts it into the Pod.
If `/var/local/aaa` already exists but is not a directory,
the Pod fails. Additionally, the kubelet attempts to make
a file named `/var/local/aaa/1.txt` inside that directory
(as seen from the host); if something already exists at
that path and isn't a regular file, the Pod fails.
Here's the example manifest:
```yaml
apiVersion: v1
kind: Pod