KubernetesK8Sストレージボリュームの詳細な説明
元のアドレス:
KubernetesK8Sのストレージボリュームの詳細な説明
ボリュームの概要
コンテナ内のファイルは一時的にディスクに保存され、これらの一時ファイルもコンテナが閉じられると削除されます。これにより、コンテナで実行されている特別なアプリケーションでいくつかの問題が発生します。
まず、コンテナーがクラッシュすると、kubeletはコンテナーを再起動し、コンテナー内のファイルは失われます。これは、コンテナーがクリーンな状態で再構築されるためです。
次に、ポッド内で複数のコンテナーを同時に実行する場合、これらのコンテナー間でファイルを共有する必要があることがよくあります。
Kubernetesは、Volumeオブジェクトを抽象化して、これら2つの問題を解決します。
Kubernetesボリュームボリュームには明確なライフサイクルがあります-それをラップするポッドと同じです。したがって、ボリュームの有効期間はポッドで実行されているどのコンテナーよりも長く、コンテナーを再起動してもデータは保持されます。もちろん、ポッドが存在しなくなると、ボリュームは存在しなくなります。さらに重要なことに、Kubernetesは多くの種類のボリュームボリュームをサポートでき、ポッドは同時に任意の数のボリュームボリュームを使用することもできます。
ボリュームを使用する場合、Podステートメントはボリュームのタイプ(.spec.volumesフィールド)とボリュームがマウントされる場所(.spec.containers.volumeMountsフィールド)を提供する必要があります。
ボリュームタイプ
Kubernetesは次のタイプのボリュームをサポートしています。
awsElasticBlockStore
azureDisk
azureFile
cephfs
cinder
configMap
csi
downwardAPI
emptyDir
fc (fibre channel)
flexVolume
flocker
gcePersistentDisk
gitRepo (deprecated)
glusterfs
hostPath
iscsi
local
nfs
persistentVolumeClaim
projected
portworxVolume
quobyte
rbd
scaleIO
secret
storageos
vsphereVolume
ここでは、Secret、ConfigMap、emptyDir、hostPathなどの一般的に使用されるストレージのみを紹介します。
emptyDirボリューム
ポッドがノードに割り当てられると、最初にemptyDirボリュームが作成され、ポッドがそのノードで実行されている限り、ボリュームは常に存在します。その名前が示すように、ボリュームは最初は空です。
emptyDirボリュームをマウントするポッド内の各コンテナーのパスは同じでも異なっていても、これらのコンテナーはすべて、emptyDirボリューム内の同じファイルを読み書きできます。
ポッドに複数のコンテナがある場合、コンテナの1つを再起動しても、emptyDirボリュームのデータには影響しません。ポッドが何らかの理由で削除されると、emptyDirボリュームのデータも完全に削除されます。
注:コンテナーのクラッシュによってポッドがノードから削除されることはないため、コンテナーがクラッシュしても、emptyDirボリュームのデータは安全です。
emptyDirのいくつかの使用法:
- ディスクベースのマージソートなどのキャッシュスペース
- 時間のかかるコンピューティングタスクのチェックポイントを提供して、タスクがクラッシュ前の状態から実行を簡単に再開できるようにします
- Webサーバーコンテナがデータを提供する場合、コンテンツマネージャコンテナによって取得されたファイルを保存します
emptyDirの例
yamlファイル
[root@k8s-master emptydir]# pwd
/root/k8s_practice/emptydir
[root@k8s-master emptydir]# cat pod_emptydir.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-emptydir
namespace: default
spec:
containers:
- name: myapp-pod
image: registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1
imagePullPolicy: IfNotPresent
volumeMounts:
- mountPath: /cache
name: cache-volume
- name: busybox-pod
image: registry.cn-beijing.aliyuncs.com/google_registry/busybox:1.24
imagePullPolicy: IfNotPresent
command: ["/bin/sh", "-c", "sleep 3600"]
volumeMounts:
- mountPath: /test/cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir: {
}
ポッドを起動してステータスを確認します
[root@k8s-master emptydir]# kubectl apply -f pod_emptydir.yaml
pod/pod-emptydir created
[root@k8s-master emptydir]#
[root@k8s-master emptydir]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-emptydir 2/2 Running 0 10s 10.244.2.166 k8s-node02 <none> <none>
[root@k8s-master emptydir]#
[root@k8s-master emptydir]# kubectl describe pod pod-emptydir
Name: pod-emptydir
Namespace: default
Priority: 0
Node: k8s-node02/172.16.1.112
Start Time: Fri, 12 Jun 2020 22:49:11 +0800
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{
"apiVersion":"v1","kind":"Pod","metadata":{
"annotations":{
},"name":"pod-emptydir","namespace":"default"},"spec":{
"containers":[{
"image":"...
Status: Running
IP: 10.244.2.166
IPs:
IP: 10.244.2.166
Containers:
myapp-pod:
Container ID: docker://d45663776b40a24e7cfc3cf46cb08cf3ed6b98b023a5d2cb5f42bee2234c7338
Image: registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1
Image ID: docker-pullable://10.0.0.110:5000/k8s-secret/myapp@sha256:9eeca44ba2d410e54fccc54cbe9c021802aa8b9836a0bcf3d3229354e4c8870e
Port: <none>
Host Port: <none>
State: Running
Started: Fri, 12 Jun 2020 22:49:12 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/cache from cache-volume (rw) ##### 挂载信息
/var/run/secrets/kubernetes.io/serviceaccount from default-token-v48g4 (ro)
busybox-pod:
Container ID: docker://c2917ba30c3322fb0caead5d97476b341e691f9fb1990091264364b8cd340512
Image: registry.cn-beijing.aliyuncs.com/google_registry/busybox:1.24
Image ID: docker-pullable://registry.cn-beijing.aliyuncs.com/ducafe/busybox@sha256:f73ae051fae52945d92ee20d62c315306c593c59a429ccbbdcba4a488ee12269
Port: <none>
Host Port: <none>
Command:
/bin/sh
-c
sleep 3600
State: Running
Started: Fri, 12 Jun 2020 22:49:12 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/test/cache from cache-volume (rw) ##### 挂载信息
/var/run/secrets/kubernetes.io/serviceaccount from default-token-v48g4 (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
cache-volume:
Type: EmptyDir (a temporary directory that shares a pod's lifetime)
Medium:
SizeLimit: <unset>
default-token-v48g4:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-v48g4
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 3s default-scheduler Successfully assigned default/pod-emptydir to k8s-node02
Normal Pulled 2s kubelet, k8s-node02 Container image "registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1" already present on machine
Normal Created 2s kubelet, k8s-node02 Created container myapp-pod
Normal Started 2s kubelet, k8s-node02 Started container myapp-pod
Normal Pulled 2s kubelet, k8s-node02 Container image "registry.cn-beijing.aliyuncs.com/google_registry/busybox:1.24" already present on machine
Normal Created 2s kubelet, k8s-node02 Created container busybox-pod
Normal Started 2s kubelet, k8s-node02 Started container busybox-pod
emptyDir検証
ポッド内のmyapp-podコンテナで操作する
[root@k8s-master emptydir]# kubectl exec -it pod-emptydir -c myapp-pod -- sh
/ # cd /cache
/cache #
/cache # pwd
/cache
/cache #
/cache # date >> data.info
/cache # ls -l
total 4
-rw-r--r-- 1 root root 29 Jun 12 14:53 data.info
/cache # cat data.info
Fri Jun 12 14:53:27 UTC 2020
ポッド内のbusybox-podコンテナで操作します
[root@k8s-master emptydir]# kubectl exec -it pod-emptydir -c busybox-pod -- sh
/ # cd /test/cache
/test/cache # ls -l
total 4
-rw-r--r-- 1 root root 29 Jun 12 14:53 data.info
/test/cache # cat data.info
Fri Jun 12 14:53:27 UTC 2020
/test/cache #
/test/cache # echo "===" >> data.info
/test/cache # date >> data.info
/test/cache # cat data.info
Fri Jun 12 14:53:27 UTC 2020
===
Fri Jun 12 14:56:05 UTC 2020
上記から、ポッド内の複数のコンテナが同じemptyDirボリュームを共有できることがわかります。
hostPath卷
hostPathボリュームは、ホストノードノードのファイルシステム上のファイルまたはディレクトリをポッドにマウントできます。これはほとんどのポッドでは必要ありませんが、一部のアプリケーションには強力なエスケープハッチを提供します。
hostPathのいくつかの使用法は次のとおりです。
- Dockerエンジンの内部メカニズムにアクセスする必要があるコンテナーを実行します。hostPathを使用して/ var / lib / dockerパスをマウントしてください。
- コンテナでcAdvisorを実行する場合は、hostPathを使用して/ sysをマウントします。
- ポッドを実行する前に特定のhostPathが存在するかどうか、作成するかどうか、およびどのように存在するかをポッドが指定できるようにします。
サポートタイプ
必要なパス属性に加えて、ユーザーはオプションでhostPathボリュームのタイプを指定できます。サポートされている型の値は次のとおりです:
値 | 動作 |
---|---|
下位互換性のために空の文字列(デフォルト)が使用されます。これは、hostPathボリュームをマウントする前にチェックが実行されないことを意味します。 | |
DirectoryOrCreate | 指定されたパスが存在しない場合は、必要に応じて空のディレクトリが作成され、権限は0755に設定され、グループと所有権はKubeletと同じになります。 |
ディレクトリ | 指定されたパスが存在する必要があります |
FileOrCreate | 指定されたパスのファイルが存在しない場合は、必要に応じて空のファイルが作成され、アクセス許可は0644に設定され、Kubeletと同じグループと所有権があります[前提条件:ファイルが配置されているディレクトリが存在する必要があります。ディレクトリが存在しない場合、ファイルを作成できません] |
ファイル | 指定されたパス上のファイルが存在する必要があります |
ソケット | 指定されたパスに存在する必要があるUNIXソケット |
CharDevice | 指定されたパスに存在する必要があるキャラクターデバイス |
BlockDevice | 指定されたパスに存在する必要があるブロックデバイス |
予防
このタイプのボリュームを使用するときは、次の理由で注意してください。
- 同じ構成の複数のポッド(たとえば、podTemplateから作成されたもの)は、ノード上のファイルが異なるため、ノードごとに異なる動作をします。
- Kubernetesが計画どおりにリソース対応のスケジューリングを追加すると、このタイプのスケジューリングメカニズムはhostPathボリュームによって使用されるリソースを考慮することができなくなります。
- ベースホスト上に作成されたファイルまたはディレクトリは、rootユーザーのみが書き込むことができます。特権コンテナーでrootとしてプロセスを実行するか、コンテナーがhostPathボリュームに書き込めるようにホストのファイル権限を変更する必要があります。
hostPathの例
yamlファイル
[root@k8s-master hostpath]# pwd
/root/k8s_practice/hostpath
[root@k8s-master hostpath]# cat pod_hostpath.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-hostpath
namespace: default
spec:
containers:
- name: myapp-pod
image: registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1
imagePullPolicy: IfNotPresent
volumeMounts:
- name: hostpath-dir-volume
mountPath: /test-k8s/hostpath-dir
- name: hostpath-file-volume
mountPath: /test/hostpath-file/test.conf
volumes:
- name: hostpath-dir-volume
hostPath:
# 宿主机目录
path: /k8s/hostpath-dir
# hostPath 卷指定 type,如果目录不存在则创建(可创建多层目录)
type: DirectoryOrCreate
- name: hostpath-file-volume
hostPath:
path: /k8s2/hostpath-file/test.conf
# 如果文件不存在则创建。 前提:文件所在目录必须存在 目录不存在则不能创建文件
type: FileOrCreate
ポッドを起動してステータスを確認します
[root@k8s-master hostpath]# kubectl apply -f pod_hostpath.yaml
pod/pod-hostpath created
[root@k8s-master hostpath]#
[root@k8s-master hostpath]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-hostpath 1/1 Running 0 17s 10.244.4.133 k8s-node01 <none> <none>
[root@k8s-master hostpath]#
[root@k8s-master hostpath]# kubectl describe pod pod-hostpath
Name: pod-hostpath
Namespace: default
Priority: 0
Node: k8s-node01/172.16.1.111
Start Time: Sat, 13 Jun 2020 16:12:15 +0800
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{
"apiVersion":"v1","kind":"Pod","metadata":{
"annotations":{
},"name":"pod-hostpath","namespace":"default"},"spec":{
"containers":[{
"image":"...
Status: Running
IP: 10.244.4.133
IPs:
IP: 10.244.4.133
Containers:
myapp-pod:
Container ID: docker://8cc87217fb483288067fb6d227c46aa890d02f75cae85c6d110646839435ab96
Image: registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1
Image ID: docker-pullable://registry.cn-beijing.aliyuncs.com/google_registry/myapp@sha256:9eeca44ba2d410e54fccc54cbe9c021802aa8b9836a0bcf3d3229354e4c8870e
Port: <none>
Host Port: <none>
State: Running
Started: Sat, 13 Jun 2020 16:12:17 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/test-k8s/hostpath-dir from hostpath-dir-volume (rw)
/test/hostpath-file/test.conf from hostpath-file-volume (rw)
/var/run/secrets/kubernetes.io/serviceaccount from default-token-v48g4 (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
hostpath-dir-volume:
Type: HostPath (bare host directory volume)
Path: /k8s/hostpath-dir
HostPathType: DirectoryOrCreate
hostpath-file-volume:
Type: HostPath (bare host directory volume)
Path: /k8s2/hostpath-file/test.conf
HostPathType: FileOrCreate
default-token-v48g4:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-v48g4
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled <unknown> default-scheduler Successfully assigned default/pod-hostpath to k8s-node01
Normal Pulled 12m kubelet, k8s-node01 Container image "registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1" already present on machine
Normal Created 12m kubelet, k8s-node01 Created container myapp-pod
Normal Started 12m kubelet, k8s-node01 Started container myapp-pod
hostPath検証
ホスト操作
ポッドによると、k8s-node01ノードのホストで操作します[ポッドがノードに割り当てられているため]
# 对挂载的目录操作
[root@k8s-node01 hostpath-dir]# pwd
/k8s/hostpath-dir
[root@k8s-node01 hostpath-dir]# echo "dir" >> info
[root@k8s-node01 hostpath-dir]# date >> info
[root@k8s-node01 hostpath-dir]# cat info
dir
Sat Jun 13 16:22:37 CST 2020
# 对挂载的文件操作
[root@k8s-node01 hostpath-file]# pwd
/k8s2/hostpath-file
[root@k8s-node01 hostpath-file]# echo "file" >> test.conf
[root@k8s-node01 hostpath-file]# date >> test.conf
[root@k8s-node01 hostpath-file]#
[root@k8s-node01 hostpath-file]# cat test.conf
file
Sat Jun 13 16:23:05 CST 2020
ポッドコンテナで操作する
# 进入pod 中的指定容器【如果只有一个容器,那么可以不指定容器】
[root@k8s-master hostpath]# kubectl exec -it pod-hostpath -c myapp-pod -- /bin/sh
##### 对挂载的目录操作
/ # cd /test-k8s/hostpath-dir
/test-k8s/hostpath-dir # ls -l
total 4
-rw-r--r-- 1 root root 33 Jun 13 08:22 info
/test-k8s/hostpath-dir # cat info
dir
Sat Jun 13 16:22:37 CST 2020
/test-k8s/hostpath-dir #
/test-k8s/hostpath-dir # date >> info
/test-k8s/hostpath-dir # cat info
dir
Sat Jun 13 16:22:37 CST 2020
Sat Jun 13 08:26:10 UTC 2020
##### 对挂载的文件操作
# cd /test/hostpath-file/
/test/hostpath-file # cat test.conf
file
Sat Jun 13 16:23:05 CST 2020
/test/hostpath-file # echo "file====" >> test.conf
/test/hostpath-file # cat test.conf
file
Sat Jun 13 16:23:05 CST 2020
file====