Kubernetes：Kubernetes Volume、PVC、PV

この記事では、Kubernetesボリュームの適用シナリオと制限、KubernetesにおけるPVCとPVの処理手順の概要について説明します。

著者：アリババのシニアR&Dエンジニア、黄柯（Zhitian）氏

#1) Volumeの紹介
###Pod Volume
Pod Volumeは以下のシナリオで使用されます。

- シナリオ1）Pod内のコンテナがクラッシュし、kubeletによって再起動されたときに、コンテナが生成した重要なデータが失われないようにする。
- シナリオ2）Pod内の複数のコンテナ間でのデータ共有を確保する。
では、一般的なPod Volumesの種類を見てみましょう。

**1) ローカルストレージ:** emptydir/hostpath を含む場合があります。
**2) ネットワークストレージ:** in-tree モードと out-of-tree モードで実装されます。in-treeモードでは、実装コードは[Kubernetes](https://www.alibabacloud.com/product/kubernetes?spm=a2c65.11461447.0.0.169a218a4q9PLz)のコードリポジトリに格納されます。Kubernetesがサポートするストレージの種類が増えるにつれ、このモードではKubernetesのメンテナンスや開発が困難になります。アウトオブツリーモードでは、異なるストレージデバイスのドライバは、抽象的なAPIを使用してKubernetesコードリポジトリから削除されます。そのため、ネットワークストレージのプラグインを実装する際には、アウトオブツリーモードを推奨しています。

次に、以下のボリュームの概念を理解することが重要です。

**1) Projected Volumes**：secret/configmap などの一部の構成は、ボリュームを介してコンテナにマウントされ、コンテナ内のプログラムが POSIX（Portable Operating System Interface）を介して構成にアクセスするようになっています。
**2) Persistent Volumes (PVs) and Persistent Volume Claims (PVCs)**：本稿では、これらのボリュームに焦点を当て、以下のセクションで説明します。

###PVs

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/45cad5fe-db31-b039-91d5-12144b1c95ed.png)

Pod Volumeが利用可能な場合、PVを導入する必要性を理解することが重要です。Podで宣言されたボリュームのライフサイクルは、Podのライフサイクルと同じです。一般的なシナリオは以下のとおりです。

- シナリオ1：イメージのアップグレード中にDeploymentで管理されているPodが削除され、再作成された場合、新しいPodは古いPodのデータを再利用する必要があります。
- シナリオ2：ホストが応答しなくなったとき、Podをホストから移行する必要があります。StatefulSetで管理されているPodには、Podボリュームでは実現できないボリュームベースの移行のセマンティクスが実装されています。
- シナリオ3：Pod間のデータ共有を宣言する必要があります。Pod Volumeは、Pod内の複数のコンテナ間でデータを共有するために使用されます。しかし、Pod Volumeは、複数のPod間のデータ共有には使用できません。
- シナリオ4：スナップショットの追加やリサイズ機能など、ボリュームの機能を拡張する必要があります。

前述のシナリオでは、再利用や共有のセマンティクスをPod Volumeで正確に表現することは難しく、また機能を拡張することも困難です。そこで、ストレージとコンピューティングを分離し、ストレージリソースとコンピューティングリソースを異なるコンポーネントで管理し、Podのライフサイクルとボリュームのライフサイクルを切り離すPVをKubernetesに導入しました。これにより、Podが削除されても、そのPVは存在し、新しいPodで再利用されるようになりました。

###PVCデザイン

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/7de22c9c-f5a4-3cf8-aef7-95cb37b366c3.png)


PVを使うということは、実はPVCを使っているということです。では、PVが利用できるのに、なぜPVCを設計する必要があるのでしょうか。PVCは、Kubernetesユーザーのストレージ利用を簡素化し、ユーザーのストレージ要件を実装の詳細から切り離すために設計されています。通常、ストレージを使用する際には、必要なストレージサイズとアクセスモードを宣言するだけで良いです。

アクセスモードとは、使用するストレージが複数のノード（Podではない）で共有されるのか、1つのノード（Podではない）で排他的にアクセスされるのか、また、使用するストレージが読み取り専用のアクセスのみをサポートするのか、読み取りと書き込みが可能なのかを示します。これが唯一の懸念点です。

PVCとPVは、要件と実装の詳細を切り離します。PVCを使ってストレージの要件を宣言します。PVはクラスタ管理者とストレージ関連のチームが統一的に管理することで、ストレージの使用を簡素化します。PVとPVCの設計は、オブジェクト指向のAPIと実装の関係に似ており、関数を使用する場合は、実装の詳細を知る必要はなく、単にAPIに注目するだけで良いです。

次のセクションでは、PVがどのように生成されるかを扱います。

###Static Volume Provisioning


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/ba8b5557-9098-fd1e-f3c3-e4c65076bca1.png)


このモードでは、クラスター管理者が、クラスターのユーザーがどのようにストレージを使用するかを計画します。一部のPVは事前に作成されます。ユーザーがPVCを提出した後、KubernetesのコンポーネントがPVCとPVの結合を支援する。ユーザーがPodを通じてストレージを使用する必要があるとき、ユーザーはPVCに基づいて対応するPVを見つけ、それらを使用することができます。

ボリューム静的プロビジョニングの欠点は何でしょうか？クラスタ管理者は、PVを事前に作成する必要があります。しかし、ユーザーの実際の要求を予測することは困難です。例えば、ユーザが20GBのPVを必要としているにもかかわらず、クラスタ管理者が80GBや100GBのPVを事前に作成した場合、これらのボリュームはリソースの無駄遣いとなり、ユーザの実際の要求を満たすことができません。

###ボリューム動的プロビジョニング

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/1dc0a2e1-c000-c3c5-7bd5-179ec047f94b.png)


このモードでは、クラスタ管理者はPVを事前に作成しません。代わりに、クラスタ管理者は、ブロックストレージやNASなど、特定のタイプのストレージデバイスに必要なパラメータを含むテンプレートファイルを作成します。これらのパラメータは、ストレージの実装に関連していますが、ユーザーには何の関係もありません。ユーザーが必要なのは、PVCを提出し、PVCに使用するストレージテンプレート（StorageClass）を指定することだけです。

Kubernetesクラスタ内の制御コンポーネントは、PVCとStorageClassの動的な情報に従って、ユーザーが必要とするストレージデバイス（PV）を生成します。PVCとPVがバインドされた後、PodはPVを使用することができます。制御コンポーネントは、ストレージに必要なストレージテンプレート（StorageClass）を生成し、ユーザーの要求に基づいてPVを動的に作成することで、オンデマンドな割り当てを実現します。これにより、ユーザの利用難易度を上げることなく、クラスタ管理者のO&M作業を軽減することができます。

#2）使用例
Pod Volume、PV、PVC、StorageClassの利用方法について説明します。

###Pod Volumesの使い方

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/ffb0b454-f93a-bcab-d0b6-beb8dad2d176.png)


前述の図の左に示すように、PodのYAMLファイルの「volume」フィールドにボリューム名とタイプを宣言します。1つのボリュームはemptyDirタイプで、もう1つはhostPathタイプです。これらはどちらもローカルボリュームです。ボリュームは、「volumeMounts」フィールドに基づいてコンテナ内で使用されます。「volumeMounts」で指定された「name」は、使用するボリュームの名前を示し、「mountPath」は、コンテナ内のマウントディレクトリを示します。

「subPath」フィールドもあります。

どちらのコンテナも、cache-volumeという同じボリュームを使用し、複数のコンテナが同じボリュームを共有する場合は、「subPath」を使用してデータを分離します。これにより、ボリューム内に2つのサブディレクトリが作成されます。コンテナ1からキャッシュに書き込まれたデータは、実際にはcache1サブディレクトリに書き込まれ、コンテナ2から書き込まれたデータは、実際にはcache2サブディレクトリに書き込まれます。

「readOnly」フィールドは、マウントポイントへのデータ書き込みを無効にします。

では、emptyDirとhostPathの違いは何でしょうか。 emptyDirは、Podの作成時に作成される一時的なディレクトリです。Podが削除されると、ディレクトリもそのデータもすべて削除されます。 hostPathは、ホスト上のディレクトリです。Podが削除されても、ディレクトリとそのデータは存在します。

###Static PVの使い方

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/821d331f-13ad-5ea3-36a2-f33dd5a92389.png)


静的PVは、管理者が作成します。この記事では、NAS（Network Attached Storage）を例に挙げます。Alibaba CloudのNASコンソールでNASを作成し、PVオブジェクトにNASの情報を追加します。PVオブジェクトが事前に作成されたら、PVCを使用してストレージ要件を宣言し、Podを作成します。Podを作成するには、上述のフィールドに基づいてコンテナのマウントポイントにストレージをマウントします。

YAMLファイルを書き込むために、クラスター管理者はクラウドストレージベンダー側でPVを作成し、PVオブジェクトに関連情報を追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/933e8335-f8e1-c778-4581-cd9e45ea2dec.png)


作成したNASに対応するPVのいくつかの重要なフィールドに注意してください。「capacity」フィールドは、作成されたストレージのサイズを示し、「accessModes」フィールドは、作成されたストレージのアクセスモードを示します。

PersistentVolumeReclaimPolicy」フィールドは、PVの再生ポリシーを示します。つまり、PVを使用しているPodとPVCが削除された後に、PVを削除するか保持するかを指定します。

ストレージを使用する前に、PVCオブジェクトを作成します。このオブジェクトには、ストレージの要件のみを指定する必要があり、ストレージの実装の詳細は指定しません。ストレージ要件には、必要なストレージのサイズである「`resources.requests.storage`」と、ストレージのアクセスモードである「accessModes」が含まれます。アクセスモードは「ReadWriteMany」と宣言されており、NASの代表的な機能である複数のノードへの読み書き可能なアクセスがサポートされていることを示しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/a80f8ea5-fdbb-b266-2da2-d3e05a652161.png)


前述の図の左に表示されているサイズとアクセスモードは、作成された静的PVのものと一致しています。この場合、PVCをサブミットする際に、KubernetesクラスタのコンポーネントがPVとPVCをバインドします。そして、PodのYAMLファイルをサブミットする際に、ボリュームにclaimNameを設定し、必要なPVCを宣言します。マウント方法は前述のものと同じです。YAMLファイルを投入すると、PVCをもとにバインドされたPVが見つかり、ストレージを利用できるようになります。以上が、PVが静的にプロビジョニングされ、Podで利用される仕組みです。

###Dynamic PVの使い方
Dynamic PVでは、システム管理者はPVを事前に割り当てる代わりに、テンプレートファイルを作成します。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/7c4a0d90-2c2c-f531-c6f5-8ea5153ee2f6.png)



テンプレートファイルはStorageClassで、プロビジョナーなどの重要な情報を設定する必要があります。プロビジョナーは、PVとそれに対応するストレージの作成に使用するストレージプラグインを指定します。

これらのパラメータは、Kubernetesでストレージを作成する際に指定する必要があります。ここでは、regionld、zoneld、fsType、typeなどのパラメータを無視します。reclaimPolicyパラメータは、Dynamic PVのPodとPVCが削除された後の処理方法を示しており、「Delete」の値は、PodとPVCが削除されたときにPVが削除されることを示します。

クラスタ管理者がStorageClass(PV作成テンプレート)を提出した後、まずPVCファイルを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/de001e61-fe16-6f72-d5bb-c5dbe56e9cab.png)


PVCファイルのストレージサイズとアクセスモードは変更されません。この場合、StorageClassNameフィールドを追加して、ダイナミックPVのテンプレートファイルの名前を指定します。ここでは、StorageClassNameをcsi-diskに設定しています。

PVCが提出されると、Kubernetesクラスタ内のコンポーネントは、PVCと対応するStorageClassに基づいてPVを動的に生成し、PVとPVCを結合します。YAMLファイルを送信した後、PVCに基づいて動的なPVを見つけ、それを対応するコンテナにマウントします。

###PVの主要フィールド


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/e4d74fa3-153b-2eb5-bf42-f591df0b15c0.png)


- Capacity:ストレージオブジェクトのサイズ。
- AccessModes:PVの使用モード。PVは3つのモードで使用されます。


1) ReadWriteOnce：シングルノードの読み書きモード
2）ReadOnlyMany：マルチノードのリードオンリーモード、一般的なデータ共有モード
3）ReadWriteMany：マルチノードの読み書き両用モード

「Capacity」と「AccessModes」は、サブミットされたPVCの中で最も重要なフィールドです。PVCがサブミットされると、Kubernetesクラスタ内のコンポーネントは以下のようにして適切なPVを見つけます。

このコンポーネントは、PVに対して作成されたAccessModesインデックスに基づいて、特定のPVCのAccessModesフィールドを満たすすべてのPVのリストを取得し、PVCのCapacity、StorageClassName、Label Selectorの値に基づいてPVをフィルタリングします。複数のPVが条件を満たす場合は、サイズが最も短く、アクセスモードリストが最も短いPVが選択されます。

- PersistentVolumeReclaimPolicy：特定のPVのPVCが削除された後、PVがどのように処理されるかを指定するポリシーです。PV は 3 つのモードで処理されます。


1） Recycle：(放棄)
2) Delete：PVCが削除されるとPVも削除されます。
3) Retain: PVC が削除されても PV は保持されます。システム管理者によって処理されます。

- StorageClassName:ボリュームの動的プロビジョニング時にPVを生成するために使用するテンプレートファイルの名前です。
- NodeAffinity:作成されたPVがマウントされるノードの制限です。NodeAffinity は、PV を使用するPodも制限します。この場合、Podは、PV を使用するノードにスケジュールされたときにのみ PV を使用します。このフィールドについては、ストレージトポロジースケジューリングのセクションで説明します。

###PVステータスの遷移

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/f190c50f-7877-261c-04cb-8d7408fc1456.png)


PV オブジェクトが作成された後、しばらくの間は保留状態になります。実際のPVが作成された後は、利用可能な状態になります。

PVCをサブミットした後、関連するKubernetesコンポーネントはPVをPVCにバインドします。この場合、PV と PVC の両方がバインド状態になります。PVCを使用した後、PVCを削除すると、PVはリリース状態になります。そして、PersistentVolumeReclaimPolicyフィールドで、PVを削除するか保持するかを決定します。

PVが解放された状態では、直接使用可能な状態に戻すことができないため、新しいPVCにバインドすることができません。解放されたPVを再利用するには、次のいずれかの方法を使用します。

方法 1: PV オブジェクトを作成し、そこにリリースされた PV のフィールド情報を追加して、PV を新しい PVC にバインドします。
方法2：Podは削除するが、PVCオブジェクトは残します。この場合、PVにバインドされたPVCはまだ存在しており、PodはPVCに基づいてPVを直接再利用します。これは、KubernetesのStatefulSetが管理するボリュームベースのPod移行です。



#3）デモンストレーション
次に、実際の環境でボリュームの静的プロビジョニングとボリュームの動的プロビジョニングを行う方法をご紹介します。

###ボリュームの静的プロビジョニングの例
ボリュームの静的プロビジョニングにはAlibaba CloudのNASを、ボリュームの動的プロビジョニングにはAlibaba Cloudのディスクを使用しています。Alibaba Cloud NAS用のcsi-nasplugin、Alibaba Cloudディスク用のcsi-diskなど、必要なストレージプラグインをKubernetesクラスタに配備しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/6d3a87ee-627a-ae7a-ba49-fbde2cc99f7f.png)

次の図は、ボリュームの静的プロビジョニングされたPVのYAMLファイルです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/15a4aaf6-b3dd-01fe-d664-53db485e6774.png)

volumeAttributesは、Alibaba Cloud NASコンソールで事前に作成されたNASに関連する情報を指定します。容量の下のストレージフィールドは5Giに、accessModesフィールドはReadWriteManyに、PersistentVolumeReclaimPolicyはRetainに、ドライバーはボリュームで使用されています。

PV を作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/18c48556-186e-49d1-05ad-8cd6fd7d819f.png)


前述の図のように、PV は利用可能な状態になっています。

次に、nas-pvcを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/fbf8c043-d328-e78e-20d9-f75d0292059d.png)

さて、PVCが作成され、作成されたPVにバインドされています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/4a333cd9-7983-8220-4417-b01fae1c134e.png)


PVCのYAMLファイルには、必要なストレージサイズとアクセスモードが記録されています。PVCを送信すると、クラスタ内のマッチしたPVにバインドされます。

次に、nas-fsを使用するPodを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/742fabb0-34ec-2a91-950c-02db7af4b1b2.png)


前述の図のように、2つのPodは実行中の状態です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/2efe7435-2d01-51fe-b4d7-dcae01814c47.png)


PodのYAMLファイルには、作成されたPVCオブジェクトが宣言されており、PVCオブジェクトはnas-containerコンテナの`/data`ディレクトリにマウントされています。「Deployment」によってPodに2つのレプリカが作成され、アンチアフィニティによって異なるノードにスケジューリングされます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/310efe3d-7f5a-d311-caf1-2185985c5914.png)


前述の図では、2つのPodが異なるホストに配置されています。

次の図のように、1つ目のコンテナにログオンし、findmntコマンドを実行して、そのマウント情報を表示します。宣言されたnas-fsにマウントされていることに注意してください。次に、test.test.testファイルに対してtouchコマンドを実行します。また、もう一方のコンテナにログオンし、共有されているかどうかを確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/8d3c5ac9-1dda-1783-546e-74c9a0bfd7ea.png)


終了してから、再び最初のコンテナにログオンします。

次の図に示すように、findmntコマンドを実行して、2つのPodが同じディレクトリにリモートマウントされていること、つまり同じNAS PVが使用されていることを確認します。両方のPodが存在していることから、異なるノードで動作している2つのPodがNASを共有していることがわかります。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/fbd58c09-5afc-9a88-0100-9818e8a8c31b.png)


Podを削除してから、対応するPVCを削除してください。Podが使用しているPVCは削除できません。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/83a30db2-d1b6-4cc6-5f80-18c632dbd10b.png)


次の図のように、PVCが削除されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/6eff879a-1a2c-3e96-2baa-4dfb445a1513.png)


NASのPVはリリースされた状態でまだ存在しており、このPVを使用しているPVCが削除され、リリースされたことを示しています。RECLAIM POLICYがRetainに設定されているため、PVは保持されています。

###Dynamic Provisioningの例
保持しているPVを手動で削除します。この場合、クラスタ内にPVは存在しません。

PVを生成するためのStorageClassテンプレートファイルを作成し、ファイルの内容を確認します。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/f95f2d37-6184-a9f9-a7d1-1a9ae9103e74.png)


前述の図のように、ストレージの作成に使用するボリュームプラグイン（Alibaba Cloudチームが作成したAlibaba Cloud disk plug-in）を指定します。パラメータの部分には、ストレージの作成に必要なパラメータが記載されています。この部分は無視してください。reclaimPolicyパラメーターはDeleteに設定されており、StorageClassによって作成されたPVが、そのバインドされたPVCが削除された後に削除されることを示しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/e303ccae-d395-be17-f3ea-195775f01cff.png)


前述の図のように、クラスターにはPVが含まれていません。PVCファイルを提出します。PVCファイルでは、accessModesはReadWriteOnce（Alibaba Cloudのディスクはシングルノードの読み書きモードしかサポートしていません）、storageは30Gi、StorageClassNameは先ほど作成したStorageClassであるcsi-diskです。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/d6e729fe-da23-429e-8413-c52395e2879b.png)


PVCは保留状態で、対応するPVが作成中であることを示しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/710dc40b-71a5-ab7a-9933-54ad2580a8c1.png)


しばらくすると、新しいPVが生成されることを確認してください。このPVは、投入されたPVCと、PVCで指定されたStorageClassを元に、動的に生成されます。次に、Kubernetesは生成されたPVを提出されたPVC（disk PVC）にバインドします。では、Podを作成して使ってみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/a83d8d48-aace-33ea-f8cb-b2b6e88d786e.png)


PodのYAMLでは、使用するPVCを宣言しています。次に、マウントポイントを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/2504d136-908d-5162-eecc-f4e13dc89788.png)


次の図は、そのイベントを示しています。ノードがスケジュールされると、attachdetach コントローラがディスクをアタッチします。これは、スケジューラがスケジュールしたノードに対応する PV をマウントすることを意味します。その後、Pod内の対応するコンテナが起動し、対応するディスクが使用されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/a2a65984-9859-1668-f0b6-2704a6de1020.png)


この場合、PVCとそれに対応するPVが存在します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/3816be19-e801-907b-3d4c-b8f9edf2a195.png)


では、PVCを削除してください。PVも削除されているのがわかります。したがって、PV は reclaimPolicy に従って PVC と一緒に削除されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/6766ad9c-222f-3c53-9084-642268eda15f.png)


#4）アーキテクチャデザイン
###PVとPVCの処理プロセス
次の図の右下にあるCSI（Container Storage Interface）を見てみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/3ce34e20-a905-4d64-fb03-d8280cb7649d.png)


Kubernetesコミュニティでは、アウトオブツリーモードのためにCSIを推奨しています。CSIの実装は2つの部分に分かれています。

- 1つはKubernetesコミュニティが推進する共通部分で、この図のcsi-provisionerやcsi-attacher controllerなどがそれにあたります。
- もう一つの部分は、図の`csi-controller-server`や`csi-node-server`のようなクラウドストレージベンダーによって実装されています。CSIはクラウドストレージベンダーのOpenAPIに接続して、create、delete、mount、unmountなどのストレージ関連の操作を実装します。

PVCのYAMLファイルを送信すると、クラスター内にPVCオブジェクトが生成され、csi-provisionerコントローラによって監視されます。そして、csi-provisionerは、PVCオブジェクトとPVCオブジェクトで宣言されたStorageClassに基づいて、GRPCを介して`csi-controller-server`を呼び出し、クラウドストレージサービス上に実ストレージを作成し、PVオブジェクトを作成します。最後に、クラスタ内のPVコントローラがPVCとPVをバインドし、その後PVが使用されます。

Podを提出した後、スケジューラは適切なノードをスケジュールします。Podの作成中、ノード上のkubeletは、作成されたPVを`csi-node-server`を通じてPodの利用可能なディレクトリにマウントし、Pod内のすべてのコンテナを作成・起動します。

###PV、PVC、およびCSIベースのストレージの使用状況
次の図は、PV、PVC、およびCSIによるストレージの使用方法を示しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/647921/734a6e7e-9464-69c7-21e2-78cb1368a705.png)


全体のプロセスは3つのステージに分かれています。

- Createステージでは、PVCを提出した後、csi-provisionerがストレージを作成してPVオブジェクトを生成し、PVコントローラがPVCと生成されたPVオブジェクトを結合します。
- Attachステージでは、PodのYAMLファイルを送信しながら、スケジューラが適切なノードをスケジュールします。ADコントローラは、ノードを監視した後、Podで使用されているPVをチェックします。その後、VolumeAttachmentという名前の内部オブジェクトが生成され、これがcsi-attacherのトリガーとなってcsi-controller-serverを呼び出し、クラウドストレージベンダーのOpenAPIを使用して実際のアタッチ操作を実行します。アタッチ操作は、Podが実行されるノードにストレージをアタッチします。
- マウントステージは、kubeletがPodを作成しているときに始まります。Pod作成時には、ノードに取り付けられたディスクが、Podからアクセス可能な特定のディレクトリにマウントされます。その後、kubeletはコンテナの作成と起動を開始します。

要約すると、Createステージでは、ストレージが作成されます。Attachステージでは、ストレージがノードにマウントされます（通常はノードの/devにマウントされます）。Mountステージでは、ストレージがPodからアクセス可能なディレクトリにマウントされます。



#概要
この記事では、Kubernetesボリュームの適用シナリオと制限について説明し、PVCおよびPVシステムを定義しています。このシステムに基づいて、Kubernetesは、マルチポッドの共有、移行、およびストレージの拡張などのシナリオでKubernetesボリュームを拡張します。さらに、異なるPVプロビジョニングモード（静的および動的）と、異なるモード間でクラスター内のPodが必要とするストレージをプロビジョニングする方法について説明しています。最後に、KubernetesにおけるPVCとPVの完全な処理手順を説明し、ユーザーがPVCとPVの動作原理を理解できるようにしています。

*本ブログは英語版からの翻訳です。オリジナルは[こちら](https://www.alibabacloud.com/blog/get-to-know-kubernetes-%7C-application-storage-and-persistent-volumes-core-knowledge_596070)からご確認いただけます。一部機械翻訳を使用しております。翻訳の間違いがありましたら、ご指摘いただけると幸いです。*

*アリババクラウドは日本に２つのデータセンターを有し、世界で60を超えるアベラビリティーゾーンを有するアジア太平洋地域No.1(2019ガートナー)のクラウドインフラ事業者です。
アリババクラウドの詳細は、こちらからご覧ください。
[アリババクラウドジャパン公式ページ](https://www.alibabacloud.com/ja)*