Use HostPath volumes

更新时间:
复制 MD 格式

A HostPath volume mounts a file or directory from a host node's file system into a pod. This volume lets a pod read and write files directly on the host node, which is useful for reading node logs, accessing configuration files, or sharing data in a development environment.

How it works

Process overview

After a pod is scheduled to a target node, the kubelet on that node mounts the HostPath volume before the container starts. The kubelet validates and prepares the host path defined in path based on the type specified in the hostPath configuration.

  • DirectoryOrCreate: Checks whether the host path exists. If it does not, the kubelet creates an empty directory with 0755 permissions. The owner and group of the directory match those of the kubelet.

  • Directory: Checks that the host path exists and is a directory. If not, the pod fails to start.

  • FileOrCreate: Checks whether the host path exists. If it does not, the kubelet creates an empty file with 0644 permissions. The owner and group of the file match those of the kubelet.

  • File: Checks that the host path exists and is a file. If not, the pod fails to start.

Once validated, the kubelet bind-mounts the host path into the container. All subsequent read and write operations on the mount point are performed directly on the host node's file system.

Usage methods

  • Mount a HostPath volume directly in a pod: Define the hostPath directly in the volumes section of the pod manifest. This method is simple but tightly couples storage to the application. It is not recommended for production applications that require long-term maintenance or may need future storage changes.

  • Mount a HostPath volume by using a PV and PVC: Define the hostPath in a standalone PV, which a pod then requests by using a PVC. This decouples storage from the application, allowing you to manage the underlying storage independently without modifying the pod configuration.

Applicability

This feature is supported only on ECS nodes. Using HostPath volumes on local disks is not recommended. This feature is not available for serverless compute resources, such as ECI and ACS.

Method one: Direct HostPath mount

  1. Create a file named pod-hostpath-direct.yaml.

    This example mounts the /data directory of the node to the /test directory in the pod.
    apiVersion: v1
    kind: Pod
    metadata:
      name: test-pod
    spec:
      containers:
      - image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6
        name: test-container
        volumeMounts:
        - mountPath: /test
          name: test-volume
      volumes:
      - name: test-volume
        hostPath:
          # Specify the path on the host node.
          path: /data
          # Specify the volume type.
          type: DirectoryOrCreate
  2. Deploy the pod.

    kubectl apply -f pod-hostpath-direct.yaml
  3. Verify the mount.

    To verify that the mount is successful, create a file inside the pod and then verify that the file exists on the node.

    1. Create a file in the pod.

      Create a file named test.txt in the /test directory (mount point) of the pod.

      kubectl exec test-pod -- sh -c 'echo "This file was created from within the Pod." > /test/test.txt'
    2. Get the name of the node where the pod is running.

      NODE_NAME=$(kubectl get pod test-pod -o jsonpath='{.spec.nodeName}')
      echo "Pod is running on node: $NODE_NAME"
    3. Verify the file on the node.

      Log on to the node and run the ls /data command to check whether the file you just created exists in the /data directory of the host node.

      The output includes the test.txt file, which indicates that the HostPath volume is successfully mounted.

Method two: Mount with a PV and PVC

  1. Create a file named pv-pvc-hostpath.yaml.

    This example creates a PV that points to the /data directory of the host node, a PVC that requests the storage, and a pod that uses the PVC.
    # --- PersistentVolume definition ---
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: hostpath-pv
      labels:
        type: local
    spec:
      capacity:
        storage: 10Gi
      accessModes:
        - ReadWriteOnce
      hostPath:
        path: "/data"
    ---
    # --- PersistentVolumeClaim definition ---
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: hostpath-pvc
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          storage: 10Gi
      # Use a selector to bind the PVC to the PV created earlier.
      selector:
        matchLabels:
          type: local
    ---
    # --- Pod definition ---
    apiVersion: v1
    kind: Pod
    metadata:
      name: test-pod-pvc
    spec:
      containers:
        - name: test-container
          image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6
          ports:
            - containerPort: 80
          volumeMounts:
            - mountPath: "/usr/share/nginx/html"
              name: storage
      volumes:
        - name: storage
          persistentVolumeClaim:
            # Reference the PVC defined earlier.
            claimName: hostpath-pvc
  2. Create the PV, PVC, and pod.

    kubectl apply -f pv-pvc-hostpath.yaml
  3. Verify the mount.

    To verify that the mount is successful, create a file inside the pod and then check if the file exists on the node.

    1. Create a file in the pod.

      Create a file named test.txt in the /usr/share/nginx/html directory (mount point) of the pod.

      kubectl exec test-pod-pvc -- sh -c 'echo "File from PV/PVC Pod." > /usr/share/nginx/html/test.txt'
    2. Get the name of the node where the pod is running.

      NODE_NAME=$(kubectl get pod test-pod-pvc -o jsonpath='{.spec.nodeName}')
      echo "Pod is running on node: $NODE_NAME"
    3. Verify the file on the node.

      Log on to the node and run the ls /data command to check whether the file you just created exists in the /data directory of the host node.

      The output includes the test.txt file, which confirms the PV/PVC-mounted HostPath volume works as expected.

Production considerations

  • Enhance security isolation

    • Mount as read-only: If your application only needs to read node data, mount the volume as read-only by setting readOnly: true in the volumeMounts section. This prevents accidental modification of files on the host node.

    • Follow the principle of least privilege: Avoid mounting the root directory (/) or sensitive system directories, such as /etc and /var, on the host node. Use a dedicated directory for the HostPath volume.

  • Monitor node resources

    • Monitor the host disk: A container that writes to a HostPath volume consumes the disk space of the node. Set up monitoring and alerting for disk partitions to prevent nodes from failing due to disk exhaustion.

    • Evaluate I/O impact: Frequent read and write operations on a HostPath volume consume the I/O resources of the node, which may affect other pods or even the stability of the kubelet. You should evaluate the performance impact.

  • A HostPath volume binds a pod directly to the physical storage of a specific node. This means that data in a HostPath volume is tied to that node and is not persisted if the pod is rescheduled to a different node.

    • HostPath volumes are not suitable for stateful applications that require high availability and persistent storage, such as databases or caches.

      • Data in a HostPath volume exists only on a single node. When a pod is rescheduled to another node due to a failure or update, access to the original data is lost.

      • Allowing a pod to access the file system of a host node breaks the isolation boundary of the container. If misconfigured (for example, by mounting the root directory /) or if the container itself has a vulnerability, the security and stability of the node can be compromised.

    • It is not suitable for nodes with a read-only root file system, such as ContainerOS.

FAQ

Does data persist if a pod is recreated?

It depends on which node the pod is scheduled to.

  • Scheduled to the same node: The new pod mounts the exact same directory on the node and can access all historical data.

  • Scheduled to a new node: The new pod mounts an empty directory on the new node. The data remains on the original node, but the new pod cannot access it.

=