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====

おすすめ

転載: blog.csdn.net/An1090239782/article/details/110927539
おすすめ