Volume: Kubernetes でコンテナのデータを永続化する
- 公開日
- カテゴリ:Kubernetes
- タグ:Kubernetes,学習メモ

コンテナの中に書いたファイルは、コンテナが起動し直すと消える。コンテナは、起動するたびに image の中身から作り直されるため。
Volume は、コンテナの外にファイルの置き場所を用意して、コンテナの中のディレクトリとして見せる仕組み。置き場所には、Pod と一緒に消えるものと、Pod が消えても残るものがある。
この記事では、同じファイルを 3 つの置き場所に書いて、コンテナが起動し直したときと Pod が作り直されたときに、残るか消えるかを確認する。
この記事でやること:
- Volume なしで書いたファイルが、コンテナの起動し直しで消えることの確認
emptyDirに書いたファイルが、コンテナの起動し直しでは残り、Pod の作り直しで消えることの確認- PersistentVolumeClaim を作り、Pod から使うと PersistentVolume が自動で作られることの確認
- PersistentVolumeClaim に書いたファイルが、Pod を作り直しても残ることの確認
- ファイルの実体がある場所(Node のディレクトリ)の確認
- Deployment を消したときと、PersistentVolumeClaim を消したときの違いの確認
contents
- 環境
- 3 つの置き場所
- Volume なしで書いたファイル
- emptyDir
- PersistentVolumeClaim を作る
- Pod から PVC を使う
- Pod を作り直してもファイルが残る
- ファイルの実体を Node の中で見る
- StorageClass
- 消す
- 同じ PVC を使う Pod を増やす
- 使用中の PVC を消す
- 用語メモ
- 参考 URL
環境
kind で作ったクラスタ(Control Plane 1台 + Worker 2台)を使う。(作り方は「Kubernetes の Pod とは?コンテナを動かす最小単位を整理する」を参照)
- 環境: macOS(Apple Silicon)、Docker Desktop 29.8.0、kind v0.33.0、Kubernetes v1.37.0、kubectl v1.36.1
3 つの置き場所
同じファイル(/data/memo.txt)を、次の 3 つの置き場所に書いて比べる。
| 置き場所 | コンテナが起動し直したら | Pod が作り直されたら |
|---|---|---|
| Volume なし(コンテナの中) | 消える | 消える |
emptyDir(Pod に付く一時的な置き場所) | 残る | 消える |
| PersistentVolumeClaim(Pod とは別に作る置き場所) | 残る | 残る |
出てくる名前は 3 つ。
| 名前 | 内容 |
|---|---|
| Volume | Pod に用意する、ファイルの置き場所。Deployment の YAML の volumes フィールドに書く。種類がいくつもあり、この記事では emptyDir と persistentVolumeClaim を使う |
| PersistentVolumeClaim(PVC) | 「これだけの大きさの置き場所が欲しい」という要求。Deployment とは別の YAML で作る |
| PersistentVolume(PV) | 用意された置き場所 1 つを表すデータ。その置き場所がどこにあり、どれだけの大きさかが書いてある。この記事では自分では書かず、PVC に合わせて自動で作られる |
PVC と PV はどこにあるか
PVC と PV は、動いているプログラムではなく、Control Plane で動いている etcd に保存されるデータ。(「ConfigMap: Kubernetes で Pod に渡す設定値」の「ConfigMap はどこにあるか」を参照)
ファイルそのものは etcd には入らない。このクラスタでは、ファイルの実体は Pod が置かれた Node のディレクトリにあり、PV にはその場所が書いてある。
- 角が二重の箱(local-path-provisioner、kubelet)は動いているプログラム。円柱は Node のディスクの上のディレクトリ。それ以外は etcd に保存されたデータと、Node の上の Pod
- 自分で YAML を書くのは Deployment と PVC の 2 つ。PV は local-path-provisioner が作る。StorageClass は kind がクラスタを作ったときに入れている
- local-path-provisioner は、kind のクラスタに最初から入っている Pod。PVC を見て、Node にディレクトリを作り、その場所を書いた PV を作る
- kubelet は、自分の Node に置かれた Pod のコンテナを起動するときに、ディレクトリをコンテナの
/dataにつなぐ
Volume なしで書いたファイル
Volume のことを何も書いていない Deployment を動かす。(Deployment は「Deployment: Kubernetes で Pod の数と更新を管理する」を参照)
# demo-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-app
spec:
replicas: 1
selector:
matchLabels:
app: demo-app
template:
metadata:
labels:
app: demo-app
spec:
containers:
- name: nginx
image: nginx:1.16.1
ports:
- containerPort: 80
$ kubectl apply -f demo-deployment.yaml
# => deployment.apps/demo-app created
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
demo-app-6d69c7cc8c-99qt4 1/1 Running 0 5s
コンテナの中に /data を作り、memo.txt に hello と書く。
$ kubectl exec deploy/demo-app -- sh -c 'mkdir /data && echo hello > /data/memo.txt'
$ kubectl exec deploy/demo-app -- cat /data/memo.txt
# => hello
| 部分 | 意味 |
|---|---|
kubectl exec deploy/demo-app -- | Deployment demo-app の Pod のコンテナの中で、-- の後ろのコマンドを実行する |
sh -c '...' | 引用符の中をシェルに実行させる |
コンテナを起動し直す
コンテナの中で、nginx を止めるコマンドを実行する。コンテナのメインのプログラムが終了するとコンテナも終了し、Node の kubelet がコンテナを起動し直す。
$ kubectl exec deploy/demo-app -- nginx -s stop
# => 2026/10/05 11:53:24 [notice] 25#25: signal process started
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
demo-app-6d69c7cc8c-99qt4 1/1 Running 1 (5s ago) 64s
RESTARTS が 1 になった。Pod の名前は demo-app-6d69c7cc8c-99qt4 のままで、中のコンテナだけが新しくなっている。
$ kubectl exec deploy/demo-app -- cat /data/memo.txt
cat: /data/memo.txt: No such file or directory
command terminated with exit code 1
ファイルが消えている。Pod が同じでも、コンテナが起動し直せば、前のコンテナの中で作ったファイルは引き継がれない。
emptyDir
emptyDir は、Pod が Node に置かれたときに作られる空のディレクトリ。実体は Node のディスクの上にあり、コンテナの外にある。
Deployment の YAML に、volumes と volumeMounts を足す。
# demo-deployment-emptydir.yaml(spec.template.spec の部分)
spec:
containers:
- name: nginx
image: nginx:1.16.1
ports:
- containerPort: 80
volumeMounts:
- name: data-volume
mountPath: /data
volumes:
- name: data-volume
emptyDir: {}
| フィールド | 書く場所 | 意味 |
|---|---|---|
volumes | Pod の定義(containers と同じ深さ) | この Pod に用意する置き場所。名前と種類を書く |
volumeMounts | コンテナの定義の中 | 上の置き場所を、このコンテナの中のどのパスに見せるか |
2 つは name(data-volume)でつながる。
$ kubectl apply -f demo-deployment-emptydir.yaml
# => deployment.apps/demo-app configured
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
demo-app-786c9df86d-9t6bk 1/1 Running 0 7s
コンテナを起動し直す
ファイルを書いて、コンテナを起動し直す。/data は volume として最初から見えているので、mkdir は要らない。
$ kubectl exec deploy/demo-app -- sh -c 'echo hello > /data/memo.txt'
$ kubectl exec deploy/demo-app -- nginx -s stop
# => 2026/10/05 11:56:57 [notice] 18#18: signal process started
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
demo-app-786c9df86d-9t6bk 1/1 Running 1 (7s ago) 46s
$ kubectl exec deploy/demo-app -- cat /data/memo.txt
# => hello
RESTARTS が 1 になったあとも、ファイルが残っている。
Pod を作り直す
Pod ごと消す。Deployment が Pod の数を 1 に保っているので、すぐに新しい Pod が作られる。
$ kubectl delete pod -l app=demo-app
# => pod "demo-app-786c9df86d-9t6bk" deleted from default namespace
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
demo-app-786c9df86d-j8c7s 1/1 Running 0 5s
$ kubectl exec deploy/demo-app -- cat /data/memo.txt
cat: /data/memo.txt: No such file or directory
command terminated with exit code 1
Pod の名前が demo-app-786c9df86d-9t6bk から demo-app-786c9df86d-j8c7s に変わり、ファイルは消えている。新しい Pod には、新しい空の emptyDir が用意される。
| 起きたこと | Pod | /data/memo.txt |
|---|---|---|
コンテナの起動し直し(RESTARTS が増える) | 同じ Pod のまま | 残る |
| Pod の作り直し(Pod の名前が変わる) | 別の Pod | 消える |
Deployment の Pod は、image を変えたときにも作り直される。emptyDir は、Pod と一緒に消えてよい一時ファイルや、同じ Pod の中の複数のコンテナでファイルを共有するときに使う。
PersistentVolumeClaim を作る
Pod が消えても残る置き場所は、Pod とは別のデータとして作る。それが PersistentVolumeClaim(PVC)。
# demo-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: demo-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Mi
| フィールド | 意味 |
|---|---|
metadata.name | PVC の名前。Deployment の YAML から、この名前で指定する |
accessModes | 置き場所の使い方。ReadWriteOnce は、1 つの Node から読み書きする |
resources.requests.storage | 欲しい大きさ。100Mi は 100 メビバイト |
PVC に書くのは、何が欲しいか。どこに、どうやって用意するかは書いていない。
$ kubectl apply -f demo-pvc.yaml
# => persistentvolumeclaim/demo-data created
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
demo-data Pending standard <unset> 5s
$ kubectl get pv
# => No resources found
- PVC の
STATUSはPending。まだ PV と結び付いていない - PV は 1 つもない
STORAGECLASSにstandardと出ている。YAML には書いていないが、クラスタの既定の StorageClass が入った(StorageClass は後の節で見る)
Pending の理由は、PVC の Events: に出る。
$ kubectl describe pvc demo-data | grep -A 3 'Events:'
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal WaitForFirstConsumer 5s (x5 over 61s) persistentvolume-controller waiting for first consumer to be created before binding
waiting for first consumer to be created before binding は、この PVC を使う最初の Pod が作られるのを待っている、という意味。Type は Normal で、エラーではない。
Pod から PVC を使う
Deployment の volumes の種類を、emptyDir から PVC に変える。volumeMounts は同じ。
# demo-deployment-pvc.yaml(volumeMounts と volumes の部分)
volumeMounts:
- name: data-volume
mountPath: /data
volumes:
- name: data-volume
persistentVolumeClaim:
claimName: demo-data
emptyDir の YAML | PVC の YAML | |
|---|---|---|
| volume の種類 | emptyDir: {} | persistentVolumeClaim: と claimName: demo-data |
| コンテナの中のパス | /data | /data |
| 置き場所が作られるとき | Pod が作られるたびに、新しく空で | PVC demo-data に対して 1 回 |
$ kubectl apply -f demo-deployment-pvc.yaml
# => deployment.apps/demo-app configured
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
demo-app-7f96f4c6fb-mx6qk 1/1 Running 0 26s 10.244.2.11 k8s-study-worker2 <none> <none>
Pod は k8s-study-worker2 に置かれた。PVC と PV を見る。
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
demo-data Bound pvc-5d888703-f30c-4b3c-ace7-7656e158ef70 100Mi RWO standard <unset> 3m15s
$ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE
pvc-5d888703-f30c-4b3c-ace7-7656e158ef70 100Mi RWO Delete Bound default/demo-data standard <unset> 67s
- PVC の
STATUSがPendingからBoundになり、VOLUMEに PV の名前が入った - PV
pvc-5d888703-f30c-4b3c-ace7-7656e158ef70ができている。自分では作っていない
| PV の列 | 意味 |
|---|---|
CAPACITY | 大きさ。PVC で要求した 100Mi |
ACCESS MODES | RWO は ReadWriteOnce の略 |
RECLAIM POLICY | PVC が消されたとき、この PV をどうするか。Delete は PV もデータも消す |
STATUS | Bound は、PVC と結び付いている状態 |
CLAIM | 結び付いている PVC。namespace/名前 |
PVC と PV は 1 対 1 で結び付く。
PV を作ったプログラム
PVC の Events: に、PV ができるまでの記録が残っている。
$ kubectl describe pvc demo-data | grep -A 6 'Events:'
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal WaitForFirstConsumer 2m29s (x10 over 4m40s) persistentvolume-controller waiting for first consumer to be created before binding
Normal ExternalProvisioning 2m24s persistentvolume-controller Waiting for a volume to be created either by the external provisioner 'rancher.io/local-path' or manually by the system administrator. If volume creation is delayed, please verify that the provisioner is running and correctly registered.
Normal Provisioning 2m24s rancher.io/local-path_local-path-provisioner-75f7fc7dc5-sjr8t_38bd4f47-bfce-4c33-abb4-9d748ba9854f External provisioner is provisioning volume for claim "default/demo-data"
Normal ProvisioningSucceeded 2m21s rancher.io/local-path_local-path-provisioner-75f7fc7dc5-sjr8t_38bd4f47-bfce-4c33-abb4-9d748ba9854f Successfully provisioned volume pvc-5d888703-f30c-4b3c-ace7-7656e158ef70
Reason | 起きたこと |
|---|---|
WaitForFirstConsumer | PVC を使う Pod が作られるのを待っていた |
ExternalProvisioning | rancher.io/local-path を担当するプログラムが PV を作るのを待っていた |
Provisioning | Pod が作られ、local-path-provisioner が置き場所を作り始めた |
ProvisioningSucceeded | 置き場所ができて、PV が作られた |
From の rancher.io/local-path_local-path-provisioner-75f7fc7dc5-sjr8t_... が、PV を作ったプログラム。local-path-provisioner は、kind のクラスタの local-path-storage namespace に最初から入っている Pod。
$ kubectl get pods -n local-path-storage
NAME READY STATUS RESTARTS AGE
local-path-provisioner-75f7fc7dc5-sjr8t 1/1 Running 14 (28m ago) 9d
PVC に合わせて PV が自動で作られることを、動的プロビジョニング(dynamic provisioning)という。
Pod を作り直してもファイルが残る
emptyDir のときと同じ手順で、ファイルを書いて Pod を消す。
$ kubectl exec deploy/demo-app -- sh -c 'echo hello > /data/memo.txt'
$ kubectl delete pod -l app=demo-app
# => pod "demo-app-7f96f4c6fb-mx6qk" deleted from default namespace
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
demo-app-7f96f4c6fb-r8jxz 1/1 Running 0 5s 10.244.2.12 k8s-study-worker2 <none> <none>
$ kubectl exec deploy/demo-app -- cat /data/memo.txt
# => hello
Pod の名前は demo-app-7f96f4c6fb-mx6qk から demo-app-7f96f4c6fb-r8jxz に変わったが、ファイルは残っている。新しい Pod も同じ PVC demo-data を使うので、同じ置き場所が /data に見える。
ファイルの実体を Node の中で見る
PV に書いてある場所を見る。
$ kubectl describe pv | grep -A 7 'Node Affinity:'
Node Affinity:
Required Terms:
Term 0: kubernetes.io/hostname in [k8s-study-worker2]
Message:
Source:
Type: HostPath (bare host directory volume)
Path: /var/local-path-provisioner/pvc-5d888703-f30c-4b3c-ace7-7656e158ef70_default_demo-data
HostPathType: DirectoryOrCreate
| 行 | 意味 |
|---|---|
Node Affinity の kubernetes.io/hostname in [k8s-study-worker2] | この PV は、Node k8s-study-worker2 でしか使えない |
Source の Type: HostPath | 実体は、Node の上のディレクトリ |
Path | そのディレクトリの場所。名前は、PV の名前・namespace・PVC の名前を _ でつないだもの |
kind の Node は Docker コンテナなので、docker exec で Node の中のコマンドを実行できる。
$ docker exec k8s-study-worker2 ls /var/local-path-provisioner/
# => pvc-5d888703-f30c-4b3c-ace7-7656e158ef70_default_demo-data
$ docker exec k8s-study-worker2 sh -c 'cat /var/local-path-provisioner/*/memo.txt'
# => hello
コンテナの中で /data/memo.txt に書いた hello が、Node k8s-study-worker2 のディレクトリの中にある。
- PV は、置き場所の実体がどの Node のどのディレクトリにあるかを書いたデータ。ファイルそのものは etcd ではなく、Node のディスクの上
- このクラスタの PV は、1 つの Node に結び付いている。Pod を作り直したあとも
NODEがk8s-study-worker2のままだったのは、PV がその Node にあるため
StorageClass
PVC の YAML には、Node の名前もディレクトリも書かなかった。PV をどのプログラムに、どう作らせるかは、StorageClass に書いてある。kind のクラスタには、StorageClass standard が最初から入っている。
$ kubectl get storageclass
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
standard (default) rancher.io/local-path Delete WaitForFirstConsumer false 9d
standard の設定 | この記事の手順で起きたこと |
|---|---|
(default) | StorageClass を書いていない PVC に、standard が入った |
PROVISIONER が rancher.io/local-path | local-path-provisioner が PV を作った |
VOLUMEBINDINGMODE が WaitForFirstConsumer | PVC を作っただけでは Pending で、Pod を作ってから Bound になった |
RECLAIMPOLICY が Delete | PVC を消すと、PV もディレクトリも消える(次の節で確認する) |
PVC・PV・StorageClass を、誰が作ったかで並べる。
| 名前 | 内容 | この記事で作ったのは |
|---|---|---|
| PVC | 置き場所の要求(大きさ、使い方) | 自分(demo-pvc.yaml) |
| PV | 用意された置き場所 1 つを表すデータ(場所、大きさ) | local-path-provisioner |
| StorageClass | PV をどのプログラムに、どう作らせるかの設定 | kind(クラスタを作ったとき) |
実体を Node の外のディスクにするとき
実体を何にするかは、PVC ではなく StorageClass で決まる。公式ドキュメントには、AWS の EBS を使う StorageClass の例が載っている。次の YAML は、その例から一部の行を抜き出したもの。
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: ebs-sc
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
parameters:
type: io1
encrypted: "true"
provisioner が、PV を作るプログラムの名前。StorageClass を作るだけでなく、この名前を担当するプログラム(この例では AWS EBS CSI driver)がクラスタに入っている必要がある。PVC からは、spec.storageClassName に StorageClass の名前を書いて選ぶ。書かなければ、既定の StorageClass が使われる。
この例は、この記事のクラスタでは動かしていない。
消す
Deployment を消す
$ kubectl delete -f demo-deployment-pvc.yaml
# => deployment.apps "demo-app" deleted from default namespace
$ kubectl get pods
# => No resources found in default namespace.
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
demo-data Bound pvc-5d888703-f30c-4b3c-ace7-7656e158ef70 100Mi RWO standard <unset> 13m
$ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE
pvc-5d888703-f30c-4b3c-ace7-7656e158ef70 100Mi RWO Delete Bound default/demo-data standard <unset> 11m
Deployment と Pod は消えたが、PVC と PV は Bound のまま残っている。
PVC を消す
$ kubectl delete -f demo-pvc.yaml
# => persistentvolumeclaim "demo-data" deleted from default namespace
$ kubectl get pv
# => No resources found
$ docker exec k8s-study-worker2 ls /var/local-path-provisioner/
PVC を消すと、PV も消えた。Node k8s-study-worker2 のディレクトリも消えている(ls は何も表示しない)。PV の RECLAIM POLICY が Delete のときの動き。
同じ PVC を使う Pod を増やす
PVC と Deployment を作り直して、Pod の数を 3 にする。
$ kubectl apply -f demo-pvc.yaml -f demo-deployment-pvc.yaml
$ kubectl scale deployment demo-app --replicas=3
# => deployment.apps/demo-app scaled
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
demo-app-7f96f4c6fb-jnb7c 1/1 Running 0 14s 10.244.2.15 k8s-study-worker2 <none> <none>
demo-app-7f96f4c6fb-mlrvb 1/1 Running 0 4s 10.244.2.17 k8s-study-worker2 <none> <none>
demo-app-7f96f4c6fb-nk9xc 1/1 Running 0 4s 10.244.2.16 k8s-study-worker2 <none> <none>
NODE が 3 つとも k8s-study-worker2。PV が 1 つの Node に結び付いているので、その PVC を使う Pod は同じ Node に置かれる。
ReadWriteOnce は 1 つの Node から読み書きするという使い方なので、同じ Node の Pod なら、複数の Pod から使える。
使用中の PVC を消す
Pod が使っている最中の PVC を消す。
$ kubectl apply -f demo-pvc.yaml -f demo-deployment-pvc.yaml
persistentvolumeclaim/demo-data created
deployment.apps/demo-app created
$ kubectl exec deploy/demo-app -- sh -c 'echo hello > /data/memo.txt'
$ kubectl delete pvc demo-data --wait=false
# => persistentvolumeclaim "demo-data" deleted from default namespace
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
demo-data Terminating pvc-1d06c166-2ff2-41ea-9503-ee1b6b9fbaf5 100Mi RWO standard <unset> 15s
$ kubectl exec deploy/demo-app -- cat /data/memo.txt
# => hello
| 部分 | 意味 |
|---|---|
--wait=false | 消え終わるのを待たずに、コマンドを終える |
deleted と表示されるが、PVC は Terminating のまま残っていて、Pod からはファイルが読める。Pod が使っている PVC は、すぐには消されない。
Deployment を消すと、PVC も消える。
$ kubectl delete -f demo-deployment-pvc.yaml
# => deployment.apps "demo-app" deleted from default namespace
$ kubectl get pvc
# => No resources found in default namespace.
用語メモ
| 用語 | 読み方 | 意味 |
|---|---|---|
| Volume | ボリューム | Pod に用意する、ファイルの置き場所。コンテナの外にあり、コンテナの中のディレクトリとして見せる |
| volumes | ボリュームズ | Deployment の YAML のフィールド。Pod に用意する置き場所の名前と種類を書く |
| volumeMounts | ボリューム マウンツ | Deployment の YAML のフィールド。置き場所を、コンテナの中のどのパスに見せるかを書く |
| emptyDir | エンプティ ディア | Volume の種類の 1 つ。Pod が Node に置かれたときにできる空のディレクトリ。Pod が消えると消える |
| PersistentVolumeClaim(PVC) | パーシステント ボリューム クレーム | 置き場所の要求。大きさと使い方を書く |
| PersistentVolume(PV) | パーシステント ボリューム | 用意された置き場所 1 つを表すデータ |
| Bound | バウンド | PVC と PV が結び付いている状態 |
| StorageClass | ストレージ クラス | PV をどのプログラムに、どう作らせるかの設定 |
| 動的プロビジョニング | どうてきプロビジョニング | PVC に合わせて、PV が自動で作られること |
| local-path-provisioner | ローカル パス プロビジョナー | kind のクラスタに最初から入っている Pod。Node にディレクトリを作り、PV を作る |
| accessModes | アクセス モーズ | 置き場所の使い方。ReadWriteOnce(RWO)は、1 つの Node から読み書きする |
| Reclaim Policy | リクレイム ポリシー | PVC が消されたとき、PV をどうするか。Delete は PV もデータも消す |
まとめ
- コンテナの中に書いたファイルは、コンテナが起動し直すと消える
- Volume は、コンテナの外に置き場所を用意して、コンテナの中のディレクトリとして見せる仕組み。Deployment の YAML に
volumesとvolumeMountsを書く emptyDirは Pod に付く一時的な置き場所。コンテナが起動し直しても残り、Pod が消えると一緒に消える- PVC は置き場所の要求で、Pod とは別に作る。Pod を作り直しても、Deployment を消しても、PVC がある間はファイルが残る
- PV は、用意された置き場所 1 つを表すデータ。kind のクラスタでは、PVC を使う Pod が作られたときに local-path-provisioner が作る。実体は Node のディレクトリで、PV はその Node に結び付く
- PV をどのプログラムに、どう作らせるかは StorageClass で決まる
- PVC を消すと、PV もファイルも消える(
RECLAIM POLICYがDeleteの場合)
参考 URL
- [official] ボリューム | Kubernetes
- [official] 永続ボリューム | Kubernetes
- [official] ボリュームの動的プロビジョニング(Dynamic Volume Provisioning) | Kubernetes
- [official] Storage Classes | Kubernetes
- [GitHub] rancher/local-path-provisioner

