3

After spending a couple of hours I found that the relative path is not supported as a mounted path in Kubernetes. I found the reference here mountpath should be absolute if it is yes then why it doesn't have that capability of the relative path could anyone please explain a bit deeper?

    Example code:
    apiVersion: v1
    kind: Pod
    metadata:
      name: task-pv-pod
    spec:
      volumes:
        - name: task-pv-storage
          hostPath:
            # directory location on host
            # path: "./code" # this is not supporting
            path: "/var/www/html/kubernetes/code"  # this is supporting
            # this field is optional
            type: DirectoryOrCreate
      containers:
        - name: task-pv-container
          image: nginx
          ports:
            - containerPort: 80
              name: "http-server"
          volumeMounts:
            - mountPath: "/usr/share/nginx/html"
              name: task-pv-storage

Under the code directory in the above code example, I just have an index.html page

Screenshot of the project structure:

enter image description here

If I use path: "./code" then the error shows like this:

Error response from daemon: create ./code: "./code" includes invalid
characters for a local volume name, only "[a-zA-Z0-9][a-zA-Z0-9_.-]" are allowed.
If you intended to pass a host directory, use absolute path.

Thanks in advance!!

Will R.O.F.
  • 3,814
  • 1
  • 9
  • 19
Bablu Ahmed
  • 4,412
  • 5
  • 49
  • 64
  • relative means relative from the perspective of something. For example relative from where you are. When you specify a path, it makes no sense to do it relative, because you don't have any reference. – suren May 17 '20 at 15:55
  • 1
    @suren here is an issue link for better example https://github.com/kubernetes/kubernetes/issues/48749 – Bablu Ahmed May 17 '20 at 16:27
  • 1
    @suren I updated my question too could you please look at it? – Bablu Ahmed May 17 '20 at 16:50
  • The setup you sometimes see in Docker-based setups of bind-mounted code from outside Docker into a container really just doesn't work well in Kubernetes. I'd recommend building an image with your code baked into it, and pushing that to some sort of registry (Docker Hub, AWS ECR, Google GCR, ...). – David Maze May 17 '20 at 17:33
  • @DavidMaze could you give me an example guide so that I can go through this? – Bablu Ahmed May 17 '20 at 17:57
  • @BabluAhmed That's my point. when you do tree, you are already in `/var/www/html/kubernetes`. But when kubelet is mounting that volume into your pod, it is not there, so you have to give it an absolute path. – suren May 17 '20 at 18:00

1 Answers1

2

I believe the source of your confusion is that you are running a single node Cluster, like Minikube.

  • The process chain (roughly summarized) is:

Kubectl > Kube-API(master) > Kubelet agent (node) > Pod creation (as specified on the yaml manifest).

In a single node cluster all these agents are on the same computer, that's why the files in /var/www/html/kubernetes/code were mounted to the pod.

  • I'll clarify it with this example:
    • You have a cluster with 3 nodes.
    • You manage your nodes remotely, with kubectl from your notebook.

When you use hostPath the files must exist on the node, not on your notebook, because it's not the kubectl on your computer that will trigger the creation of the pod and mount the files/directories.

This is the job of the kubelet agent of the node that will create the pod and apply it's manifest. This is why you need to specify the full path of the file/dir you want to mount.


According to PersistentVolumes documentation:

Kubernetes supports hostPath for development and testing on a single-node cluster. A hostPath PersistentVolume uses a file or directory on the Node to emulate network-attached storage.

In a production cluster, you would not use hostPath. Instead a cluster administrator would provision a network resource like a Google Compute Engine persistent disk, an NFS share, or an Amazon Elastic Block Store volume. Cluster administrators can also use StorageClasses to set up dynamic provisioning.

Watch out when using hostPath type, because:

  • Pods with identical configuration (such as created from a podTemplate) may behave differently on different nodes due to different files on the nodes.
  • when Kubernetes adds resource-aware scheduling, as is planned, it will not be able to account for resources used by a hostPath.
  • 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 or modify the file permissions on the host to be able to write to a hostPath volume

If you have any question let me know in the comments.

Community
  • 1
  • 1
Will R.O.F.
  • 3,814
  • 1
  • 9
  • 19
  • 1
    it's a great explanation and really appreciable I have another request to you could you please explain the difference between initContainers and containers here https://stackoverflow.com/questions/61858409/difference-between-initcontainers-and-containers-in-kubernetes @willrof – Bablu Ahmed May 18 '20 at 18:53
  • "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 or modify the file permissions on the host to be able to write to a hostPath volume" - In Kubernetes with either docker, cri-o or containerd, the containers run as root with CAP_DAC_OVERRIDE by default. You don't need a privileged container to access hostPath mounts. – uvuv Feb 26 '21 at 18:47