Pod 内のコンテナから、ボリュームをマウントするには次の4つの方法がある。
- hostPath で、Pod が作成されたノード上の特定のパスをボリュームとする。
- emptyDir で、Pod が作成されたノード上に、Pod と同じ寿命の空のボリュームをつくる。
- クラウドプロバイダ(AWS, Azure, GCE 等)が提供する作成済みのストレージをボリュームとする。
- PersistentVolume, PersistentVolumeClaim, StorageClass を使った永続ボリュームを利用する。
https://kubernetes.io/ja/docs/concepts/storage/volumes/
最初の2つがローカルなボリュームであり、マニフェストファイル kuard-pod-vol.yml
でこれらを試してみる。
Mac OS X の Docker for Mac 上のローカルな Kubernetes クラスタで試してみる。そのために
$ kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
* docker-desktop docker-desktop docker-desktop
gke_todo-kube-343008_us-central1-c_todo-cluster gke_todo-kube-343008_us-central1-c_todo-cluster gke_todo-kube-343008_us-central1-c_todo-cluster
で、カレントコンテキストが docker-desktop になっていることを確実にしておく。
Pod をデプロイ
$ kubectl apply -f kuard-pod-vol.yml
pod/kuard created
次に、 https://gist.github.com/fortune/0b17295b84923fbd074aaa7bf744e99e のとおりにローカルな K8S クラスタのノードになっている Linux VM に入る。
$ docker run -it --rm --privileged --pid=host justincormack/nsenter1
/ #
Pod のマニフェストファイルでは指定できないが、コンテナのイメージ作成の Dockerfile で Volume 命令を使っていれば、そのコンテナはボリュームにマウントされる。ここでは、redis コンテナがそうだ。
Linux VM ノード内で、redis コンテナがマウントしたボリュームを見てみる。
/ # cd /var/lib/docker/volumes/
/var/lib/docker/volumes # ls
backingFsBlockDev metadata.db
c5988c5677c5496125c78c3e1d9f9bdce3f858ce91fa217cdc126a1c8a946cfc
/var/lib/docker/volumes # cd c5988c5677c5496125c78c3e1d9f9bdce3f858ce91fa217cdc126a1c8a946cfc/
/var/lib/docker/volumes/c5988c5677c5496125c78c3e1d9f9bdce3f858ce91fa217cdc126a1c8a946cfc # ls
_data
/var/lib/docker/volumes/c5988c5677c5496125c78c3e1d9f9bdce3f858ce91fa217cdc126a1c8a946cfc # cd _data
/var/lib/docker/volumes/c5988c5677c5496125c78c3e1d9f9bdce3f858ce91fa217cdc126a1c8a946cfc/_data #
/var/lib/docker/volumes/c5988c5677c5496125c78c3e1d9f9bdce3f858ce91fa217cdc126a1c8a946cfc/_data # ls
/var/lib/docker/volumes/c5988c5677c5496125c78c3e1d9f9bdce3f858ce91fa217cdc126a1c8a946cfc/_data #
Pod 内の redis コンテナにはいってみる。
$ kubectl exec -it kuard -c redis -- /bin/bash
root@kuard:/data# pwd
/data
root@kuard:/data#
root@kuard:/data#
root@kuard:/data# ls
root@kuard:/data# echo hello >hello.txt
再び、Linux VM ノードの方を見てみると、redis コンテナが作成したファイルが見える。
/var/lib/docker/volumes/c5988c5677c5496125c78c3e1d9f9bdce3f858ce91fa217cdc126a1c8a946cfc/_data # cat hello.txt
hello
このボリュームは、redis コンテナ単位で作成されているので、redis コンテナが再作成されたりすると、新しいコンテナでは使用されず、別のボリュームが作成されてしまう。
次に、Pod マニフェストの volumes 定義で作成した kuard-data
ボリュームを確認する。これは、hostPath.path により、ノードの特定のパスにマウントさせる
ボリュームだ。
Pod 内の kuard コンテナに入る。
$ kubectl exec -it kuard -c kuard -- /bin/sh
~ $ cd /data
/data $ ls
/data $
test-client コンテナに入る。
$ kubectl exec -it kuard -c test-client -- /bin/bash
root@kuard:/# cd /workspace/
root@kuard:/workspace# ls
root@kuard:/workspace#
root@kuard:/workspace# echo fortunefield >fortunefield.txt
root@kuard:/workspace#
再び、kuard コンテナの方を見ると
/data $ ls
fortunefield.txt
/data $ cat fortunefield.txt
fortunefield
/data $
になり、たしかに共通のボリュームをマウントしている。
Linux VM ノードに戻って、上で作成した fortunefield.txt を探す。
/ #
/ # find . -name fortunefield.txt
./var/lib/mount-docker-cache/entries/services.tar/7faf803132f55a3e5671b59b7fc3133d2117557fd2e00ddc8a39b88801921917/containers/services/docker/rootfs/home/fortunefield.txt
./var/lib/mount-docker-cache/entries/services.tar/7faf803132f55a3e5671b59b7fc3133d2117557fd2e00ddc8a39b88801921917/containers/services/docker/tmp/upper/home/fortunefield.txt
./var/lib/mount-docker-cache/entries/docker.tar/da2df7ce7c953bc090d2abf0e887f581c5efea69356aa7ec1134b48ea5f3835a/containers/services/docker/rootfs/home/fortunefield.txt
./var/lib/mount-docker-cache/entries/docker.tar/da2df7ce7c953bc090d2abf0e887f581c5efea69356aa7ec1134b48ea5f3835a/containers/services/docker/tmp/upper/home/fortunefield.txt
./containers/services/docker/rootfs/home/fortunefield.txt
./containers/services/docker/tmp/upper/home/fortunefield.txt
/ #
/ # cd containers/services/docker/rootfs/home
/containers/services/docker/rootfs/home # ls
fortunefield.txt
/containers/services/docker/rootfs/home # cat fortunefield.txt
fortunefield
/containers/services/docker/rootfs/home #
ノードの /home をボリュームとして指定していたが、直接ノードの /home がボリュームになるのではないようだ。これは、K8S クラスタによって異なるのかもしれない。
kuard-empty
ボリュームを確認する。これは、emptyDir で作成した空のボリュームだ。
kuard コンテナで見ると
~ $ cd /empty-data/
/empty-data $ ls
/empty-data $
/empty-data $ echo tomita >tomita.txt
/empty-data $ ls
tomita.txt
test-client コンテナで見ると
root@kuard:/workspace# cd /empty-workspace/
root@kuard:/empty-workspace# ls
tomita.txt
root@kuard:/empty-workspace# cat tomita.txt
tomita
root@kuard:/empty-workspace#
たしかに共通にマウントできてる。
ここで Pod を再作成してみる。
$ kubectl delete -f kuard-pod-vol.yml
pod "kuard" deleted
$ kubectl apply -f kuard-pod-vol.yml
pod/kuard created
その後で、再度、kuard コンテナの中に入って確認する。
$ kubectl exec -it kuard -c kuard -- /bin/sh
~ $ ls /data/
fortunefield.txt
~ $
~ $
~ $ ls /empty-data/
~ $
hotPath.path で作成した方のボリュームの内容は残っているが、emptyDir で作成したボリュームの中身は消えていることがわかる。emptyDir は Pod 内のコンテナ間の通信に使うのに向いている。
あらかじめ、GKE 上にクラスタを作成してある。それを対象にするように kubectl のコンテキストを設定して、Pod をデプロイする。
$ kubectl config use-context gke_todo-kube-343008_us-central1-c_todo-cluster
Switched to context "gke_todo-kube-343008_us-central1-c_todo-cluster".
$
$ kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
docker-desktop docker-desktop docker-desktop
* gke_todo-kube-343008_us-central1-c_todo-cluster gke_todo-kube-343008_us-central1-c_todo-cluster gke_todo-kube-343008_us-central1-c_todo-cluster
$ kubectl apply -f kuard-pod-vol.yml
pod/kuard created
$ kubectl get pod kuard
NAME READY STATUS RESTARTS AGE
kuard 3/3 Running 0 54s
kuard Pod 内の kuard コンテナに入ってみると
$ kubectl exec -it kuard -c kuard -- /bin/sh
~ $
~ $
~ $ ls
bin dev etc kuard media proc run srv tmp var
data empty-data home lib mnt root sbin sys usr
~ $ ls /data
chronos containerd kubernetes
~ $
~ $
~ $ ls /empty-data/
~ $
test-client コンテナに入ってみると
$ kubectl exec -it kuard -c test-client -- /bin/bash
root@kuard:/#
root@kuard:/#
root@kuard:/# ls -l /workspace/
total 12
drwxr-xr-x 2 1000 1000 4096 Feb 18 03:56 chronos
drwxr-xr-x 2 root root 4096 Mar 3 09:19 containerd
drwxr-xr-x 11 root root 4096 Mar 3 09:19 kubernetes
root@kuard:/#
root@kuard:/#
root@kuard:/# ls /empty-workspace/
root@kuard:/#
kuard
ボリュームはノードの /home にマウントしていた。上でわかるように、GKE のクラスタ上で、この kuard Pod が作成されたノードの /home には、
drwxr-xr-x 2 1000 1000 4096 Feb 18 03:56 chronos
drwxr-xr-x 2 root root 4096 Mar 3 09:19 containerd
drwxr-xr-x 11 root root 4096 Mar 3 09:19 kubernetes
があることがわかる。