#はじめに
今回はVolumeのリソースを確認したいと思います。
Volumeには色々な種類がありますが、検証環境がPC1台ですので、できるものの動作を確認します。
#emptyDir
emptyDirはworkerノードの領域をコンテナからマウントして使用します。Podが削除されるとその領域は削除されます。
ユースケースとして、以下がマニュアルに記載されています。わかるようなわからないようなという感じですが。
- scratch space, such as for a disk-based merge sort
- checkpointing a long computation for recovery from crashes
- holding files that a content-manager Container fetches while a webserver Container serves the data
以下のマニフェストを作成しました。「mountPath」と「name」にマウントポイントと名前を指定します。
apiVersion: v1
kind: Pod
metadata:
name: test-emptydir
spec:
containers:
- image: nginx:latest
name: test-emptydir
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir: {}
このマニフェストをapplyします。
$ kubectl apply -f emptyDir.yaml
pod/test-emptydir created
$ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test-emptydir 1/1 Running 0 3m46s 192.168.79.101 k8s-worker01 <none> <none>
ログインして確認します。
$ kubectl exec -it test-emptydir /bin/bash
root@test-emptydir:/# df -k
Filesystem 1K-blocks Used Available Use% Mounted on
overlay 17811456 7913692 9897764 45% /
tmpfs 65536 0 65536 0% /dev
tmpfs 1457088 0 1457088 0% /sys/fs/cgroup
/dev/mapper/centos-root 17811456 7913692 9897764 45% /cache
shm 65536 0 65536 0% /dev/shm
tmpfs 1457088 12 1457076 1% /run/secrets/kubernetes.io/serviceaccount
tmpfs 1457088 0 1457088 0% /proc/acpi
tmpfs 1457088 0 1457088 0% /proc/scsi
tmpfs 1457088 0 1457088 0% /sys/firmware
root@test-emptydir:/# touch /cache/testfile
root@test-emptydir:/# ls /cache/testfile
/cache/testfile
/cacheに/dev/mapper/centos-rootがマウントされていますね。
ファイルも作成できます。
workerノードも確認してみます。
worker01にデプロイされていますので、worker01を確認します。
[k8s-worker01 ~]$ df -k
ファイルシス 1K-ブロック 使用 使用可 使用% マウント位置
devtmpfs 1445272 0 1445272 0% /dev
tmpfs 1457088 0 1457088 0% /dev/shm
tmpfs 1457088 9640 1447448 1% /run
tmpfs 1457088 0 1457088 0% /sys/fs/cgroup
/dev/mapper/centos-root 17811456 7913820 9897636 45% /
/dev/sda1 1038336 204504 833832 20% /boot
tmpfs 291420 0 291420 0% /run/user/1000
rootファイルシステムがそのままマウントされていますが、workerノードのrootファイルシステムは参照できないようです。
今度は1GBのファイルを作ってみます。
root@test-emptydir:/# dd if=/dev/zero of=/cache/tmpfile bs=1M count=1024
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 2.38459 s, 450 MB/s
root@test-emptydir:/# ls -l /cache/
total 1048576
-rw-r--r--. 1 root root 0 Apr 25 12:40 testfile
-rw-r--r--. 1 root root 1073741824 Apr 26 07:02 tmpfile
root@test-emptydir:/# df -k /cache/
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/mapper/centos-root 17811456 8963176 8848280 51% /cache
worker01の容量も確認します。
[k8s-worker01 ~]$ df -k /
ファイルシス 1K-ブロック 使用 使用可 使用% マウント位置
/dev/mapper/centos-root 17811456 8963280 8848176 51% /
同じ容量が消費されていることがわかりますね。
Podを削除すると、領域も開放されます。
$ kubectl delete -f emptyDir.yaml
pod "test-emptydir" deleted
[k8s-worker01 ~]$ df -k /
ファイルシス 1K-ブロック 使用 使用可 使用% マウント位置
/dev/mapper/centos-root 17811456 7914956 9896500 45% /
複数のPodで同じ領域をマウントすることになりますので、ファイルの共有ができるのかも?と思い確認してみます。
ReplicaSetを複数作って、同じworkerノードにデプロイされているPodで共有できるのかを確認します。
$ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test-emptydir-dep-75f6f5996-2dzzn 1/1 Running 0 56s 192.168.79.103 k8s-worker01 <none> <none>
test-emptydir-dep-75f6f5996-bxpkn 1/1 Running 0 56s 192.168.79.104 k8s-worker01 <none> <none>
test-emptydir-dep-75f6f5996-pgrlq 1/1 Running 0 56s 192.168.69.205 k8s-worker02 <none> <none>
test-emptydir-dep-75f6f5996-wwrp8 1/1 Running 0 56s 192.168.69.207 k8s-worker02 <none> <none>
1つのPodでファイルを作って、そのファイルが別のPodから参照できるのかを確認します。
$ kubectl exec -it test-emptydir-dep-75f6f5996-2dzzn touch /cache/testfile
$ kubectl exec -it test-emptydir-dep-75f6f5996-2dzzn ls /cache
testfile
$ kubectl exec -it test-emptydir-dep-75f6f5996-bxpkn ls /cache
同じworkerノードにデプロイされているPodでも参照はできませんでした。
同じ領域をマウントしていてもファイルの共有はできないようです。
#hostPath
hostPathはworkerノードのある領域をコンテナからマウントします。emptyDirとの違いは、workerノードの領域を参照できるかどうかです。
ユースケースとしては、以下があげられてます。
- running a Container that needs access to Docker internals; use a hostPath of /var/lib/docker
- running cAdvisor in a Container; use a hostPath of /sys
<* allowing a Pod to specify whether a given hostPath should exist prior to the Pod running, whether it should be created, and what it should exist as
以下のマニフェストを作成しました。
workerノードの「/sys」を「/test」でマウントします。
また、「type」は「Directory」を指定していますが、ほかにもいくつかあります。
apiVersion: v1
kind: Pod
metadata:
name: test-hostpath
spec:
containers:
- image: nginx:latest
name: test-hostpath
volumeMounts:
- mountPath: /test
name: test-volume
volumes:
- name: test-volume
hostPath:
path: /sys
type: Directory
このマニフェストをapplyします。
$ kubectl apply -f hostPath.yaml
pod/test-hostpath created
ログインして確認します。
$ kubectl exec -it test-hostpath /bin/bash
root@test-hostpath:/# ls -l /test/
total 0
drwxr-xr-x. 2 root root 0 Apr 26 08:27 block
drwxr-xr-x. 34 root root 0 Apr 26 08:27 bus
drwxr-xr-x. 52 root root 0 Apr 26 08:27 class
drwxr-xr-x. 4 root root 0 Apr 26 08:27 dev
drwxr-xr-x. 15 root root 0 Apr 26 08:27 devices
drwxr-xr-x. 6 root root 0 Apr 26 08:27 firmware
drwxr-xr-x. 7 root root 0 Apr 26 08:27 fs
drwxr-xr-x. 2 root root 0 Apr 26 08:27 hypervisor
drwxr-xr-x. 10 root root 0 Apr 26 08:27 kernel
drwxr-xr-x. 181 root root 0 Apr 26 08:27 module
drwxr-xr-x. 2 root root 0 Apr 26 08:27 power
workerノードの/sysも確認します。同じですね。
[k8s-worker01 ~]$ ls -l /sys/
合計 0
drwxr-xr-x. 2 root root 0 4月 26 15:42 block
drwxr-xr-x. 34 root root 0 4月 26 15:42 bus
drwxr-xr-x. 52 root root 0 4月 26 15:42 class
drwxr-xr-x. 4 root root 0 4月 26 15:42 dev
drwxr-xr-x. 15 root root 0 4月 26 15:42 devices
drwxr-xr-x. 6 root root 0 4月 26 15:42 firmware
drwxr-xr-x. 7 root root 0 4月 26 15:42 fs
drwxr-xr-x. 2 root root 0 4月 26 15:42 hypervisor
drwxr-xr-x. 10 root root 0 4月 26 15:42 kernel
drwxr-xr-x. 181 root root 0 4月 26 15:42 module
drwxr-xr-x. 2 root root 0 4月 26 15:43 power
コンテナから書き込みができるか確認してみます。
root@test-hostpath:/# touch /test/testfile
touch: cannot touch '/test/testfile': Permission denied
パーミッションがありませんね。
#downwardAPI
downwardAPIはPodなどの情報をファイルとしてコンテナ内の指定したディレクトリに配置します。
配置できる情報はこちらに記載されています。
以下のマニフェストでPod名、namespace、requestCPU数を配置してみます。
apiVersion: v1
kind: Pod
metadata:
name: test-downwardapi
spec:
containers:
- name: test-downwordapi
image: nginx:latest
volumeMounts:
- name: podinfo
mountPath: /etc/podinfo
volumes:
- name: podinfo
downwardAPI:
items:
- path: "podname"
fieldRef:
fieldPath: metadata.name
- path: "namespace"
fieldRef:
fieldPath: metadata.namespace
- path: "cpu_request"
resourceFieldRef:
containerName: test-downwordapi
resource: requests.cpu
$ kubectl apply -f downwardAPI.yaml
pod/test-downwardapi created
$ kubectl exec -it test-downwardapi ls /etc/podinfo
cpu_request namespace podname
$ kubectl exec -it test-downwardapi cat /etc/podinfo/cpu_request
0
$ kubectl exec -it test-downwardapi cat /etc/podinfo/namespace
default
$ kubectl exec -it test-downwardapi cat /etc/podinfo/podname
test-downwardapi
それぞれの値がファイルとして配置され、その中に記載されていることがわかります。
#projected
projectedは以下の4つのボリュームリソースを同じディレクトリにマウントするリソースです。
- secret
- downwardAPI
- configMap
- serviceAccountToken
以下のマニフェストをapplyして確認します。
SecretとConfigMapは以前作成したものを流用します。
apiVersion: v1
kind: Pod
metadata:
name: test-projected
spec:
containers:
- name: container-test
image: nginx:latest
volumeMounts:
- name: all-in-one
mountPath: "/projected-volume"
readOnly: true
volumes:
- name: all-in-one
projected:
sources:
- secret:
name: sample-auth
items:
- key: username
path: secret/data
- configMap:
name: sample-configmap2
items:
- key: maxmemory
path: configmap/data
- downwardAPI:
items:
- path: "podname"
fieldRef:
fieldPath: metadata.name
$ kubectl apply -f projected.yaml
pod/test-projected created
$ kubectl exec -it test-projected /bin/bash
root@test-projected:/# cd /projected-volume/
root@test-projected:/projected-volume# ls
configmap podname secret
root@test-projected:/projected-volume# cat configmap/data
2mb
root@test-projected:/projected-volume# cat podname
test-projected
root@test-projected:/projected-volume# cat secret/data
user01
3つの値が同じマウントポイントにマウントされていることがわかりますね。
#まとめ
今回はVolumeリソースの動作を確認しました。
Volumeはworkerノードのファイルシステムやあらかじめ作成したリソース(ConfigMapなど)をコンテナ上で利用可能とするものです。Volumeというと、私は物理的な領域やディスクを連想しますが、Kubernetesではファイルシステムから上の論理的な領域に近いイメージですね。
言葉から受ける印象から先入観を持たないようにしないといけないです。