如何在docker-for-desktop中访问PersistentVolume文件?

7

我想要在我的本地电脑(macOS)上访问和编辑KubernetesPersistentVolume中的文件,但我不知道在哪里可以找到这些文件!

我将hostPath指向了/tmp/wordpress-volume,但是我无法在任何地方找到它。我错过了什么隐藏的秘密吗?

我正在一个docker-for-desktop集群Version 2.0.0.2 (30215)上使用以下配置。

PersistentVolume

kind: PersistentVolume
metadata:
  name: wordpress-volume
spec:
  # ...
  hostPath:
    path: /tmp/wordpress-volume

PersistentVolumeClaim

kind: PersistentVolumeClaim
metadata:
  name: wordpress-volume-claim
# ...

部署

kind: Deployment
metadata:
  name: wordpress
# ...
spec:
  containers:
  - image: wordpress:4.8-apache
    # ...
    volumeMounts:
    - name: wordpress-volume
      mountPath: /var/www/html
  volumes:
  - name: wordpress-volume
    persistentVolumeClaim:
      claimName: wordpress-volume-claim
4个回答

10

感谢 @aman-tuladhar 和在互联网上浪费的一些时间,我发现你只需要确保为你的 PersistentVolumePersistentVolumeClaim 设置storageClassName即可。

根据文档,如果你想避免Kubernetes动态生成PersistentVolumes时忽略静态声明的部分,你可以将其设置为空字符串" "

在我的情况下,我设置了storageClassName: manual

PersistentVolume

kind: PersistentVolume
metadata:
  name: wordpress-volume
spec:
  # ...
  storageClassName: manual
  hostPath:
    path: /tmp/wordpress-volume

持久卷索取(PersistentVolumeClaim)

kind: PersistentVolumeClaim
metadata:
  name: wordpress-volume-claim
spec:
  storageClassName: manual
  # ...

只要mountPath设置为绝对路径,它就可以与 docker-for-desktop 集群一起使用。

参考资料:


这个答案在最新版本的Docker Desktop for macOS(截至目前为止的v4.1.1)中不起作用。它最终会使用Docker VM内部的该文件夹。话虽如此,local-storage似乎也在做同样的事情。 - Rads
2
更正我部分错误的评论。解决方案有效,但不适用于任何非用户拥有的目录。如果它不是用户拥有的目录链(例如:/tmp/xyz),Docker桌面会在静默中从Docker VM挂载文件夹。然而,对于 /Users/$(whoami)/ 目录有效。这种机制没有在任何地方记录,非常令人沮丧。 - Rads
对于那些惊讶于找不到文档的人:manual 可以是任何字符串,例如 foo,这仍然有效。此外,您可能还需要添加一些选择器来确保 PVC 仅附加到预期的 PV。 - andrewdotn
PS:pvc规范的"volumeName"只有在资源创建时指定pv规范的"claimRef.name"和"claimRef.namespace"与所需的pv匹配时才会“起作用”。但是,如果您将它留空,一旦绑定,您可以从该字段读取pv名称。 - andrewdotn

4
首先要记住的是,Kubernetes 运行在 minikube 集群上。 minikube 本身运行在虚拟机上。因此,该路径不会在您的主机上,而是在虚拟机中的路径。
但是使用 minikube 我们可以很容易地做到这一点。首先,您必须将主机目录挂载到 minikube 上。
(如果您正在使用云提供商,则会有一些方法来创建存储。对于 GCE,您可以使用 gcePersistentDiskminikube mount /path/to/dir/to/mount:/vm-mount-path 现在
kind: PersistentVolume
metadata:
  name: wordpress-volume
spec:
  # ...
  hostPath:
    path: /vm-mount-path

如果您创建此资源,则应将文件保存在您的主机上。 按照此minikube文档进行更详细的了解

我本来想使用docker-for-desktop,但目前我会转而使用Minikube,因为它似乎在这方面有更多的文档。 - a.barbieri
嗯,你还记得你在哪里看到它的吗?我找到了这篇文章,它说:“为了让pvc实际绑定到pv上,您需要在yaml定义中给它们两个都分配相同的storageClassName。”(https://medium.com/@snowmiser/kubernetes-binding-persistentvolumes-and-persistentvolumeclaims-33323b907722) - a.barbieri
我不记得在哪里看到的,但是如果您没有使用StorageClass资源,可能需要在创建PVC的yaml文件中添加spec.storageClassName: ""。这将确保使用现有的PV而不是创建新的PV。 - A0__oN
1
是的,我找到了另一篇谈论同样事情的文章在这里 - a.barbieri

3

如果是在MacOS和Docker for Mac中使用Kubernetes,如何寻找基于目录的本地卷在虚拟机中的真实位置。

1)创建一个带有唯一路径的新持久卷:

blablabla.yml:

kind: PersistentVolume
apiVersion: v1
metadata:
  name: blablabla
spec:
  storageClassName: manual
  capacity:
    storage: 1G
  accessModes:
    - ReadWriteMany
  hostPath:
    path: "/mnt/blablabla"

kubectl apply -f blablabla.yml

2) Log into VM:

screen ~/Library/Containers/com.docker.docker/Data/vms/0/tty
# then press Enter

3) 找到您的音量:

find / -name blablabla
/containers/services/docker/rootfs/mnt/blablabla # <= got it!
/containers/services/docker/tmp/upper/mnt/blablabla

4) 退出screen:Ctrl-a k y,从screen分离:Ctrl-a d

注意

有时候会出现破损的screen会话,stdout可能会显示垃圾字符,但stdin仍然可以正常使用。此时,尝试终止所有screen会话并重新连接到第一个会话,或者重启你的Docker for Mac。


在问题路径(/tmp/wordpress-volume)的情况下,可以在/containers/services/docker/rootfs/tmp/wordpress-volume中找到它。 拥有像Lens这样的K8S IDE允许您登录VM / Node而无需使用屏幕。 - Shondeslitch
在最新的 macOS 版本中,tty(来自步骤2)将无法使用。替代方法是:docker run -it --privileged --pid=host justincormack/nsenter1 - abhinavroy23

2
我创建了一个 PersistentVolume 并使用了 storageClassName(在下面的示例中为 local-storage)。请确保将 path/Users/user/data-pv1)替换为您的 Mac 上的实际路径。
apiVersion: v1
kind: PersistentVolume
metadata:
  name: local-pv1
spec:
  capacity:
    storage: 30Gi
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: local-storage
  local:
    path: /Users/user/data-pv1
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - docker-desktop

如果您想访问hostPath,则需要使用nsenter:
docker run -it --rm --privileged --pid=host alpine:edge nsenter -t 1 -m -u -n -i sh

or nsenter1

docker run -it --rm --privileged --pid=host justincormack/nsenter1

并导航到以下目录:

/var/lib/k8s-pvs

感谢您,这个答案解决了我的问题。请特别关注 /spec/local/path。大多数示例使用 hostPath/path 设置,它只在 Docker 容器主机上创建文件夹。 - Michel Rugenbrink
更正我部分不正确的评论。答案(以及标记为接受的答案)是正确的,但是对于任何非用户拥有的目录都不起作用。如果它不是用户拥有的目录链(例如:/tmp/xyz),Docker桌面会在后台挂载来自Docker VM的文件夹。但是,对于 /Users/$(whoami)/ 目录有效。这种机制没有在任何地方得到记录,非常令人沮丧。 - Rads

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接