docker for Windows + WSL2におけるKubernetesのhostPathの利用


docker for Windows + WSL2でKubernetesのVolumesの1つ、hostPathを使う方法を調査した。

動作環境

  • Windows10 Pro 19041.172
  • WSL2
  • docker for Windows 2.2.0.5
    • Settings→General→Enable the experimental WSL2 based engine を有効にしていること
    • Linux containerを利用していること

ホストのディレクトリを使用する

以下のようにhostPathを指定する。

host-pod.yml
apiVersion: v1
kind: Pod
metadata:
  name: test
spec:
  containers:
    - name: test
      image: alpine:latest
      command: ["/bin/sh", "-c", "tail -f /dev/null"]
      volumeMounts:
      - name: myvolume
        mountPath: /data
  volumes:
    - name: myvolume
      hostPath:
        path: /run/desktop/mnt/host/c/mydata

上記の場合、ホスト(Windows)のC:\mydataがマウントされる。local volumeでも同様の指定が可能。
自宅の環境ではこの方法はディスクアクセスが遅い。次の方法のほうが高速にアクセスできる。

docker-desktop Distroのディレクトリを使用する

docker for Windows + WSL2のバックエンドであるdocker-desktop Distroのディレクトリをマウントする。

docker-desktop-pod.yml
apiVersion: v1
kind: Pod
metadata:
  name: test
spec:
  containers:
    - name: test
      image: alpine:latest
      command: ["/bin/sh", "-c", "tail -f /dev/null"]
      volumeMounts:
      - name: myvolume
        mountPath: /data
  volumes:
    - name: myvolume
      hostPath:
        path: /var/lib/k8s-pvs/mydata

作成されるmydataディレクトリは以下で確認できる。

C:\Users\docker>wsl -d -docker-desktop
My-PC:/tmp/docker-desktop-root/mnt/host/c/Users/docker# ls -l /mnt/host/wsl/docker-desktop-data/data/k8s-pvs
total 16
drwxr-xr-x    4 root     root          4096 Feb 25 12:36 data-redmine-mariadb-0
drwxr-xr-x    3 root     root          4096 Apr 15 13:31 jenkins
drwxr-xr-x    2 root     root          4096 Apr 16 13:35 mydata
drwxr-xr-x    4 root     root          4096 Feb 25 12:36 redmine

上記の/var/lib/k8s-pvsは、helmでJenkinsなどをインストールした際に作成されるPersistentVolumeで使用されている。
他にも以下の指定が可能

path マウントされるdocker-desktop Distroのパス
/var/lib/mydata /mnt/host/wsl/docker-desktop-data/data/mydata
/var/lib/docker/volumes /mnt/host/wsl/docker-desktop-data/data/docker/volumes

上記の2つ目はdocker volume createでvolumeが作成されるディレクトリなので、docker volume createで作成したvolumeをPodにマウントすることができる。
逆に以下はマウントしてデータを書き込んだとしてもdocker for Windowsを再起動するとデータが消えてしまう。

path マウントされるdocker-desktop Distroのパス
/home /mnt/version-pack/containers/services/docker/rootfs/home
/run/desktop/tmp 不明

マウントしたvolumeへの書き込みでPermission deniedが発生するときの対応

以下の方法のいずれかで解決することができる。

マウントするディレクトリのアクセス権を変更する

C:\Users\docker>wsl -d -docker-desktop
My-PC:/tmp/docker-desktop-root/mnt/host/c/Users/docker# chmod 777 /mnt/host/wsl/docker-desktop-data/data/mydata
My-PC:/tmp/docker-desktop-root/mnt/host/c/Users/docker# ls -l /mnt/host/wsl/docker-desktop-data/data
total 220
drwxr-xr-x    5 root     root          4096 Feb 24 13:01 cni
drwx------   10 root     root          4096 Feb 24 13:00 containerd
drwx--x--x   16 root     root          4096 Apr 16 13:04 docker
-rw-r--r--    1 root     root        173663 Apr 16 13:04 docker-desktop.conf
drwxr-xr-x    3 root     root          4096 Feb 24 13:00 dockershim
drwx------    3 root     root          4096 Apr 16 13:05 etcd
drwxr-xr-x    5 root     root          4096 Apr 16 13:44 k8s-pvs
drwxr-xr-x    4 root     root          4096 Feb 24 13:00 kubeadm
drwx------    9 root     root          4096 Feb 24 13:00 kubelet
drwxr-xr-x    3 root     root          4096 Feb 24 13:00 kubelet-plugins
-rw-r--r--    1 root     root            37 Feb 24 13:00 machine-id
drwxrwxrwx    2 root     root          4096 Apr 16 13:53 mydata
drwxr-xr-x    3 root     root          4096 Feb 24 13:00 nfs

PodのsecurityContextを設定する

pod.yml
apiVersion: v1
kind: Pod
metadata:
  name: test
spec:
  securityContext:
    runAsUser: 0
    runAsGroup: 0
    fsGroup: 0
  containers:
    - name: test
      image: alpine:latest
      command: ["/bin/sh", "-c", "tail -f /dev/null"]
      volumeMounts:
      - name: myvolume
        mountPath: /data
  volumes:
    - name: myvolume
      hostPath:
        path: /var/lib/mydata

MobyLinuxVMの場合

Settings→General→Enable the experimental WSL2 based engine を無効にした場合、hostPathの指定は以下のようになる。

path マウントされるディレクトリ
/host_mnt/c/mydata ホスト(Windows)のC:\mydata
/var/lib/docker/volumes MobyLinuxVMの/var/lib/docker/volumes

※ホスト(Windows)のディレクトリをマウントするにはSettings→Resources→FILE SHARINGで該当ドライブにチェックを入れておく必要がある。
※MobyLinuxVMの/homeや/tmpはdocker for Windows再起動時にクリアされてしまうのでデータ保存には向かない。
※MobyLinuxVMの/var/lib/docker/volumesを使う方法が妥当かどうかまで調べていない。

MobyLinuxVMのファイルシステムは以下の方法で確認できる

C:\Users\docker>docker run --net=host --ipc=host --uts=host --pid=host -it --security-opt=seccomp=unconfined --privileged --rm -v /:/host alpine /bin/sh
/ # ls -l /host/var/lib/docker/volumes
total 60
drwxr-xr-x    3 root     root          4096 Mar 14 12:03 50f4601e34490446d2a2bf15131d26bb3cff1fa701b65a54aa49859b529d174c
drwxr-xr-x    3 root     root          4096 Mar 14 15:15 73104b426cb6b5288c8dc66fc155d424e8454b49d30765a1a0205b4f7c5b38c3
drwxr-xr-x    3 root     root          4096 Mar 14 15:15 bed6b001d9612edee2974800e220a33337d8d696c9232115776d4514e64ef872
-rw-------    1 root     root         65536 Apr 12 01:21 metadata.db
/ #