节点存储卷 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.

DirectoryOrCreate

指定的路劲不存在时,自动将其创建为权限是 0755 的空目录,属主属组均为 kubelet。

Directory

必须存在的目录路径

FileOrCreate

指定的路劲不能存在时,自动将其创建为权限是 0644 的空文件,属主和属组同是 kubelet。

File

必须存在的文件路径。

Socket

必须存在的 Socket 文件路径。

CharDevice

必须存在的字符设备文件路径

BlockDevice

必须存在的块设备文件路径。

  下面是一个 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

注意:

  1. 使用 hostPath 存储卷时需要注意到,不同节点上的文件或许并不完全相同,于是,那些要求事先必须存在的文件或目录的满足状态也可能会有所不同;
  2. 另外,基于资源可用状态的调度器调度 Pod 时,hostPath 资源的可用性状态不会被考虑在内;
  3. 再者,在这个节点中创建的文件或目录默认仅有 root 可写,若期望容器内的进程拥有写权限,则要么将它运行为特权容器,要么修改节点上目录路径的权限。

  那些并非执行系统级管理任务的且不受控于 Daemonset 控制器的无状态应用在 Pod 资源被重新调度至其他节点运行时,此前创建的文件或目录大多都不会存在。因此,hostPath 存储卷虽然能持久化保存数据,但对于被调度器按需调度的应用来说并不适用,这时需要用到的是独立于集群节点的持久性存储卷,即网络存储卷。