节点存储卷 hostPath
hostPath 类型的存储卷是指将工作节点上某文件的目录或文件挂载于 Pod 中的一种存储卷,它可独立于 Pod 资源的生命周期,因而具有持久性。但它是工作节点本地的存储空间,仅适用于特定情况下的存储卷使用需求,例如,将工作节点上的文件系统关联为 Pod 的存储卷,从而使得容器访问节点文件系统上的数据,这一点在运行有管理任务的系统级 Pod 资源需要访问节点上的文件尤为有用。
HostPath 卷存在许多安全风险,最佳做法是尽可能避免使用 HostPath。 当必须使用 HostPath 卷时,它的范围应仅限于所需的文件或目录,并以只读方式挂载。(见:https://kubernetes.io/docs/concepts/storage/volumes/#hostpath)
如果通过 AdmissionPolicy 限制 HostPath 对特定目录的访问,则必须要求 volumeMounts
使用 readOnly
挂载以使策略生效。(见:https://kubernetes.io/docs/concepts/storage/volumes/#hostpath)
配置 hostPath 存储卷的嵌套字段共有两个:一个是用于指定工作节点上的目录路径的必选字段path;另一个是指定存储卷类型的 type,如下所示:
[root@mh-k8s-master-247-10 ~]# kubectl explain pod.spec.volumes.hostPath
KIND: Pod
VERSION: v1
RESOURCE: hostPath <Object>
DESCRIPTION:
HostPath represents a pre-existing file or directory on the host machine
that is directly exposed to the container. This is generally used for
system agents or other privileged things that are allowed to see the host
machine. Most containers will NOT need this. More info:
https://kubernetes.io/docs/concepts/storage/volumes#hostpath
Represents a host path mapped into a pod. Host path volumes do not support
ownership management or SELinux relabeling.
FIELDS:
path <string> -required-
Path of the directory on the host. If the path is a symlink, it will follow
the link to the real path. More info:
https://kubernetes.io/docs/concepts/storage/volumes#hostpath
type <string>
Type for HostPath Volume Defaults to "" More info:
https://kubernetes.io/docs/concepts/storage/volumes#hostpath
[root@mh-k8s-master-247-10 ~]#
例如,hostPath
的一些用法有:
- 运行一个需要访问 Docker 内部机制的容器;可使用
hostPath
挂载/var/lib/docker
路径。 - 在容器中运行 cAdvisor 时,以
hostPath
方式挂载/sys
。 - 允许 Pod 指定给定的
hostPath
在运行 Pod 之前是否应该存在,是否应该创建以及应该以什么方式存在。
除了必需的 path
属性之外,用户可以选择性地为 hostPath
卷指定 type
。(见:https://kubernetes.io/docs/concepts/storage/volumes/#hostpath):
Value | Behavior |
| Empty string (default) is for backward compatibility, which means that no checks will be performed before mounting the hostPath volume. |
| 指定的路劲不存在时,自动将其创建为权限是 0755 的空目录,属主属组均为 kubelet。 |
| 必须存在的目录路径 |
| 指定的路劲不能存在时,自动将其创建为权限是 0644 的空文件,属主和属组同是 kubelet。 |
| 必须存在的文件路径。 |
| 必须存在的 Socket 文件路径。 |
| 必须存在的字符设备文件路径 |
| 必须存在的块设备文件路径。 |
下面是一个 hostPath 的示例(示例参考:https://kubernetes.io/docs/concepts/storage/volumes/#hostpath):
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /test-pd
name: test-volume
volumes:
- name: test-volume
hostPath:
# directory location on host
path: /data
# this field is optional
type: Directory
注意:FileOrCreate
模式不会负责创建文件的父目录。 如果欲挂载的文件的父目录不存在,Pod 启动会失败。 为了确保这种模式能够工作,可以尝试把文件和它对应的目录分开挂载,如下所示:
apiVersion: v1
kind: Pod
metadata:
name: test-webserver
spec:
containers:
- name: test-webserver
image: k8s.gcr.io/test-webserver:latest
volumeMounts:
- mountPath: /var/local/aaa
name: mydir
- mountPath: /var/local/aaa/1.txt
name: myfile
volumes:
- name: mydir
hostPath:
# 确保文件所在目录成功创建。
path: /var/local/aaa
type: DirectoryOrCreate
- name: myfile
hostPath:
path: /var/local/aaa/1.txt
type: FileOrCreate
注意:
- 使用 hostPath 存储卷时需要注意到,不同节点上的文件或许并不完全相同,于是,那些要求事先必须存在的文件或目录的满足状态也可能会有所不同;
- 另外,基于资源可用状态的调度器调度 Pod 时,hostPath 资源的可用性状态不会被考虑在内;
- 再者,在这个节点中创建的文件或目录默认仅有 root 可写,若期望容器内的进程拥有写权限,则要么将它运行为特权容器,要么修改节点上目录路径的权限。
那些并非执行系统级管理任务的且不受控于 Daemonset 控制器的无状态应用在 Pod 资源被重新调度至其他节点运行时,此前创建的文件或目录大多都不会存在。因此,hostPath 存储卷虽然能持久化保存数据,但对于被调度器按需调度的应用来说并不适用,这时需要用到的是独立于集群节点的持久性存储卷,即网络存储卷。