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

Docker Desktop for Windows + WSL2でKubernetesのVolumesの1つ、hostPathを使う方法を調査した。
# 動作環境
- Windows11 Pro 22631.3447
- WSL2
- Docker Desktop 4.29.0
    - Settings→General→Use the WSL 2 based engine をチェックしていること

# ホストのディレクトリを使用する
以下のようにhostPathを指定する。

```yml: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 Desktop for Windows + WSL2のバックエンドであるdocker-desktop Distroのディレクトリをマウントする。

```yml: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/version-pack-data/community/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
```
エクスプローラからも確認可能
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132879/0e61e1f7-eeea-f65b-7f71-2214c07222bc.png)

上記pathで重要なのは/var/lib/の部分でそれ以降は任意だ。
バージョン2.2.0.5の頃は/mnt/host/wsl/docker-desktop-data/dataに作成されていた。
他にも以下の指定が可能

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

上記の２つ目はdocker volume createでvolumeが作成されるディレクトリなので、docker volume createで作成したvolumeをPodにマウントすることができる。

逆に以下はマウントしてデータを書き込んだとしてもdocker for Windowsを再起動するとデータが消えてしまう。

| path|マウントされるdocker-desktop Distroのパス|
|:-----------------|:------------------|
| /home |/mnt/host/wsl/docker-desktop-data/version-pack-data/community/mount-services-cache/entries/services.raw/｛ハッシュ値｝.mnt/containers/services/01-docker/rootfs/home|

# マウントした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/version-pack-data/community/mydata
My-PC:/tmp/docker-desktop-root/mnt/host/c/Users/docker# ls -l /mnt/host/wsl/docker-desktop-data/version-pack-data/community
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を設定する
```yaml: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の場合　※2021年時点
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
/ #
```