Skip to content

Commit 8bbc076

Browse files
authored
Merge pull request #42510 from sftim/20230812_revise_hostpath_docs
Revise details for hostPath volumes
2 parents eabc417 + ba4579e commit 8bbc076

File tree

1 file changed

+117
-48
lines changed

1 file changed

+117
-48
lines changed

content/en/docs/concepts/storage/volumes.md

Lines changed: 117 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -349,92 +349,161 @@ and then removed entirely in the v1.26 release.
349349

350350
### hostPath {#hostpath}
351351

352+
A `hostPath` volume mounts a file or directory from the host node's filesystem
353+
into your Pod. This is not something that most Pods will need, but it offers a
354+
powerful escape hatch for some applications.
355+
352356
{{< warning >}}
353-
HostPath volumes present many security risks, and it is a best practice to avoid the use of
354-
HostPaths when possible. When a HostPath volume must be used, it should be scoped to only the
355-
required file or directory, and mounted as ReadOnly.
357+
Using the `hostPath` volume type presents many security risks.
358+
If you can avoid using a `hostPath` volume, you should. For example,
359+
define a [`local` PersistentVolume](#local), and use that instead.
360+
361+
If you are restricting access to specific directories on the node using
362+
admission-time validation, that restriction is only effective when you
363+
additionally require that any mounts of that `hostPath` volume are
364+
**read only**. If you allow a read-write mount of any host path by an
365+
untrusted Pod, the containers in that Pod may be able to subvert the
366+
read-write host mount.
367+
368+
---
369+
370+
Take care when using `hostPath` volumes, whether these are mounted as read-only
371+
or as read-write, because:
356372

357-
If restricting HostPath access to specific directories through AdmissionPolicy, `volumeMounts` MUST
358-
be required to use `readOnly` mounts for the policy to be effective.
373+
* Access to the host filesystem can expose privileged system credentials (such as for the kubelet) or privileged APIs
374+
(such as the container runtime socket), that can be used for container escape or to attack other
375+
parts of the cluster.
376+
* Pods with identical configuration (such as created from a PodTemplate) may
377+
behave differently on different nodes due to different files on the nodes.
359378
{{< /warning >}}
360379

361-
A `hostPath` volume mounts a file or directory from the host node's filesystem
362-
into your Pod. This is not something that most Pods will need, but it offers a
363-
powerful escape hatch for some applications.
380+
Some uses for a `hostPath` are:
381+
382+
* running a container that needs access to node-level system components
383+
(such as a container that transfers system logs to a central location,
384+
accessing those logs using a read-only mount of `/var/log`)
385+
* making a configuration file stored on the host system available read-only
386+
to a {{< glossary_tooltip text="static pod" term_id="static-pod" >}};
387+
unlike normal Pods, static Pods cannot access ConfigMaps
364388

365-
For example, some uses for a `hostPath` are:
389+
#### `hostPath` volume types
366390

367-
* running a container that needs access to Docker internals; use a `hostPath`
368-
of `/var/lib/docker`
369-
* running cAdvisor in a container; use a `hostPath` of `/sys`
370-
* allowing a Pod to specify whether a given `hostPath` should exist prior to the
371-
Pod running, whether it should be created, and what it should exist as
391+
In addition to the required `path` property, you can optionally specify a
392+
`type` for a `hostPath` volume.
372393

373-
In addition to the required `path` property, you can optionally specify a `type` for a `hostPath` volume.
394+
The available values for `type` are:
374395

375-
The supported values for field `type` are:
396+
<!-- empty string represented using U+200C ZERO WIDTH NON-JOINER -->
376397

377398
| Value | Behavior |
378399
|:------|:---------|
379-
| | Empty string (default) is for backward compatibility, which means that no checks will be performed before mounting the hostPath volume. |
400+
| `‌""` | Empty string (default) is for backward compatibility, which means that no checks will be performed before mounting the `hostPath` volume. |
380401
| `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. |
381402
| `Directory` | A directory must exist at the given path |
382403
| `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. |
383404
| `File` | A file must exist at the given path |
384405
| `Socket` | A UNIX socket must exist at the given path |
385-
| `CharDevice` | A character device must exist at the given path |
386-
| `BlockDevice` | A block device must exist at the given path |
406+
| `CharDevice` | _(Linux nodes only)_ A character device must exist at the given path |
407+
| `BlockDevice` | _(Linux nodes only)_ A block device must exist at the given path |
387408

388-
Watch out when using this type of volume, because:
409+
{{< caution >}}
410+
The `FileOrCreate` mode does **not** create the parent directory of the file. If the parent directory
411+
of the mounted file does not exist, the pod fails to start. To ensure that this mode works,
412+
you can try to mount directories and files separately, as shown in the
413+
[`FileOrCreate` example](#hostpath-fileorcreate-example) for `hostPath`.
414+
{{< /caution >}}
389415

390-
* HostPaths can expose privileged system credentials (such as for the Kubelet) or privileged APIs
391-
(such as container runtime socket), which can be used for container escape or to attack other
392-
parts of the cluster.
393-
* Pods with identical configuration (such as created from a PodTemplate) may
394-
behave differently on different nodes due to different files on the nodes
395-
* The files or directories created on the underlying hosts are only writable by root. You
396-
either need to run your process as root in a
397-
[privileged Container](/docs/tasks/configure-pod-container/security-context/) or modify the file
398-
permissions on the host to be able to write to a `hostPath` volume
416+
Some files or directories created on the underlying hosts might only be
417+
accessible by root. You then either need to run your process as root in a
418+
[privileged container](/docs/tasks/configure-pod-container/security-context/)
419+
or modify the file permissions on the host to be able to read from
420+
(or write to) a `hostPath` volume.
399421

400422
#### hostPath configuration example
401423

402-
```yaml
424+
{{< tabs name="hostpath_examples" >}}
425+
{{< tab name="Linux node" codelang="yaml" >}}
426+
---
427+
# This manifest mounts /data/foo on the host as /foo inside the
428+
# single container that runs within the hostpath-example-linux Pod.
429+
#
430+
# The mount into the container is read-only.
403431
apiVersion: v1
404432
kind: Pod
405433
metadata:
406-
name: test-pd
434+
name: hostpath-example-linux
407435
spec:
436+
os: { name: linux }
437+
nodeSelector:
438+
kubernetes.io/os: linux
408439
containers:
409-
- image: registry.k8s.io/test-webserver
410-
name: test-container
440+
- name: example-container
441+
image: registry.k8s.io/test-webserver
411442
volumeMounts:
412-
- mountPath: /test-pd
413-
name: test-volume
443+
- mountPath: /foo
444+
name: example-volume
445+
readOnly: true
414446
volumes:
415-
- name: test-volume
447+
- name: example-volume
448+
# mount /data/foo, but only if that directory already exists
416449
hostPath:
417-
# directory location on host
418-
path: /data
419-
# this field is optional
420-
type: Directory
421-
```
422-
423-
{{< caution >}}
424-
The `FileOrCreate` mode does not create the parent directory of the file. If the parent directory
425-
of the mounted file does not exist, the pod fails to start. To ensure that this mode works,
426-
you can try to mount directories and files separately, as shown in the
427-
[`FileOrCreate`configuration](#hostpath-fileorcreate-example).
428-
{{< /caution >}}
450+
path: /data/foo # directory location on host
451+
type: Directory # this field is optional
452+
{{< /tab >}}
453+
{{< tab name="Windows node" codelang="yaml" >}}
454+
---
455+
# This manifest mounts C:\Data\foo on the host as C:\foo, inside the
456+
# single container that runs within the hostpath-example-windows Pod.
457+
#
458+
# The mount into the container is read-only.
459+
apiVersion: v1
460+
kind: Pod
461+
metadata:
462+
name: hostpath-example-windows
463+
spec:
464+
os: { name: windows }
465+
nodeSelector:
466+
kubernetes.io/os: windows
467+
containers:
468+
- name: example-container
469+
image: microsoft/windowsservercore:1709
470+
volumeMounts:
471+
- name: example-volume
472+
mountPath: "C:\\foo"
473+
readOnly: true
474+
volumes:
475+
# mount C:\Data\foo from the host, but only if that directory already exists
476+
- name: example-volume
477+
hostPath:
478+
path: "C:\\Data\\foo" # directory location on host
479+
type: Directory # this field is optional
480+
{{< /tab >}}
481+
{{< /tabs >}}
429482

430483
#### hostPath FileOrCreate configuration example {#hostpath-fileorcreate-example}
431484

485+
The following manifest defines a Pod that mounts `/var/local/aaa`
486+
inside the single container in the Pod. If the node does not
487+
already have a path `/var/local/aaa`, the kubelet creates
488+
it as a directory and then mounts it into the Pod.
489+
490+
If `/var/local/aaa` already exists but is not a directory,
491+
the Pod fails. Additionally, the kubelet attempts to make
492+
a file named `/var/local/aaa/1.txt` inside that directory
493+
(as seen from the host); if something already exists at
494+
that path and isn't a regular file, the Pod fails.
495+
496+
Here's the example manifest:
497+
432498
```yaml
433499
apiVersion: v1
434500
kind: Pod
435501
metadata:
436502
name: test-webserver
437503
spec:
504+
os: { name: linux }
505+
nodeSelector:
506+
kubernetes.io/os: linux
438507
containers:
439508
- name: test-webserver
440509
image: registry.k8s.io/test-webserver:latest

0 commit comments

Comments
 (0)